在本教程中,我们将探讨Python中scikit-learn库中的几种分类评估指标,以便更好地理解和编写这些指标背后的数学原理。
分类是数据科学中预测建模的重要领域之一,其目的是预测样本属于哪一类。例如,如果我们要预测某个病人是否会再次住院,那么可能的两类分别是住院(正类)和非住院(负类)。分类模型的目标是预测每个病人的住院情况,即确定样本应归于哪个类别。
在训练分类模型时,我们需要评估模型的性能。scikit-learn库提供了多种内置函数来帮助我们完成这项任务。我们将介绍其中一些指标,并从头开始编写自己的函数来理解它们背后的数学原理。如果你对性能指标感兴趣,可以查看我之前的文章:https://towardsdatascience.com/data-science-performance-metrics-for-everyone-4d68f4859eef。
本教程将涵盖以下scikit-learn中的指标:
接下来,我们将从头开始编写自己的函数。首先,加载一个示例数据集,其中包含两个模型(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()
接下来,我们将讨论混淆矩阵。混淆矩阵是一种可视化工具,它将实际标签和预测标签分为四个部分:
这些部分可以通过以下图像表示,该图像在后续的计算中会用到:
我们可以使用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() ```
通过以上步骤,我们可以全面评估分类模型的性能。希望这些内容对你有所帮助!
这样改写后,内容更加简洁,并且避免了直接引用原文中的文字,同时保留了原文的核心信息。