1.引入参数C后的支持向量

软间隔让决定两条虚线超平面的支持向量可能是来自于同一个类别的样本点,而硬间隔的时候两条虚线超平面必须是来自两个不同类别的支持向量决定的。

C值会决定我们究竟是依赖红色点作为支持向量,还是要依赖软间隔中混在在红色中的紫色点来作为支持向量。如果C值设定较大,那SVC可能会选择边际较小的,能够更好地分类所有训练点的决策边界,训练时间也会变长。如果C的设定值较小,那SVC会尽量最大化边界,尽量将掉落在决策边界另一方的样本点预测正确,这样会影响训练的决策准确度。此时,所有可能影响超平面的样本都会被定义为支持向量,而不仅仅是压在虚线超平面上的点,是哪些混在彼此类别中的点。
观察不同数据集分类的支持向量
数据导入以及绘制linear下各个数据集的支持向量

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn import svm
from sklearn.datasets import make_circles, make_moons,make_blobs,make_classificationn_samples =100
datasets = [make_moons(n_samples=n_samples, noise=0.2, random_state=0),make_circles(n_samples=n_samples, noise=0.2, factor=0.5, random_state=1),make_blobs(n_samples=n_samples, centers=2, random_state=5),make_classification(n_samples=n_samples,n_features =
2,n_informative=2,n_redundant=0, random_state=5)
]
Kernel = ["linear"]
for X,Y in datasets:plt.figure(figsize=(5,4))plt.scatter(X[:,0],X[:,1],c=Y,s=50,cmap="rainbow")
nrows=len(datasets)
ncols=len(Kernel)+1fig, axes = plt.subplots(nrows,ncols,figsize=(10,16))
for ds_cnt, (X,Y) in enumerate(datasets):ax = axes[ds_cnt,0]if ds_cnt ==0:ax.set_title("Input data")ax.scatter(X[:,0],X[:,1],c=Y,zorder=10,cmap=plt.cm.Paired,edgecolors='k')ax.set_xticks(())ax.set_yticks(())for est_idx, kernel in enumerate(Kernel):ax = axes[ds_cnt,est_idx+1]clf = svm.SVC(kernel=kernel,gamma=2).fit(X,y)score =clf.score(X,Y)ax.scatter(X[:,0],X[:,1],c=Y,zorder=10,cmap=plt.cm.Paired,edgecolors='k')ax.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,1],s=100,facecolors='none',zorder=10,edgecolors='white')x_min, x_max = X[:,0].min()-.5,X[:,0].max()+.5y_min, y_max = X[:,1].min()-.5,X[:,1].max()+.5XX, YY = np.mgrid[x_min:x_max:200j, y_min:y_max:200j]#np.c_,类似于np.vstack的功能Z = clf.decision_function(np.c_[XX.ravel(), YY.ravel()]).reshape(XX.shape)ax.pcolormesh(XX,YY,Z>0,cmap=plt.cm.Paired)ax.contour(XX,YY,Z,colors=['k','k','k'],linestyles=['--','-','--'],levels=[-1,0,1])ax.set_xticks(())ax.set_yticks(())if ds_cnt==0:ax.set_title(kernel)ax.text(0.95,0.06,('%.2f'% score).lstrip('0'),size=15,bbox=dict(boxstyle='round',alpha=0.8,facecolor='white'),transform=ax.transAxes,horizontalalignment='right')
plt.tight_layout()
plt.show()




其中白色圈出来的就是我们的支持向量,可以看到所有在两条虚线超平面之间的点,和虚线超平面外的,但属于另一个类别的点,都被认为是支持向量,并不是因为这些点都在超平面上,而是因为超平面由所有的这些点来决定,可以调节C来移动超平面,让超平面超过任何一个白色点。

2.SVC重要参数class_weight

分类模型天生倾向于多数的类,即让多数类判断正确,少数类被牺牲掉。为了让算法意识到数据的标签是不均衡的,通过一些惩罚或者改变样本本身,让模型向着捕获少数类的方向建模。SVC中一半调整SVC类中的class_weight和接口fit中可以设定的sample_weight参数

逻辑回归中的上采样下采样方法,会增加样本点的总数,对于SVC这种算法来说。样本量对计算速度的影响很大,而且决策边界仅仅受到参数C和支持向量的影响,单纯增加样本数量可能增加无数对决策边界无影响的点。

SVC的参数:class_weight
默认None,表示自动认为标签比例为1:1,所有类都被假设为占有相同的权重1,模型会根据数据原本的状况去训练。可以添加字典来进行调整。或者输入‘balanced’,使使用y的值自动调整为与输入数据中的类频率成反比的权重n_samples/(n_classes * np.bincount(y))
SVC的接口fit的参数:sample_weight
数组,结构为 (n_samples, ),必须对应输入fit中的特征矩阵的每个样本。每个样本在fit时的权重,让权重 * 每个样本对应的C值来迫使分类器强调设定的权重更大的样本。通常,较大的权重加在少数类的样本上,以迫使模型向着少数类的方向建模

通常设置两个参数中的一个即可

分别绘制进行了数据平衡与未数据平衡数据的决策边界
步骤一:导入库和创建不平衡的数据集

import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.datasets import make_blobsclass_1 = 500
class_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 = svm.SVC(kernel='linear',C=1.0)
clf.fit(X,y)
wclf = svm.SVC(kernel='linear',class_weight={1:10})
wclf.fit(X,y)clf.score(X,y)
wclf.score(X,y)


步骤三:绘制两个模型下的数据的决策边界

#获取数据分布以及网格
plt.figure(figsize=(6,5))
plt.scatter(X[:,0],X[:,1],c=y,cmap="rainbow",s=10)
ax=plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
xx = np.linspace(xlim[0],xlim[1],30)
yy = np.linspace(ylim[0],ylim[1],30)
YY,XX =np.meshgrid(yy,xx)
xy = np.vstack([XX.ravel(),YY.ravel()]).T
#找出样本点到决策边界的距离
Z_clf = clf.decision_function(xy).reshape(XX.shape)
a = ax.contour(XX,YY,Z_clf,colors='black',levels=[0],alpha=0.5,linestyles=['-'])
Z_wclf = wclf.decision_function(xy).reshape(XX.shape)
b = ax.contour(XX,YY,Z_wclf,colors='red',levels=[0],alpha=0.5,linestyles=['-'])
#画图例
plt.legend([a.collections[0],b.collections[0]],["non weighted","weighted"],loc="upper right")
plt.show()


从准确率的角度来看,不做样本平衡的准确率反而更高。这是因为做了样本平衡之后,为了更加有效的捕捉出少数类,模型多数类被分错的数量>少数类被分类正确的数量,如果此时我们追求的是模型整体的准确率,那么就要拒绝样本平衡。当然实际生活中,我们往往追求的是捕捉少数类,因为它们判错的代价比较大。

3.SVC的模型评估指标

混淆矩阵

  • 准确率 Accuracy:整体效果
  • 精确度 Precision:多数类判错成本
(y[y == clf.predict(X)] == 1).sum()/(clf.predict(X) ==1).sum()
(y[y == wclf.predict(X)] == 1).sum()/(wclf.predict(X) ==1).sum()


它可以帮我们判断是否每一次对少数类的预测都精确,所以又被称为“查准率”。如果代价是不惜一切捕捉少数类,则不必在意。

  • 召回率 Recall:真实为1 的样本中预测正确占的比例
(y[y == clf.predict(X)] ==1).sum()/(y==1).sum()
(y[y == wclf.predict(X)] ==1).sum()/(y==1).sum()


如果不在意少数类,则不必在意。

  • 假负率 False Negative Rate:1-Recall

  • F1 measure:同时兼顾精确度和召回率

F−measure=21Precision+1Recall=2∗Precision∗RecallPrecision+RecallF-measure=\frac{2}{\frac{1}{Precision}+\frac{1}{Recall}}=\frac{2*Precision*Recall}{Precision+Recall}F−measure=Precision1​+Recall1​2​=Precision+Recall2∗Precision∗Recall​
两个数的调和平均倾向于靠近两个数中比较小的那一个数,高的F1值能保证精确度和召回率都较高

  • 特异度 Specificity:真实为0的样本中,被正确预测为0所占的比例
(y[y == clf.predict(X)] == 0).sum()/(y==0).sum()
(y[y == wclf.predict(X)] == 0).sum()/(y==0).sum()

  • 假正率 False Positive Rate:1-specificity

sklearn中的混淆矩阵

含义
sklearn.metrics.confusion_matrix 混淆矩阵
sklearn.metrics.accuracy_score 准确率accuracy
sklearn.metrics.precision_score 精确度precision
sklearn.metrics.recall_score 召回率recall
sklearn.metrics.precision_recall_curve 精确度-召回率平衡曲线
sklearn.metrics.f1_score F1 measure

ROC曲线
全称The Receiver Operating Characteristic Curve,是一条以不同阈值下的假正率FPR为横坐标,不同阈值下的召回率为纵坐标的曲线

概率probability和阈值threshold
步骤一:数据创建

class_1_ = 7
class_2_ = 4
centers_ = [[0.0, 0.0], [1,1]]
clusters_std = [0.5, 1]
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=30)
plt.show()


步骤二:建模调用概率

from sklearn.linear_model import LogisticRegression as LogiR
clf_lo = LogiR().fit(X_,y_)
prob = clf_lo.predict_proba(X_)
import pandas as pd
prob = pd.DataFrame(prob)


步骤三:设置阈值0,5,大于0,5的预测为1

for i in range(prob.shape[0]):if prob.loc[i,"1"] > 0.5:prob.loc[i,"pred"] =1else:prob.loc[i,"pred"]=0
prob["y_true"]=y_
prob = prob.sort_values(by="1",ascending=False)


步骤四:使用混淆矩阵查看结果

from sklearn.metrics import confusion_matrix as CM,precision_score as P ,recall_score as R
CM(prob.loc[:,"y_true"],prob.loc[:,"pred"],labels=[1,0])
P(prob.loc[:,"y_true"],prob.loc[:,"pred"],labels=[1,0])
R(prob.loc[:,"y_true"],prob.loc[:,"pred"],labels=[1,0])


步骤五:设置阈值为5并查看变化

for i in range(prob.shape[0]):if prob.loc[i,"1"] > 0.4:prob.loc[i,"pred"] =1else:prob.loc[i,"pred"]=0
CM(prob.loc[:,"y_true"],prob.loc[:,"pred"],labels=[1,0])
P(prob.loc[:,"y_true"],prob.loc[:,"pred"],labels=[1,0])
R(prob.loc[:,"y_true"],prob.loc[:,"pred"],labels=[1,0])



可以看到,不同阈值下模型的评估指标也会发生变化。升高或者降低阈值并不能确保Recall的改变,一切要根据数据的实际变化来进行判断。如果有概率需求,通常优先考虑逻辑回归和朴素贝叶斯。

4.SVM实现概率预测

decision_function
返输入的特征矩阵中每个样本到划分数据集的超平面的距离,也被称为SVM的置信度(confidence)

SVC参数probability

参数 含义
probability 布尔值,可不填,默认False ,是否启用概率估计
进行必须在调用fit之前启用它,启用此功能会减慢SVM的运算速度

设置为True则会启动,启用之后,SVC的接口predict_proba和predict_log_proba将生效。在二分类情况下,SVC将使用Platt缩放来生成概率,即在decision_function生成的距离上进行Sigmoid压缩,并附加训练数据的交叉验证拟合,来生成类逻辑回归的SVM分数

概率预测实现
步骤一:创建数据

class_1 = 500
class_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 = svm.SVC(kernel="linear",C=1.0,probability=True).fit(X,y)
clf_proba.predict_proba(X)
clf_proba.predict_proba(X).shape
clf_proba.decision_function(X)
clf_proba.decision_function(X).shape


由于是距离,所以decision_function只会生成一列距离。注意,Platt缩放中涉及的交叉验证对于大型数据集来说非常昂贵,计算会非常缓慢。另外,由于Platt缩放的理论原因,在二分类过程中,有可能出现predict_proba返回的概率小于0.5,但样本依旧被标记为正类的情况出现,毕竟支持向量机本身并不依赖于概率来完成自己的分类。如果需要置信度分数,但不一定非要是概率形式的话,那建议可以将probability设置为False,使用decision_function这个接口而不是predict_proba

手动绘制SVM的ROV曲线
ROC是一条以不同阈值下假正率FPR为横坐标,不同阈值下的召回率为纵坐标的曲线,因此需要不断调整阈值求解混淆矩阵。

recall = []
FPR = []
probrange = np.linspace(clf_proba.predict_proba(X)[:,1].min(),clf_proba.predict_proba(X)[:,1].max(),num=50,endpoint=False)
from sklearn.metrics import confusion_matrix as CM,recall_score as R
import matplotlib.pyplot as plotfor i in probrange:y_predict = []for j in range(X.shape[0]):if clf_proba.predict_proba(X)[j,1]>i:y_predict.append(1)else:y_predict.append(0)cm = CM(y,y_predict,labels=[1,0])recall.append(cm[0,0]/cm[0,:].sum())FPR.append(cm[1,0]/cm[1,:].sum())
recall.sort()
FPR.sort()
plt.plot(FPR,recall,c="red")
plt.plot(probrange+0.05,probrange+0.05,c="black",linestyle="--")
plt.show()


建立ROC曲线的根本目的是找寻Recall和FPR之间的平衡,能够在尽量在捕捉少数类的时候,误伤多数类的情况会如何变化。横坐标是FPR,代表着模型将多数类判断错误的能力,纵坐标Recall,代表着模型捕捉少数类的能力,所以ROC曲线代表着,随着Recall的不断增加,FPR如何增加。
对于一条凸型ROC曲线来说,曲线越靠近左上角越好,越往下越糟糕,曲线如果在虚线的下方,则证明模型完全无法使用。但是它也有可能是一条凹形的ROC曲线。对于一条凹型ROC曲线来说,应该越靠近右下角越好,凹形曲线代表模型的预测结果与真实情况完全相反,那也不算非常糟糕,只要手动将模型的结果逆转,就可以得到一条左上方的弧线了。最糟糕的就是,无论曲线是凹形还是凸型,曲线位于图像中间,和虚线非常靠近。

sklearn中绘制ROC曲线和AUC面积

from sklearn.metrics import roc_curve
FPR,recall,thresholds = roc_curve(y,clf_proba.decision_function(X),pos_label=1)
from sklearn.metrics import roc_auc_score as AUC
area = AUC(y,clf_proba.decision_function(X))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.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()


利用ROC曲线找到最佳阈值

maxindex = (recall - FPR).tolist().index(max(recall - FPR))
thresholds[maxindex]
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()


还可以用KS曲线,或者收益曲线(profit chart)来选择我们的阈值,都是和ROC曲线类似的用法。

ccc-sklearn-9-SVM(3)相关推荐

  1. sklearn中的支持向量机SVM(下)

    1 二分类SVC的进阶 1.1 SVC用于二分类的原理复习 sklearn中的支持向量机SVM(上) 1.2 参数C的理解进阶 有一些数据,可能是线性可分的,但在线性可分状况下训练准确率不能达到100 ...

  2. sklearn SVM(支持向量机)模型使用RandomSearchCV获取最优参数及可视化​​​​​​​

    sklearn SVM(支持向量机)模型使用RandomSearchCV获取最优参数及可视化 支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义 ...

  3. sklearn实战-----8.支持向量机SVM(下)

    1 二分类SVC的进阶 1.1 SVC用于二分类的原理复习 在上周的支持向量SVM(上)中,我们学习了二分类SVC的所有基本知识,包括SVM的原理,二分类SVC的损失函数,拉格朗日函数,拉格朗日对偶函 ...

  4. SVM(支持向量机)

    目录 前言 一.SVM和KNN 二.SVM分类的代码实现 1.引入库 2.导入数据集 3.构建SVM分类器,训练函数 4.初始化分类器实例,训练模型 5.展示训练结果及验证结果 总结 前言 SVM 最 ...

  5. 支持向量机SVM(下)

    一. 二分类SVC的进阶 1 SVC用于二分类的原理复习 在支持向量SVM(上)中,学习了二分类SVC的所有基本知识,包括SVM的原理,二分类SVC的损失函数,拉格朗日函数,拉格朗日对偶函数,预测函数 ...

  6. Hard-Margin SVM(支持向量机)

    什么是Hard-Margin SVM?指的是这个向量机只适用于"数据完全可分(seperately)"的情况. (一)什么是支持向量机? 上述三条直线,选择哪一条比较好?直觉上来说 ...

  7. 机器学习——SVM(支持向量机)与人脸识别

    目录 系列文章目录 一.SVM的概念与原理 1.SVM简介 2.SVM基本流程 3.SVM在多分类中的推广 二.经典SVM运用于图像识别分类 三.SVM运用于人脸识别 1.预处理 1.1 数据导入与处 ...

  8. SVM——(三)对偶性和KKT条件(Lagrange duality and KKT condition)

    之前说到过拉格朗日乘数法以及推导过程,那么今天要说的就是拉格朗日对偶性以及KKT条件 1.Lagrange multipliers 一句话说,拉格朗日乘数法就是用来解决条件极值的一个方法,且约束条件都 ...

  9. 学习SVM(四) 理解SVM中的支持向量(Support Vector)

    学习SVM(四) 理解SVM中的支持向量(Support Vector) 版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/chaipp0607/articl ...

  10. 支持向量机SVM(三)软间隔与松弛变量的替代损失函数

    前两篇关于SVM的讨论中,我们只讨论了样本在原始空间和特征空间中线性可分的情况,但是,现实不可能这么完美,就算真的被找到了,但是世上没有免费的午餐,最后的结果很可能过拟合了. 所以要来讨论一下,怎么付 ...

最新文章

  1. 计算机视觉:Bag of words算法实现图像识别与搜索
  2. mybatis 逆向工程使用姿势不对,把表清空了,心里慌的一比,于是写了个插件。
  3. 线上Java应用排查和诊断规范
  4. axure 链接html文件,通过WuliHub免费托管原型Axure HTML文件
  5. 长沙医学院学位计算机考试内容,湖南长沙医学院2017年9月计算机等级考试报名时间...
  6. python3软件怎么使用_python3怎么使用pip
  7. DOS命令 format
  8. Science亮点!ExSeq:完整生物组织的原位空间转录组分析
  9. WebApp 开发中常用的代码片段
  10. bash 脚本编写_如何在Bash中编写循环
  11. 阿里云ECS服务器 Centos7.2 使用 yum 安装 ansible 报错
  12. 化工企业数据分析报表系统项目之销售模块分析
  13. 【洛谷】【堆+贪心】P1484 种树
  14. SVM之Libsvm工具包的安装教程
  15. python可以下载百度文库_Python在线百度文库爬虫(免下载券)
  16. 作数学题应不该用计算机,数学奥数考试
  17. 分享一下我自己做的新媒体运营月报,有人看吗?
  18. UWB定位/RSSI定位 三边测量法trilateration C语言代码详解
  19. 有监督学习,无监督学习,强化学习总结
  20. AutoIt教程资源汇总

热门文章

  1. 两个进程共享内存,一个写,一个读
  2. 网站压力测试工具was
  3. CSDN的C币获得方法
  4. MeterSphere:超好用的开源测试平台
  5. 游戏安全与反外挂:加固工具介绍
  6. linux 入门命令,新手入门Linux命令集锦
  7. javaScript小案例------js实现手风琴效果篇
  8. c函数itoa和atoi实现
  9. android集成友盟u app,友盟U-Mini小程序集成指南
  10. PHP视频教程 全35讲rmvb格式下载