sklearn下对于二分类和多类分类问题的评估方法总结

目录

 

二分类:

多分类:

一、什么是多类分类?

二、如何处理多类分类?

三、代码实践:

评估指标:混淆矩阵,accuracy,precision,f1-score,AUC,ROC,P-R(不能用)

1.混淆矩阵:

2. accuracy,precision,reacall,f1-score:

3. ROC图和AUC值:

4 . 多类分类问题不能用P-R曲线 

5.其他评分函数 : score  和 classification_report


二分类:

之前做了二分类问题的评估总结,代码和注释 在我的github:https://github.com/Clarksh/python_data_analyse/blob/master/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%AE%9E%E8%B7%B5/task4_%E6%A8%A1%E5%9E%8B%E8%AF%84%E4%BC%B0%EF%BC%88%E6%95%B4%E7%90%86%E7%89%88%EF%BC%89.ipynb

 

多分类:


 那么多类分类下sklearn那些评估指标还能不能用呢?如果能用,为什么能用?应当如何使用?本文就是来解决这个问题。

参考:
https://blog.csdn.net/mixiaolemy/article/details/84529051
https://blog.csdn.net/YE1215172385/article/details/79443552
https://blog.csdn.net/zhanht/article/details/88669537

本文代码连接:https://github.com/Clarksh/python_data_analyse/blob/master/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%AE%9E%E8%B7%B5/%E5%A4%9A%E5%88%86%E7%B1%BB%E7%9A%84%E8%AF%84%E4%BC%B0%E9%97%AE%E9%A2%98.ipynb

一、什么是多类分类?

       多类分类(multiclass是指具有两类以上的分类任务; 例如,分类一组可能是橘子,苹果或梨的水果图像。多类分类假设每个样品分配到一个且仅一个标签:水果可以是苹果或梨,但不能同时两个。
       当然还有其他:
       多标签分类(multilabel)为每个样本分配一组目标标签。这可以被认为是预测不相互排斥的数据点的属性,例如与文档相关的主题。一个文字可能是宗教,政治,金融或教育的任何一个或者同时或没有一个。
       更多内容查看:https://blog.csdn.net/mixiaolemy/article/details/84529051

       要说明一点, scikit-learn中的所有分类器都是开箱即用的多类分类,在使用评估方法时相比于二分类问题,记得加一些处理和加上额外的参数就可以,详情看后面的代码。

二、如何处理多类分类?

 -----》对标签编码成one-hot !!! 

       假设测试样本个数为m,类别个数为n。预测得到测试样本的在各类别下的概率,得到一个[m, n]形状的概率矩阵P,将每个测试样本的标签转换为one-hot ,每个位置用来标记是否属于对应的类别,由此也可以获得一个[m, n]的标签矩阵L。
     将标签转换为one-hot,举个例子:
     0 -> 100
     1 -> 010
      2->001

然后接下来多类分类评估有两种办法,分别对应sklearn.metrics中参数average值为'micro'和'macro'的情况。两种方法求的值也不一样。
方法一:'micro':Calculate metrics globally by counting the total true positives, false negatives and false positives.
每种类别下,都可以得到m个测试样本为该类别的概率(矩阵P中的列)。所以,根据概率矩阵P和标签矩阵L中对应的每一列,可以计算出各个阈值下的假正例率(FPR)和真正例率(TPR),从而绘制出一条ROC曲线。这样总共可以绘制出n条ROC曲线。最后对n条ROC曲线取平均,即可得到最终的ROC曲线。

方法二:'macro':Calculate metrics for each label, and find their unweighted mean. This does not take label imbalance into account.
(没看很懂?):首先,对于一个测试样本:1)标签只由0和1组成,1的位置表明了它的类别(可对应二分类问题中的‘’正’’),0就表示其他类别(‘’负‘’);2)要是分类器对该测试样本分类正确,则该样本标签中1对应的位置在概率矩阵P中的值是大于0对应的位置的概率值的。基于这两点,将标签矩阵L和概率矩阵P分别按行展开,转置后形成两列,这就得到了一个二分类的结果。所以,此方法经过计算后可以直接得到最终的ROC曲线。

 

三、代码实践:

  处理和建模:

注意的是:预测值y的三种形式:
 #形式一:原始值(0或1或2),默认是返回形式二中概率最大的那个类别。
 #形式二:各类概率值,比如  [  8.79681649e-01   1.20307538e-01   1.08131372e-05]  每一个样本分别分三类的概率值。
 # 形式三:one-hot值 是形式一的ont-hot 

from sklearn import datasets
import numpy as np
from sklearn.preprocessing import label_binarize
from sklearn.metrics import confusion_matrix, precision_score, accuracy_score,recall_score, f1_score,roc_auc_score


iris = datasets.load_iris()
n_class = len(set(iris.target))                               # 类别数量

x, y = iris.data, iris.target
y_one_hot = label_binarize(y, np.arange(n_class))             # 转化为one-hot

# 建模
model = LogisticRegression()
model.fit(x, y)

# 预测值y的三种形式
y_score = model.predict(x)                                    # 形式一:原始值(0或1或2)
y_score_pro = model.predict_proba(x)                          # 形式二:各类概率值
y_score_one_hot = label_binarize(y_score, np.arange(n_class)) # 形式三:one-hot值

评估指标:混淆矩阵,accuracy,precision,f1-score,AUC,ROC,P-R(不能用)

1.混淆矩阵:

只能用原始数值,不能用one-hot数值

obj1 = confusion_matrix(y, y_score)
print('confusion_matrix\n', obj1)

# 结果:
confusion_matrix
 [[50  0  0]
 [ 0 45  5]
 [ 0  1 49]]

2. accuracy,precision,reacall,f1-score:

用原始数值和one-hot数值都行;accuracy不用加average='micro'(因为没有),其他的都要加上

在二分类中,上面几个评估指标默认返回的是 正例的 评估指标; 在多分类中 , 返回的是每个类的评估指标的加权平均值

print('accuracy:{}'.format(accuracy_score(y, y_score)))
print('precision:{}'.format(precision_score(y, y_score,average='micro')))
print('recall:{}'.format(recall_score(y, y_score,average='micro')))
print('f1-score:{}'.format(f1_score(y, y_score,average='micro')))
#结果:
accuracy:0.96
precision:0.96
recall:0.96
f1-score:0.96

3. ROC图和AUC值:

    先从二分类角度理解 什么是ROC图和AUC值:
    https://mp.weixin.qq.com/s/LwKiqYkZpW1jCLpGdov3SQ 这篇文章讲的很清楚。

    然后多类分类下面怎么使用:
   要用概率值(形式二) ,加参数 average='micro'  (不能用ont-hot (形式三) )

用概率值(形式二):变化阈值产生多个ROC值连成曲线

from sklearn.metrics import roc_curve
%matplotlib inline

# AUC值
auc = roc_auc_score(y_one_hot, y_score_pro,average='micro')

# 画ROC曲线
fpr, tpr, thresholds = roc_curve(y_one_hot.ravel(),y_score_pro.ravel())   # ravel()表示平铺开来
plt.plot(fpr, tpr, linewidth = 2,label='AUC=%.3f' % auc)
plt.plot([0,1],[0,1], 'k--')
plt.axis([0,1.1,0,1.1])
plt.xlabel('False Postivie Rate')
plt.ylabel('True Positive Rate')
plt.legend()
plt.show()
auc = roc_auc_score(y_one_hot, y_score_pro,average='micro')

  结果如图:

如果用one-hot(形式三) : 求AUC已经确定了(不用变化阈值),只有一个确定的ROC值
结果如图:只有折角那个点是ROC值

4 . 多类分类问题不能用P-R曲线 

 仅在二分类问题中可以用P-R曲线,看到文档里面写着  this implementation is restricted to the binary classification task
 不过既然提到了,我们就来讲讲P-R曲线在二分类中的使用,还有和ROC曲线的区别:
(1)P-R曲线代码:

 

from sklearn.metrics import precision_recall_curve
def draw_pr(y_true, y_pred,label=None):
    precision,recall,thresholds = precision_recall_curve(y_true, y_pred)
    plt.plot(recall,precision,linewidth = 2, label=label)
    plt.plot([0,1],[0,1], 'k--')
    plt.axis([-0.05,1.05,-0.05,1.05])
    plt.xlabel("Recall Rate")
    plt.ylabel("Precision Rate")

#这里也是要用的是概率值,y_train_pro_lr[:,1]取了概率值中的正例的概率
draw_pr(y_train,y_train_pro_lr[:,1],'lr_train')
draw_pr(y_test,y_test_pro_lr[:,1],'lr_test')
plt.legend()
plt.show()

结果如图:

怎么来看P-R 图好不好?

用P-R曲线判定分类器效果,方法很简单,就看曲线和XY轴围成图形的面积,面积越大,分类器效果越好。 有时候也会分析和y=x的交点(不是很懂)

如何在P-R图中寻找最佳阈值?

选取合适的阈值点要根据实际需求,比如我们想要高的召回率R,那么我们就会牺牲一些准确率P,在保证R最高的情况下,P也不那么低。(比如在企业中对召回率的要求就比较严苛,毕竟关乎用户体验,能尽量返回结果)
要找到想要的P和R对应的阈值:找到对应索引就好

precision,recall,thresholds = precision_recall_curve(y_true, y_pred)
# 输出
precision: [ 0.25965131  0.25942074  0.25950156 ...,  1.          1.          1.        ] 
recall:    [ 1.          0.99880096  0.99880096 ...,  0.00239808  0.00119904  0.        ] 
thresholds:[ 0.0235701   0.02362303  0.02364767 ...,  0.99963826  0.9998569   0.99989261]


(2)P-R曲线 vs ROC曲线:
PR曲线的稳定性不如roc,在数据不平衡的情况下表现很差。

观察图能够发现,当正样本比例减小时,ROC曲线变化不明显,但是P-R曲线的纵坐标,即准确率出现了明显的衰减。
原因是,当样本严重倾斜时,我们假定召回率不变,那么表现较差的模型必然会召回更多的负样本,那么FP(假正例)就会迅速增加,准确率就会大幅衰减。

 

5.其他评分函数 : score  和 classification_report

(1)score  :  返回的是accuracy平均值 ,是评判模型最直观的方法

clf_lr = LogisticRegression()
clf_lr.fit(x_train, y_train)
clf_lr.score(x_test, y_test)

(2)classification_report :综合评估,是评判模型便捷且全面的方法(参数digits控制精度)

clf_lr = LogisticRegression()
clf_lr.fit(x_train, y_train)
y_pred = clf_lr.predict(x_test)
ans = classification_report(y_test,y_pred,digits=5)
print(ans)
#结果 :
          precision    recall  f1-score   support

          0    0.81006   0.93446   0.86783      1068
          1    0.64103   0.34819   0.45126       359

avg / total    0.76754   0.78697   0.76303      1427

 

  • 16
    点赞
  • 143
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值