最近做實驗要用到性能度量的東西,之前學習過現在重新學習并且實作一下。
衡量模型泛化能力的評價标準,這就是性能度量。性能度量反應了任務需求,在對比不同模型的能力時,使用不同的性能度量往往會導緻不同的評判結果;什麼樣的模型是好的,不僅取決于算法和資料,還決定于任務需求。
一、性能度量方法
1.1錯誤率與精度
錯誤率是分類錯誤的樣本數占樣本總數的比例,精度是分類正确的樣本數占樣本總數的比例。
1.2查準率(precision)、查全率(recall)與F1
對于二分類問題,将樣例根據其真實類别與預測類别的組合劃分為真正例(true positive,TP)、假正例(false positive,FP)、真反例(true negative,TN)、假反例(false negative,FN)。有 (為樣本總數)。分類結果的混肴矩陣:

查準率P與查全率R分别定義為:
算法對樣本進行分類時,都會有置信度,即表示該樣本是正樣本的機率,比如99%的機率認為樣本A是正例,1%的機率認為樣本B是正例。通過選擇合适的門檻值,比如50%,對樣本進行劃分,機率大于50%的就認為是正例,小于50%的就是負例。
通過置信度就可以對所有樣本進行排序,再逐個樣本的選擇門檻值,在該樣本之前的都屬于正例,該樣本之後的都屬于負例。每一個樣本作為劃分門檻值時,都可以計算對應的precision和recall,那麼就可以以此繪制曲線。那很多書上、部落格上給出的P-R曲線,都長這樣。
平衡點(break-even point,BEP)是查準率=查全率時的取值。基于它可以判斷學習器的優劣。
但是BEP還是過于簡化,更常用的是F1度量:
F1度量的一般形式F3,能讓我們表達出對查準率/查全率的不同偏好,定義為:
其中β>0度量了查全率對查準率的相對重要性。β=1時退化為标準的F1;β>1時查全率有更大的影響;β<1時查準率有更大的影響。
有時候我們有多個二分類混淆矩陣,例如進行多次訓練測試;或是在多個資料集上訓練測試等,我們希望在n個二分類混淆矩陣上總和考察查準率和查全率。是以有宏F1和微F1。
F1是基于查準率與查全率的調和平均定義的
。
Fβ則是權重調和平均:
。
與算術平均(
)和幾何平均(
)相比,調和平均更重視較小值。
1.3ROC與AUC
ROC全稱受試者工作特征(Receiver Operating Characteristic)曲線,ROC曲線的縱軸是真正例率(True Positive Rate,TPR),橫軸是假正例率(False Positive Rate,FPR),定義:
AUC(Area Under ROC Curve) :為ROC曲線下的面積和,通過它來判斷學習器的性能。AUC考慮的是樣本預測的排序品質。
給定個正例和個反例,令和分别表示正反例集合,定義排序損失
:
即考慮一對正反例,若正例預測值小于反例,記一個罰分,若相等,記0.5個罰分。容易看出對應的是ROC曲線之上的面積。是以有:
二、python實作
圖均為上節中引用的圖檔,在此不重複引用。
2.1P-R
from sklearn import svm, datasets
from sklearn.model_selection import train_test_split
import numpy as np
iris = datasets.load_iris()
X = iris.data
y = iris.target
# Add noisy features
random_state = np.random.RandomState(0)
n_samples, n_features = X.shape
X = np.c_[X, random_state.randn(n_samples, 200 * n_features)]
# 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=.5,
random_state=random_state)
# Create a simple classifier
classifier = svm.LinearSVC(random_state=random_state)
classifier.fit(X_train, y_train)
y_score = classifier.decision_function(X_test)
from sklearn.metrics import precision_recall_curve
import matplotlib.pyplot as plt
precision, recall, _ = precision_recall_curve(y_test, y_score)
plt.step(recall, precision, color='b', alpha=0.2,
where='post')
plt.fill_between(recall, precision, step='post', alpha=0.2,
color='b')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.ylim([0.0, 1.05])
plt.xlim([0.0, 1.0])
plt.title('2-class Precision-Recall curve: AP={0:0.2f}'.format(
average_precision))
2.2ROC
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 scipy import interp
# 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=.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()
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()
作者:Rookiekk
轉載:https://blog.csdn.net/qq_18888869/article/details/84848689