python支持向量机SVM (sklearn)

文章目录

  • python支持向量机SVM (sklearn)
    • 原理概述
    • 代码
      • 导入库
      • 生成数据集
      • 核心代码
      • 线性不可分的情况
      • 核函数
      • 重要参数C(软间隔和硬间隔)
      • 混淆矩阵
      • 小案例
      • 多分类
      • 补充
        • 参数class_weight

原理概述

说实话以前用支持向量机都是直接套进去的,不过现在看了看菜菜提供数学原理发现其实挺有意思(是超有意思!!)。此处就不详述了,这原理到处都是。反正这文SVM和决策树一样,有支持向量分类(SVC)和支持向量回归(SVR)

代码

下面是一个SVC的案例

导入库

from sklearn.datasets import make_blobs
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np

生成数据集

X,y = make_blobs(n_samples=50, centers=2, random_state=0,cluster_std=0.6)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap="rainbow")
plt.xticks([])
plt.yticks([])
plt.show()

核心代码

模型本身并不难,就是要画出相应的图

clf = SVC(kernel = "linear").fit(X,y)
print(clf.predict(X))

上述例子预测又对X自己预测了一变。按照核心代码依旧延续sklearn的风格,十分简单。

  • 实例化
  • fit()
  • predict()。

可视化可能优点麻烦,需要用到下面这个函数。这个函数只需输入clf即可。

def plot_svc_decision_function(model,ax=None):if ax is None:ax = plt.gca()xlim = ax.get_xlim()ylim = ax.get_ylim()x = np.linspace(xlim[0],xlim[1],30)y = np.linspace(ylim[0],ylim[1],30)Y,X = np.meshgrid(y,x)xy = np.vstack([X.ravel(), Y.ravel()]).T#decision_function这个函数可以返回给定的x,y点到决策边界(也就是点到SVM所得到划分线的距离)P = model.decision_function(xy).reshape(X.shape)ax.contour(X, Y, P,colors="k",levels=[-1,0,1],alpha=0.5,linestyles=["--","-","--"])ax.set_xlim(xlim)ax.set_ylim(ylim)

函数大概思路就是首先生成一个网格,然后计算网格中各个点到决策边界的距离,最后绘制等高线(算出的距离相等的一条线)。

则可以写作

clf = SVC(kernel = "linear").fit(X,y)
plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap="rainbow")
plot_svc_decision_function(clf)

其中灰色实线就是决策边界虚线之间的距离就是边际。而SVM就是要找到边际最大的一条决策边界,而上面那三个穿虚线而过的点就是支持向量(最下面那个红色不算),也就是离决策边界最近的3个点

线性不可分的情况

这就是整个SVM我觉得最关键也最有意思的地方。从上面的图我们能够知道SVM实际上是找到一个超平面将各点分开。如果能找到自然就是线性可分的,那如果找不到呢?

超平面就是比当前空间维度低一个维度的分界,对于二维平面来说是一条线,对于三维空间是一个面

对于这么一个案例

from sklearn.datasets import make_circles
X,y = make_circles(100, factor=0.1, noise=.1)
X.shape
y.shape
plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap="rainbow")
plt.show()

我们可以看出,不可能存在一条直线,能将红色和蓝色分开,所以它是线性不可分的,怎么办呢?答案是升维!!!

对于原来每一个点,我们使用一个映射函数,使得从原来的二维点变为原来的三维点。对于原来一个点有(x0,y0),
从(x0,y0)变为(x1,y1,z1),其中z1有

x1 = x0; y1 = y0; z1 = e^{-(x^2+y^2)}

先别想这个函数是怎么来的,让我们先看看映射后的结果怎么样

这个结果非常的amazing啊,红色的点浮起来了,现在只需要用一个平面就能把红色和蓝色隔开,也就是说,升维之后线性可分了!(当时就把我看湿了

下面是上面这个案例的完整代码

from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import make_circles
X,y = make_circles(100, factor=0.1, noise=.1)
plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap="rainbow")
def plot_svc_decision_function(model,ax=None):if ax is None:ax = plt.gca()xlim = ax.get_xlim()ylim = ax.get_ylim()x = np.linspace(xlim[0],xlim[1],30)y = np.linspace(ylim[0],ylim[1],30)Y,X = np.meshgrid(y,x)xy = np.vstack([X.ravel(), Y.ravel()]).TP = model.decision_function(xy).reshape(X.shape)ax.contour(X, Y, P,colors="k",levels=[-1,0,1],alpha=0.5,linestyles=["--","-","--"])ax.set_xlim(xlim)ax.set_ylim(ylim)
clf = SVC(kernel = "linear").fit(X,y)
plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap="rainbow")
plot_svc_decision_function(clf)
r = np.exp(-(X**2).sum(1))
rlim = np.linspace(min(r),max(r),30)
from mpl_toolkits import mplot3d
def plot_3D(elev=30,azim=30,X=X,y=y):ax = plt.subplot(projection="3d")ax.scatter3D(X[:,0],X[:,1],r,c=y,s=50,cmap='rainbow')ax.view_init(elev=elev,azim=azim)ax.set_xlabel("x")ax.set_ylabel("y")ax.set_zlabel("r")plt.show()
#下面这个如果你用的是jupyter就可以互动了
#from ipywidgets import interact,fixed
#interact(plot_3D,elev=[0,30],azip=(-180,180),X=fixed(X),y=fixed(y))
#plt.show()

核函数

所以说上面这个映射函数到底是怎么来的呢,什么是核函数,又和核函数又什么关系呢?
首先SVM最终的决策函数是

  • f(x_test)是最终的分类,定义为{-1,1}
  • 其中sign是符号函数,大于0取1,小于0取-1。
  • y是标签,二分类有两个标签,取{-1,1}
  • x_i是支持向量
  • x_test是测试向量
  • b是一个常数

很显然我们要计算x_i与x_test之间的内积,当我们升维之后,我们要算的的内积是映射(升维)后的内积

那么我们定义核函数:

现在我们就只需要直接把两个向量带入核函数,而不用先映射成高维再算内积。这其实省去了很多麻烦,因为计算映射其实挺复杂的。
注意,正是因为再SVM中我们只用到了高维函数的内积,所以只需要计算核函数即可,有了核函数,我们便能再低维计算高维的内积,(这是一次低维生物对高维发起的伟大挑战)显然我们有,只要映射函数不同,核函数就不同
下面是sklearn中的几个核函数,个人建议用"rbf",至于每一个核函数对应的映射函数,自己百度吧。

并且有

  • 线性核,尤其是多项式核函数在高次项时计算非常缓慢
  • rbf和多项式核函数都不擅长处理量纲不统一的数据集
    所以需要针对其进行标准化
from sklearn.preprocessing import StandardScaler
X = StandardScaler().fit_transform(X)

重要参数C(软间隔和硬间隔)

c:

浮点数,默认1,必须大于等于0,可不填
松弛系数的惩罚项系数。如果C值设定比较大,那SVC可能会选择边际较小的,能够更好地分类所有训练点的决策边界,不过模型的训练时间也会更长。如果C的设定值较小,那SVC会尽量最大化边界,决策功能会更简单,但代价是训练的准确度。换句话说,C在SVM中的影响就像正则化参数对逻辑回归的影响.

混淆矩阵

1是少数类,0是多数类

  • 准确率:Accuracy,所有预测正确的样本除以总样本,(11+00)/(11+10+01+00)
  • 精确率:Precision,预测的少数类中,真正的少数类的占比。11/(11+01)
  • 召回率 :Recall,又被称为敏感度(sensitivity),真正率,查全率,表示所有真实为1的样本中,被我们预测正确的样本所占的比例,11/(11+10).
  • 假负率:False Negative Rate,1-Recall。没召回的占少数类的占比。10/(11+10)
  • 特异度:Specificity,表示所有真实为0的样本中,被正确预测为0的样本所占的比例,00/(01+00)
  • 假正率:False Positive Rate,1 - specificity就是一个模型将多数类判断错误的能力,01/(01+00)
  • ROC曲线,横轴为假正率(FPR),纵轴为召回率(Recall),当曲线越往左上角偏说明效果越好,。
  • AUC面积,它代表了ROC曲线下方的面积,这个面积越大,代表ROC曲线越接近左上角,模型就越好。

小案例

  • 首先生成数据集并带入模型训练
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import make_blobs
class_1 = 500 #类别1有500个样本
class_2 = 50 #类别2只有50个
centers = [[0.0, 0.0], [2.0, 2.0]] #设定两个类别的中心
clusters_std = [1.5, 0.5] #设定两个类别的方差,通常来说,样本量比较大的类别会更加松散
X, y = make_blobs(n_samples=[class_1, class_2],centers=centers,cluster_std=clusters_std,random_state=0, shuffle=False)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap="rainbow",s=10)
clf_proba = SVC(kernel="linear",C=1.0,probability=True).fit(X,y)

  • 其次把个点所预测得到的概率放入DataFrame里
prob = clf_proba.predict_proba(X)
#将样本和概率放到一个DataFrame中
import pandas as pd
prob = pd.DataFrame(prob)
prob.columns = ["0","1"]
  • 找出最佳阈值并画出ROC曲线并得到相应的FPR和Recall,以及AUC
from sklearn.metrics import roc_curve
FPR, recall, thresholds = roc_curve(y,prob.loc[:,"1"], pos_label=1)
#此时的threshold就不是一个概率值,而是距离值中的阈值了,所以它可以大于1,也可以为负
#找到最佳阈值
maxindex = (recall - FPR).tolist().index(max(recall - FPR))
print('thresholds:')
print(thresholds[maxindex])print('recall:')
print(recall[maxindex])print('FPR:')
print(FPR[maxindex])
from sklearn.metrics import roc_auc_score as AUC
area = AUC(y,clf_proba.decision_function(X))plt.scatter(FPR[maxindex],recall[maxindex],c="black",s=30)
#把上述代码放入这段代码中:
plt.figure()
plt.plot(FPR, recall, color='red',label='ROC curve (area = %0.2f)' % area)
plt.plot([0, 1], [0, 1], color='black', linestyle='--')
plt.scatter(FPR[maxindex],recall[maxindex],c="black",s=30)
plt.xlim([-0.05, 1.05])
plt.ylim([-0.05, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('Recall')
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
plt.show()

  • 最后进行预测,得出结果
for i in range(prob.shape[0]):if prob.loc[i,"1"] > thresholds[maxindex]:prob.loc[i,"pred"] = 1else:prob.loc[i,"pred"] = 0
prob["y_true"] = y
prob = prob.sort_values(by="1",ascending=False)
prob

  • 得到混淆矩阵来评估
from sklearn.metrics import confusion_matrix as CM, precision_score as P, recall_score as R
cm = CM(prob.loc[:,"y_true"],prob.loc[:,"pred"],labels=[1,0])
cm

PS:这个案例用的是核函数是线性核,但又试了一遍还是‘rbf’比较好,
并且其实不一定需要最佳阈值,要结合实际来看。
例如,三星手机发生爆炸,三星想要召回率能达到100%,即宁可把没有问题的手机召回,也不能放过任何一个有问题的手机,阈值也要相应调整。

多分类

多分类其实也很简单,应该是sklearn的多分类很简单,数学原理十分可怕。区别就是输入的Y多了几个分类而已。

clf = SVC(decision_function_shape='ovo') clf.fit(X, Y)

上面用的是ovo(one vs one),也就是每一个类两两组合来构建,也可以选择’ovr’速度更快,效果不怎么样。

补充

参数class_weight

如果你想追求最高的召回率,宁可错杀不可放过,那么class_weight = "balanced"

clf = SVC(kernel = kernel ,gamma="auto",degree = 1,cache_size = 5000,class_weight = "balanced").fit(Xtrain, Ytrain)

如果还想再高,那么class_weight = {1:10}

python支持向量机SVM (sklearn)相关推荐

  1. python sklearn 支持向量机_python机器学习库sklearn之支持向量机svm介绍

    python机器学习库sklearn之支持向量机svm介绍tcB太阳2平台注册|网站分类目录 python数据挖掘系列教程tcB太阳2平台注册|网站分类目录 这里只讲述sklearn中如何使用svm算 ...

  2. python机器学习库sklearn——支持向量机svm

    分享一个朋友的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!大家可以看看是否对自己有帮助:点击打开 全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 支持向量机svm的相关的知 ...

  3. python向量机使用方法_Python中支持向量机SVM的使用方法详解

    除了在Matlab中使用PRTools工具箱中的svm算法,Python中一样可以使用支持向量机做分类.因为Python中的sklearn库也集成了SVM算法,本文的运行环境是Pycharm. 一.导 ...

  4. Python中的支持向量机SVM的使用(有实例项目给的地址)

    除了在Matlab中使用PRTools工具箱中的svm算法,Python中一样可以使用支持向量机做分类.因为Python中的sklearn库也集成了SVM算法,本文的运行环境是Pycharm. 一.导 ...

  5. Python中的支持向量机SVM的使用(有实例有源码)

    转自:http://www.cnblogs.com/luyaoblog/p/6775342.html 除了在Matlab中使用PRTools工具箱中的svm算法,Python中一样可以使用支持向量机做 ...

  6. 机器学习之支持向量机SVM之python实现ROC曲线绘制(二分类和多分类)

    目录 一.ROC曲线 二.TP.FP.TN.FN 三. python绘制ROC曲线(二分类) 1.思路 2.关键代码 3.完整代码 四. python绘制ROC曲线(多分类) 五.参考文献 一.ROC ...

  7. python支持向量机回归_Python中支持向量机SVM的使用方法详解

    除了在Matlab中使用PRTools工具箱中的svm算法,Python中一样可以使用支持向量机做分类.因为Python中的sklearn库也集成了SVM算法,本文的运行环境是Pycharm. 一.导 ...

  8. 支持向量机python代码_Python中的支持向量机SVM的使用(有实例)

    除了在Matlab中使用PRTools工具箱中的svm算法,Python中一样可以使用支持向量机做分类.因为Python中的sklearn库也集成了SVM算法,本文的运行环境是Pycharm. 一.导 ...

  9. python支持向量机_支持向量机(SVM)Python实现

    什么是支持向量机? "支持向量机"(SVM)是一种监督机器学习算法,可用于分类或回归挑战.然而,它主要用于分类问题.在这个算法中,我们将每一个数据项作为一个点在n维空间中(其中n是 ...

最新文章

  1. 中科院王斌教授加入小米,任自然语言处理首席科学家
  2. 寻宝天行服务器维护中,你好。我的电脑寻宝天行网站上不去,其他网址都可以上,都好几天了。要么就无访问,要么跳出个502什么的...
  3. jQueryUI modal dialog does not show close button (x) JQueryUI和BootStrap混用时候,右上角关闭按钮显示不出图标的解决办法...
  4. asp.net 用户注册怎么判断用户名是否重复 ajax,AJAX_asp.net结合Ajax验证用户名是否存在的代码,1, 使用JavaScript js文件,验证 - phpStudy...
  5. mysql在同一台机器上实现主从_MySQL 5.7主从搭建(同一台机器)
  6. 个人从源码理解JIT模式下angular编译AppModule的过程
  7. 阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_07-新增页面-前端-页面完善...
  8. 罗技无法使用计算机上的配置文件,罗技游戏软件检测不到游戏启动,导致无法自动切换配置文件...
  9. ms08067 分析与利用
  10. 组合导航(六):惯性导航误差建模
  11. 2019_WSDM_Social Attentional Memory Network Modeling Aspect- and Friend-level Differences in Recomme
  12. Google学术的使用指南
  13. Excel之如何使用VLOOKUP函数合并两张表
  14. Spring教程——Spring注入内部Bean
  15. 使用爬虫获取四川省各市的降雨量
  16. 城市交通大脑的内涵与顶层设计
  17. 阿里云AMD服务器ECS实例g6a、c6a和r6a性能参数详解
  18. python语言创意绘画是什么-Python街机模块的draw系列绘画例子集合
  19. WebGL实时视频(6) Unity里面显示视频
  20. c语言中未定义标识符IDD,一、Windows对话框—对话框及其模板

热门文章

  1. IBL(二) IBL中Specular 和Diffuse的计算(ReflectProbe 和 LightProbe)
  2. STL — 迭代器设计思维(二)
  3. python制作收费_python分段计费demo
  4. 团队作业(三):项目分工
  5. 亿级(无限级)并发,没那么难-科普文
  6. Python学习笔记:数据可视化(一)
  7. 全球重磁异常以及水深数据分享
  8. 第六章 半导体存储器【微机原理】
  9. 【降维打击,带你深度学习CPU(上)】
  10. 鲁兴海:英国皇室裁缝合作伙伴--地方--人民网