准确率顾名思义就是分类器正确分类的样本数占总体数的比例,虽然准确率可以衡量分类器的整体正确性,但是当类别在总样本中呈偏态分布是,准确率就不是一个很有效的衡量指标,例如信用卡欺诈检测,大多数是合法交易,所以分类器的分类准确率会达到99%以上,但是这不能说明模型就一定是好的,所以分类器会经常使用精准率和召回率来进行衡量。
在分类时,会出现四种情况,如表所示
分类 | 预测结果为正 | 预测结果为负 |
---|---|---|
实际结果为+1 | 真正例 or 真阳性(TP) | 伪反例 or 假阴性(FN) |
实际结果为-1 | 伪正例 or 假阳性(FP) | 真反例 or 真阴性(TN) |
精准率就是预测为真例的样本中真正正例的比例,计算公式为TP/(TP+FP)
召回率是预测为真例的占被总体正例的样本的比例,计算公式为TP/(TP+FN)
错检率就是预测为真例的反例占总体反例的比例,的计算公式为FP/(FP+TN)
这其中需要注意名称变化:
真阳性率TPR = 召回率
假阳性率FPR = 错检率
如果召回率为1,则证明FN为0,也就是分类器没有做出伪反例的预测
F1值是精准率和召回率的调和平均值,计算公式为 2*(精确率*召回率)/(精确率+召回率),数值越大,模型越好
F1值会对精准率和召回率不平衡的分类器进行惩罚,例如总是预测为正例的分类器,达到完美精准率和召回率的模型F1值为1,而达到完美精准率,而召回率为0的模型F1得分为0。
由F1衍生出还有F0.5以及F2两种得分,其中F0.5偏向于精准率,F2偏向于召回率,
受试者操作特征(ROC)曲线,是通过对一个分类器的性能进行可视化,ROC曲线对类别分布不均匀的数据集不敏感,这点与准确率不同,其计算公式为 FP/(TN+FP),也就是伪正例数量占真实为反例的比例,
AUC则是ROC曲线以下的部分面积,如图所示,虚线是占整个格子一半,它表示一个分类器对类随机进行预测,它的AUC值为0.5,而曲线下就是实际的AUC值,这个图形的AUC值在0.9以上,是一个很好的分类器模型
下面实际操作,看看各个指标在sklearn中要如何实现:
这次使用皮马糖尿病数据集,这是一个二分类问题,首先导入所需的包和数据集
from sklearn.svm import SVC
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split,cross_val_score
from sklearn.metrics import precision_score,recall_score,roc_auc_score,roc_curve,auc
import warnings
warnings.filterwarnings('ignore')
data = pd.read_csv(r'C:\Users\11060\Desktop\pima-indians-diabetes.csv')
划分数据集,训练集,并选出特征还有类别,对数据进行特征化处理
X = data.iloc[:,0:8].values
y = data.iloc[:,8].values
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.33,stratify=y,random_state=1)
model = SVC(kernel='rbf',C=1,gamma=0.01)
ss = StandardScaler()
X_train_scalaed = ss.fit_transform(X_train)
X_test_scalaed = ss.transform(X_test)
model.fit(X_train_scalaed,y_train)
y_predict = model.predict(X_test_scalaed)
这里使用SVM做分类,模型拟合并输出不同的指标分数
model.fit(X_train_scalaed,y_train)
y_predict = model.predict(X_test_scalaed)
accuracy_score = cross_val_score(model,X_train_scalaed,y_train,cv=5)
print('准确率为',np.mean(accuracy_score))
precision_score = cross_val_score(model,X_train_scalaed,y_train,cv=5,scoring='precision')
print('精准率为',np.mean(precision_score))
recall_score = cross_val_score(model,X_train_scalaed,y_train,cv=5,scoring='recall')
print('召回率为',np.mean(recall_score))
f1_score = cross_val_score(model,X_train_scalaed,y_train,cv=5,scoring='f1')
print('F1值为',np.mean(f1_score))
fpr,tpr,thresholds = roc_curve(y_test,y_predict)
roc_auc = auc(fpr,tpr)
print('ROC值为',roc_auc)
# output
准确率为 0.7763182943080145
精准率为 0.7401693404634582
召回率为 0.5642857142857143
F1值为 0.6356493181980437
ROC值为 0.7129724208375893
我们将ROC曲线画出来
plt.figure(figsize=(8,6))
plt.plot(fpr,tpr,'b',label='AUC=%0.2f'%roc_auc)
plt.rcParams['font.sans-serif']=['SimHei']
plt.legend(loc='lower right')
plt.xlim([0,1])
plt.ylim([0,1])
plt.ylabel('tpr召回率')
plt.xlabel('fpr错检率')
plt.plot([0,1],[0,1],'r--')
plt.show()