一.了解ROC与PR曲线
1.引入概念
假如需要我们在一堆食物中,分辨它是不是汉堡,我们该怎么做到呢?在机器学习的领域内,我们要不断预测,最终将其分类。但是预测的准确与否,该要怎么体现出来呢?这就需要我们的混淆矩阵了
2.混淆矩阵
就以上述例子,机器模型将是否为汉堡不断分类,可以得到这样的表格:
其中:
TP+FP+FN+TN:样本总数
TP+FP:成功预测
FN+TN:错误预测
TP+FN:正样本
FP+TN:负样本
3.ROC曲线
1.我们应该怎么样评估预测模型的好坏呢?这里就用到我们ROC曲线了
如果我们不断改变分类器阈值(当然范围是(0,1]),是否就可以得到很多不同的混淆矩阵,在通过某个曲线展示出来,最终就可以得到我们想要的模型评估方法!
其中:
TPR=TP/(TP+FN)
FPR=FP/(FP+TN)
从公式中看到,我们总是希望预测准确一些,那么要求TP的值大;同时,FP的值就要小,同一数据样本分母总是不变的,那么图形越靠近左上角越好。
2.AUC
定义为曲线与x轴围成面积大小,面积越大,则拟合效果越好(图中阴影大小)
4.PR曲线
单一的模型检测总是不准确的,我们从另一个指标得到了PR曲线:
其中,精确率(Precision)为纵轴,以召回率(Recall)为横轴
精确率是指分类器预测为正例的样本中,实际为正例的比例;召回率是指分类器正确预测为正例的样本占所有正例样本的比例。
公式:
precision = TP/(TP + FP)
recall = TP/(TP +FN)
我们希望precision与reacll值同时越大越好,那么图像就越靠近右上方越好
二.ROC与PR曲线的绘制
1.准备数据
首先需要准备分类器的预测结果以及真实标签。假设我们有一个二分类问题,可以使用sklearn.datasets
中的make_classification
函数生成一些随机的样本数据。
from sklearn.datasets import make_classification
import numpy as np
# 生成样本数据
X, y = make_classification(n_samples=1000, n_features=10, n_informative=3,
n_redundant=2, random_state=42)
# 将y中的0变为负例,1变为正例
y[y==0] = -1
2.定义分类器模型
在前面我们已经实现KNN算法,我们这里依旧选择其作为分类器
··导入KNeighborsClassifier模型:
from sklearn.neighbors import KNeighborsClassifier
··构建KNN分类器模型:
classifier = KNeighborsClassifier(n_neighbors=5) # 这里的n_neighbors可以根据需要进行调整
3.训练分类器并预测结果
from sklearn.model_selection import train_test_split
# 使用train_test_split函数将数据划分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)
# 训练分类器模型
classifier.fit(X_train, y_train)
# 预测测试集结果
y_score = classifier.decision_function(X_test)
4.计算评估指标
使用sklearn.metrics
中的函数计算评估指标,包括真阳性率、假阳性率、精确率和召回率。
from sklearn.metrics import roc_curve, precision_recall_curve, auc
# 计算ROC曲线数据点
fpr, tpr, thresholds_roc = roc_curve(y_test, y_score)
# 计算PR曲线数据点
precision, recall, thresholds_pr = precision_recall_curve(y_test, y_score)
5.绘制ROC曲线和PR曲线
使用matplotlib
库绘制ROC曲线和PR曲线。可以使用auc
函数计算ROC曲线和PR曲线的面积
import matplotlib.pyplot as plt
# 绘制ROC曲线
plt.plot(fpr, tpr, lw=2, label='ROC curve (AUC = %0.2f)' % auc(fpr, tpr))
plt.plot([0, 1], [0, 1], color='gray', lw=1, linestyle='--')
plt.xlim([-0.05, 1.05])
plt.ylim([-0.05, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic')
plt.legend(loc="lower right")
plt.show()
# 绘制PR曲线
plt.plot(recall, precision, lw=2, label='Precision-Recall curve (AUC = %0.2f)' % auc(recall, precision))
plt.xlim([-0.05, 1.05])
plt.ylim([-0.05, 1.05])
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.title('Precision-Recall')
plt.legend(loc="lower left")
plt.show()
6.源码如下:
from sklearn.datasets import make_classification
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_curve, precision_recall_curve, auc
import matplotlib.pyplot as plt
import numpy as np
# 生成样本数据
X, y = make_classification(n_samples=1000, n_features=10, n_informative=3,
n_redundant=2, random_state=42)
# 将y中的0变为负例,1变为正例
y[y==0] = -1
# 构建KNN分类器模型
classifier = KNeighborsClassifier(n_neighbors=5)
# 使用train_test_split函数将数据划分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)
# 训练分类器模型
classifier.fit(X_train, y_train)
# 预测测试集结果
y_score = classifier.predict_proba(X_test)[:, 1]
# 计算ROC曲线数据点
fpr, tpr, thresholds_roc = roc_curve(y_test, y_score)
# 计算PR曲线数据点
precision, recall, thresholds_pr = precision_recall_curve(y_test, y_score)
# 绘制ROC曲线
plt.plot(fpr, tpr, lw=2, label='ROC curve (AUC = %0.2f)' % auc(fpr, tpr))
plt.plot([0, 1], [0, 1], color='gray', lw=1, linestyle='--')
plt.xlim([-0.05, 1.05])
plt.ylim([-0.05, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic')
plt.legend(loc="lower right")
plt.show()
# 绘制PR曲线
plt.plot(recall, precision, lw=2, label='Precision-Recall curve (AUC = %0.2f)' % auc(recall, precision))
plt.xlim([-0.05, 1.05])
plt.ylim([-0.05, 1.05])
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.title('Precision-Recall')
plt.legend(loc="lower left")
plt.show()
7.图形效果:
三.实验小结
1.更新与改进
1.我在最终的图形绘制上计算了AUC的值,前面介绍了这是利用积分面积来评判模型拟合效果的方法,这为我们实验增加了可靠性
2.分类器的选择,我选择了更熟悉的KNN算法,这次是直接调用库中的方法,提高了我们实验便捷性
2.不足
1.样本不平衡问题:如果数据集中正负样本数量不平衡,比如正样本数量很少,那么ROC曲线和PR曲线可能会受到影响。在这种情况下,AUC值可能不足以准确评估分类器的性能。因此,建议在评估时使用其他指标,例如准确率、F1-score等,结合曲线绘制来对分类器进行全面评估。
2.评估方式的选择:ROC曲线适用于对分类器的整体表现进行评估,而PR曲线更适用于关注精确率和召回率的场景。因此,根据具体问题和需求,选择合适的评估方式。同时,可以使用多种评估指标和曲线进行综合分析。
··参数选择:在构建分类器模型时,KNN算法中的k值是一个重要的参数。不同的k值可能会导致不同的性能结果。因此,在实验中应该尝试不同的k值,并综合考虑各种评估指标和曲线结果,选择最优的k值。