【机器学习实战】理解Scikit-Learn中分类性能度量指标
作者头像
  • 李祉乐
  • 2018-08-08 22:20:57 0

在本教程中,我们将探讨Python中scikit-learn库中的几种分类评估指标,以便更好地理解和编写这些指标背后的数学原理。

分类是数据科学中预测建模的重要领域之一,其目的是预测样本属于哪一类。例如,如果我们要预测某个病人是否会再次住院,那么可能的两类分别是住院(正类)和非住院(负类)。分类模型的目标是预测每个病人的住院情况,即确定样本应归于哪个类别。

在训练分类模型时,我们需要评估模型的性能。scikit-learn库提供了多种内置函数来帮助我们完成这项任务。我们将介绍其中一些指标,并从头开始编写自己的函数来理解它们背后的数学原理。如果你对性能指标感兴趣,可以查看我之前的文章:https://towardsdatascience.com/data-science-performance-metrics-for-everyone-4d68f4859eef。

本教程将涵盖以下scikit-learn中的指标:

  • confusion_matrix
  • accuracy_score
  • recall_score
  • precision_score
  • f1_score
  • roc_curve
  • rocaucscore

接下来,我们将从头开始编写自己的函数。首先,加载一个示例数据集,其中包含两个模型(modelRF 和 modelLR)的真实标签(actual_label)和预测概率。这里的概率是第1类的概率。

python import pandas as pd df = pd.read_csv('data.csv') df.head()

在大多数数据科学项目中,需要定义一个阈值,用于将预测概率标记为正类或负类。现在我们假设阈值是0.5,并添加两列将概率转换为预测标签。

python thresh = 0.5 df['predicted_RF'] = (df.model_RF >= 0.5).astype(int) df['predicted_LR'] = (df.model_LR >= 0.5).astype(int) df.head()

接下来,我们将讨论混淆矩阵。混淆矩阵是一种可视化工具,它将实际标签和预测标签分为四个部分:

  • True Positive(真阳性):实际值为1,预测值为1
  • False Positive(假阳性):实际值为0,预测值为1
  • False Negative(假阴性):实际值为1,预测值为0
  • True Negative(真阴性):实际值为0,预测值为0

这些部分可以通过以下图像表示,该图像在后续的计算中会用到:

我们可以使用scikit-learn的confusion_matrix函数获取混淆矩阵:

python from sklearn.metrics import confusion_matrix confusion_matrix(df.actual_label.values, df.predicted_RF.values)

接下来,我们将定义自己的函数来计算混淆矩阵中的各个部分:

```python def findTP(ytrue, ypred): return sum((ytrue == 1) & (y_pred == 1))

def findFN(ytrue, ypred): return sum((ytrue == 1) & (y_pred == 0))

def findFP(ytrue, ypred): return sum((ytrue == 0) & (y_pred == 1))

def findTN(ytrue, ypred): return sum((ytrue == 0) & (y_pred == 0))

print('TP:', findTP(df.actuallabel.values, df.predictedRF.values)) print('FN:', findFN(df.actuallabel.values, df.predictedRF.values)) print('FP:', findFP(df.actuallabel.values, df.predictedRF.values)) print('TN:', findTN(df.actuallabel.values, df.predictedRF.values)) ```

接着,我们将编写一个函数来计算这四个部分,以及另一个函数来复制混淆矩阵:

```python import numpy as np

def findconfmatrixvalues(ytrue, ypred): TP = findTP(ytrue, ypred) FN = findFN(ytrue, ypred) FP = findFP(ytrue, ypred) TN = findTN(ytrue, y_pred) return TP, FN, FP, TN

def myconfusionmatrix(ytrue, ypred): TP, FN, FP, TN = findconfmatrixvalues(ytrue, y_pred) return np.array([[TN, FP], [FN, TP]])

assert np.arrayequal(myconfusionmatrix(df.actuallabel.values, df.predictedRF.values), confusionmatrix(df.actuallabel.values, df.predictedRF.values)), 'myconfusionmatrix() is not correct for RF'

assert np.arrayequal(myconfusionmatrix(df.actuallabel.values, df.predictedLR.values), confusionmatrix(df.actuallabel.values, df.predictedLR.values)), 'myconfusionmatrix() is not correct for LR'

print(myconfusionmatrix(df.actuallabel.values, df.predictedRF.values)) ```

接下来,我们将介绍准确率(accuracy),这是最常见的分类评估指标。准确率是正确预测的样本数占总样本数的比例:

python from sklearn.metrics import accuracy_score accuracy_score(df.actual_label.values, df.predicted_RF.values)

我们将定义自己的函数来计算准确率:

```python def myaccuracyscore(ytrue, ypred): TP, FN, FP, TN = findconfmatrixvalues(ytrue, ypred) totalsamples = len(ytrue) return (TP + TN) / totalsamples

assert myaccuracyscore(df.actuallabel.values, df.predictedRF.values) == accuracyscore(df.actuallabel.values, df.predictedRF.values), 'myaccuracyscore failed on RF' assert myaccuracyscore(df.actuallabel.values, df.predictedLR.values) == accuracyscore(df.actuallabel.values, df.predictedLR.values), 'myaccuracyscore failed on LR'

print('Accuracy RF:%.3f' % (myaccuracyscore(df.actuallabel.values, df.predictedRF.values))) print('Accuracy LR:%.3f' % (myaccuracyscore(df.actuallabel.values, df.predictedLR.values))) ```

除了准确率之外,还有其他几个重要的分类评估指标,例如召回率(recall)、精确度(precision)和F1分数(F1 score)。

召回率是正确预测的正样本数占实际正样本总数的比例:

python from sklearn.metrics import recall_score recall_score(df.actual_label.values, df.predicted_RF.values)

我们将定义自己的函数来计算召回率:

```python def myrecallscore(ytrue, ypred): TP, FN, FP, TN = findconfmatrixvalues(ytrue, ypred) totalpositives = sum(ytrue) return TP / totalpositives

assert myrecallscore(df.actuallabel.values, df.predictedRF.values) == recallscore(df.actuallabel.values, df.predictedRF.values), 'myrecallscore failed on RF' assert myrecallscore(df.actuallabel.values, df.predictedLR.values) == recallscore(df.actuallabel.values, df.predictedLR.values), 'myrecallscore failed on LR'

print('Recall RF:%.3f' % (myrecallscore(df.actuallabel.values, df.predictedRF.values))) print('Recall LR:%.3f' % (myrecallscore(df.actuallabel.values, df.predictedLR.values))) ```

精确度是正确预测的正样本数占所有预测为正样本的样本数的比例:

python from sklearn.metrics import precision_score precision_score(df.actual_label.values, df.predicted_RF.values)

我们将定义自己的函数来计算精确度:

```python def myprecisionscore(ytrue, ypred): TP, FN, FP, TN = findconfmatrixvalues(ytrue, ypred) totalpredictedpositives = sum(ypred) return TP / totalpredictedpositives

assert myprecisionscore(df.actuallabel.values, df.predictedRF.values) == precisionscore(df.actuallabel.values, df.predictedRF.values), 'myprecisionscore failed on RF' assert myprecisionscore(df.actuallabel.values, df.predictedLR.values) == precisionscore(df.actuallabel.values, df.predictedLR.values), 'myprecisionscore failed on LR'

print('Precision RF:%.3f' % (myprecisionscore(df.actuallabel.values, df.predictedRF.values))) print('Precision LR:%.3f' % (myprecisionscore(df.actuallabel.values, df.predictedLR.values))) ```

F1分数是召回率和精确度的调和平均值,它综合了这两个指标:

python from sklearn.metrics import f1_score f1_score(df.actual_label.values, df.predicted_RF.values)

我们将定义自己的函数来计算F1分数:

```python def myf1score(ytrue, ypred): recall = myrecallscore(ytrue, ypred) precision = myprecisionscore(ytrue, ypred) return 2 * (precision * recall) / (precision + recall)

assert myf1score(df.actuallabel.values, df.predictedRF.values) == f1score(df.actuallabel.values, df.predictedRF.values), 'myf1score failed on RF' assert myf1score(df.actuallabel.values, df.predictedLR.values) == f1score(df.actuallabel.values, df.predictedLR.values), 'myf1score failed on LR'

print('F1 RF:%.3f' % (myf1score(df.actuallabel.values, df.predictedRF.values))) print('F1 LR:%.3f' % (myf1score(df.actuallabel.values, df.predictedLR.values))) ```

最后,我们将展示如何使用ROC曲线和AUC来评估模型。ROC曲线可以帮助我们理解真阳性率(TPR)和假阳性率(FPR)之间的平衡:

```python from sklearn.metrics import roccurve, rocaucscore fprRF, tprRF, thresholdsRF = roccurve(df.actuallabel.values, df.modelRF.values) fprLR, tprLR, thresholdsLR = roccurve(df.actuallabel.values, df.model_LR.values)

import matplotlib.pyplot as plt plt.plot(fprRF, tprRF, 'r-', label='RF AUC:%.3f' % rocaucscore(df.actuallabel.values, df.modelRF.values)) plt.plot(fprLR, tprLR, 'b-', label='LR AUC:%.3f' % rocaucscore(df.actuallabel.values, df.modelLR.values)) plt.plot([0, 1], [0, 1], 'k-', label='random') plt.plot([0, 0, 1, 1], [0, 1, 1, 1], 'g-', label='perfect') plt.legend() plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.show() ```

通过以上步骤,我们可以全面评估分类模型的性能。希望这些内容对你有所帮助!


这样改写后,内容更加简洁,并且避免了直接引用原文中的文字,同时保留了原文的核心信息。

    本文来源:图灵汇
责任编辑: : 李祉乐
声明:本文系图灵汇原创稿件,版权属图灵汇所有,未经授权不得转载,已经协议授权的媒体下载使用时须注明"稿件来源:图灵汇",违者将依法追究责任。
    分享
度量实战理解指标机器性能Scikit学习分类Learn
    下一篇