支持向量机专题03

1.二分类SVC中样本不均衡问题

1.1不均衡问题:重要参数class_weight

分类模型天生会倾向于多数的类,让多数类更容易被判断正确,少数类会被牺牲.即便模型什么都不做,把全部的样本都当成不会犯罪的人,即使模型的评估指标accuracy变得毫无意义,但却无法达到我们要求‘识别犯罪的人’的建模目的。

A.采样方法(与逻辑回归类似)
但在向量机模型中并不能被采用,支持向量机模型而言,样本对计算速度影响巨大,单纯增加样本数目不仅会增加计算时间,而且还会增加无数对决策边界无关的样本点。
B.标签赋予权重
class_weight、sample_weight ,通常来说,这两种参数我们只能选取一个来设置


1、导入所需的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.datasets import make_blobs
2、创造样本不均衡的数据集
class_1 = 500
class_2 = 50
centers = [[0.0 , 0.0] ,[2.0 ,2.0]]
cluster_std = [1.5 ,0.5]
X,y = make_blobs(n_samples=[class_1 , class_2]
                ,centers= centers
                ,cluster_std= cluster_std
                ,random_state= 0 
                ,shuffle= False
                )
plt.scatter(X[:,0],X[:,1],c=y , cmap = 'rainbow',s= 10)
-------------------------------------------------------------------------
3、建立两种模型(有无设置标签权重)
#不设定class_weight
clf = svm.SVC(kernel='linear')
clf.fit(X,y)
#设定class_weight
wclf = svm.SVC(kernel='linear',class_weight={1:10})
wclf.fit(X,y)
#第一种情况下的模型打分
clf.score(X,y) 0.9418181818181818
#第二种情况下的模型打分
wclf.score(X,y) 0.9127272727272727
-------------------------------------------------------------------------
4、绘制两个模型下数据的决策边界
#首先要有数据分布
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()

在这里插入图片描述

1.2混淆矩阵(Confusion Matrix)

在这里插入图片描述

1、准确度
A c c u r a c y = 11 + 10 11 + 10 + 01 + 00 Accuracy = \frac{11+10}{11+10+01+00} Accuracy=11+10+01+0011+10
准确度就是预测正确的所有样本除以总样本,通常越接近1越好。
准确度也是模型整体效果的评估单位

2、精准度
P r e c i s i o n = 11 11 + 01 Precision = \frac{11}{11+01} Precision=11+0111
精准度就是将多数类判错后所需付出成本的衡量
(y[y == clf.predict(X)] == 1).sum() / (clf.predict(X)==1).sum()
当每一次将多数类判断错误的成本十分高的时候,我们会追求高精确度。

3、召回率
R e c a l l = 11 11 + 10 Recall = \frac{11}{11+10} Recall=11+1011
召回率表示所有真实为1的样本中,被我们预测正确的样本所占的比例。
(y[y == clf.predict(X)] == 1).sum() / (y == 1).sum()
如果我们希望不计一切代价,找出少数类,我们就追求高召回率

4、F1 measure
F − m e a s u r e = 2 1 P r e c i s i o n + 1 R e c a l l = 2 ∗ P r e c i s i o n P r e c i s i o n + R e c a l l F - measure =\frac{2}{{1\over Precision} + {1\over Recall} } = \frac{2*Precision}{Precision+Recall} Fmeasure=Precision1+Recall12=Precision+Recall2Precision
F1 measure能够保证精确度和召回率都很高

5、特异度
S p e c i f i c i t y = 00 00 + 01 Specificity = \frac{00}{00+01} Specificity=00+0100
特异度表示所有真实为0的样本中,被正确预测为0的样本所占的比例。
(y[y == clf.predict(X)])
特异值衡量了一个模型将多数类判断正确的能力。

6、假正率
F P R = 01 00 + 01 FPR = \frac{01}{00+01} FPR=00+0101
假正率即1 - specificity 就是一个模型将多数类判断错误的能力。


2.ROC曲线及相关问题

2.1逻辑回归实现概率预测

1、自建数据集
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.datasets import make_blobs

class_1_ = 7
class_2_ = 4
centers_ = [[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)

在这里插入图片描述

2、建模,调用概率
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)
prob.columns = ['0', '1']
prob
		0			1
0	0.694619	0.305381
1	0.510931	0.489069
2	0.820038	0.179962
3	0.785647	0.214353
4	0.777387	0.222613
5	0.656634	0.343366
6	0.768586	0.231414
7	0.349171	0.650829
8	0.366184	0.633816
9	0.663272	0.336728
10	0.607529	0.392471
--------------------------------------------------------------------------------
3、使用阈值0.5,大于0.5的样本直接预测为1,小于0的样本预测为0
for i in range(prob.shape[0]):
    if prob.loc[i,'1'] > 0.5:
        prob.loc[i,'pred'] = 1
    else:
        prob.loc[i,'pred'] = 0
prob['y_true'] = y_
prob = prob.sort_values(by = '1', ascending= False)
prob
	0	1	pred	y_true
7	0.349171	0.650829	1.0	0
8	0.366184	0.633816	1.0	0
1	0.510931	0.489069	0.0	0
10	0.607529	0.392471	0.0	0
5	0.656634	0.343366	0.0	0
9	0.663272	0.336728	0.0	0
0	0.694619	0.305381	0.0	0
6	0.768586	0.231414	0.0	1
4	0.777387	0.222613	0.0	1
3	0.785647	0.214353	0.0	1
2	0.820038	0.179962	0.0	1
--------------------------------------------------------------------------------
4、使用混淆矩阵查看结果
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])

总结:在不同的阈值下其模型的评估指标会发生改变,但并不是说对阈值进行升高或降低就会发生定向改变,一切要根据数据的实际分布来进行判断。

2.2SVM实现概率预测

1、自建数据集
class_1 = 500
class_2 = 50
centers = [[0,0],[2,2]]
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)
array([[0.68035758, 0.31964242],
       [0.24033895, 0.75966105],
       [0.9662359 , 0.0337641 ],
       ...,
       [0.13634925, 0.86365075],
       [0.33415679, 0.66584321],
       [0.29297621, 0.70702379]])
 clf_proba.predict_proba(X).shape
 (550, 2)
 clf_proba.decision_function(X).shape
 (550,)

decision_function 只会生成一列距离,样本的类别由距离的符号来进行判断;predict_proba会生成两个类别分别对应的概率。

2.3绘制SVM的ROC曲线

ROC是一条以不同阈值下的假正率FPR为横坐标,不同阈值下的召回率Recall为纵坐标的曲线。
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 plot

for 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曲线来说,越靠近左上角说明效果拟合越好,越往下越糟糕。

2.4关于ROC的理解

sklearn.metrics.roc_curve(y_true ,y_score , pos_label = None , sample_weight = None , drop_intermediate = True)
可以帮助我们计算ROC曲线的横坐标假正率FPR , 纵坐标Recall和对应的阈值

from sklearn.metrics import roc_curve
FPR , recall , thresholds = roc_curve(y ,clf_proba.decision_function(X) , pos_label= 1)
返回ROC曲线下的FPR,Recall及对应的阈值的数值
from sklearn.metrics import roc_auc_score as AUC
area = AUC(y,clf_proba.decision_function(X))
返回我们计算AUC面积
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.xlabel('False Positive Rate')
plt.ylim([-0.05 , 1.05])
plt.ylabel('Recall')
plt.title('Receiver operating characteristic example')
plt.legend(loc = 'lower right')
plt.show()

在这里插入图片描述
约登指数:我们的希望是模型在捕获少数类的能力变强的时候,尽量不误伤多数类,也就是说,随着recall的变大,FPR的大小越小越好。而Recall和FPR差距最大的点,这个点叫做约登指数。

maxindex = (recall - FPR).tolist().index(max(recall - FPR))
thresholds[maxindex]
-1.0860191749391461
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 ='k' , s = 30)
plt.xlim([-0.05 , 1.05])
plt.xlabel('False Positive Rate')
plt.ylim([-0.05 , 1.05])
plt.ylabel('Recall')
plt.title('Receiver operating characteristic example')
plt.legend(loc = 'lower right')
plt.show()

在这里插入图片描述

最佳阈值就是这样选择出来的,我们选择的最佳阈值就是最佳距离,我们也可以选取的最佳阈值是一个概率值,我们让这个模型距离/概率以上的点为正类,以下的点为负类,模型就是最好的。即能捕捉少数类,又能不误伤多数类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值