一、PR曲线
PR曲线是以precision(精准率)和recall(召回率)这两个为变量而做出的曲线,其中recall为横坐标,precision为纵坐标。
1.精确率和召回率
公式: (精确率,所有预测为正样本中有多大比例为真正的正样本)
(召回率,所有正样本中有多大比例预测为正样本)
2.阈值
一个阈值对应PR曲线上的一个点。通过选择合适的阈值,比如50%,对样本进行划分,概率大于50%的就认为是正例,小于50%的就是负例,从而计算相应的精准率和召回率。(选取不同的阈值,就得到很多点,连起来就是PR曲线)。
3.P-R曲线图比较模型效果
如图所示:(1)曲线包裹的面积越大,性能越好。(A和B优于C)。
(2)平衡点(P=R的取值)越大,性能越好。
(3)有交叉的曲线性能无法直接判断(A和B),可以通过平衡点判断。
4.PR曲线代码实现
使用鸢尾花数据集
from sklearn.metrics import PrecisionRecallDisplay
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
X, y = load_iris(return_X_y=True)
# Add noisy features
random_state = np.random.RandomState(0)
n_samples, n_features = X.shape
X = np.concatenate([X, random_state.randn(n_samples, 200 * n_features)], axis=1)
# Limit to the two first classes, and split into training and test
X_train, X_test, y_train, y_test = train_test_split(
X[y < 2], y[y < 2], test_size=0.5, random_state=random_state
)
classifier = make_pipeline(StandardScaler(), LinearSVC(random_state=random_state))
classifier.fit(X_train, y_train)
display = PrecisionRecallDisplay.from_estimator(
classifier, X_test, y_test, name="LinearSVC"
)
_ = display.ax_.set_title("2-class Precision-Recall curve")
二、ROC曲线
ROC曲线是以True Positive Rate(真正率)和 False Positive Rate(假正率)这两个为变量而做出的曲线,其中False Positive Rate为横坐标,True Positive Rate为纵坐标。
1、真正率和假正率
公式:
2、ROC曲线图比较模型效果
ROC曲线图中,越靠近(0,1)的点对应的模型分类性能越好。
接近对角线时,说明模型的预测结果为随机预测结果。
如图所示:(1)当一个曲线被另一个曲线完全包含了,则后者性能优于前者。
(2)ROC曲线下方的面积(AUC)越大,分类效果越好。
(3)当两个模型的ROC曲线发生交叉,难以判断哪一个模型更好,可以用AUC来做判断。
3、AUC相等情况
特别注意:当不同模型的ROC曲线的AUC相等时,需要具体问题具体分析。
当需要高Sensitivity值时,A模型好过B;当需要高Specificity值时,B模型好过A。
4、代码
使用鸢尾花数据集
import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle
from sklearn import svm, datasets
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import label_binarize
from sklearn.multiclass import OneVsRestClassifier
from sklearn.metrics import roc_auc_score
# Import some data to play with
iris = datasets.load_iris()
X = iris.data
y = iris.target
# Binarize the output
y = label_binarize(y, classes=[0, 1, 2])
n_classes = y.shape[1]
# Add noisy features to make the problem harder
random_state = np.random.RandomState(0)
n_samples, n_features = X.shape
X = np.c_[X, random_state.randn(n_samples, 200 * n_features)]
# shuffle and split training and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)
# Learn to predict each class against the other
classifier = OneVsRestClassifier(
svm.SVC(kernel="linear", probability=True, random_state=random_state)
)
y_score = classifier.fit(X_train, y_train).decision_function(X_test)
# Compute ROC curve and ROC area for each class
fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(n_classes):
fpr[i], tpr[i], _ = roc_curve(y_test[:, i], y_score[:, i])
roc_auc[i] = auc(fpr[i], tpr[i])
# Compute micro-average ROC curve and ROC area
fpr["micro"], tpr["micro"], _ = roc_curve(y_test.ravel(), y_score.ravel())
roc_auc["micro"] = auc(fpr["micro"], tpr["micro"])
plt.figure(dpi=100)
lw = 2
plt.plot(
fpr[2],
tpr[2],
color="darkorange",
lw=lw,
label="ROC curve (area = %0.2f)" % roc_auc[2],
)
plt.plot([0, 1], [0, 1], color="navy", lw=lw, linestyle="--")
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel("False Positive Rate")
plt.ylabel("True Positive Rate")
plt.title("Receiver operating characteristic example")
plt.legend(loc="lower right")
plt.show()
三、两种曲线对比
1:pr曲线因为涉及到精确率precision计算,容易受到样本分布的影响。而roc曲线本质上是正样本或者负样本召回率计算,不收样本分布的影响。
2:ROC曲线主要应用于测试集中的样本分布的较为均匀的情况,且当测试集中的正负样本的分布变化的时候,ROC曲线能够保持不变。
3:实际问题中,正负样本数量往往很不均衡,P-R曲线的变化就会非常大,而ROC曲线则能够更加稳定地反映模型本身的好坏。
4:当正负样本比例失调时,ROC曲线变化不大,此时用PR曲线更加能反映出分类器性能的好坏。