二分类问题常用的评估指标是精度(precision),召回率(recall),F1值(F1-score)
通常以关注的类为正类positive,其他类为负类negative,分类器在测试数据上预测正确或不正确,结合正负类,4种情况出现的可能为:
将正类预测为正类(true positive)——用tp表示
将正类预测为负类(false negative)——用fn表示
将负类预测为正类(false positive)——用fp表示
将负类预测为负类(true negative)——用tn表示
用诊断病人是否有病,“有病”是被关注的正类,“没病”是不关注的负类。
精度可以看作是预测数据的正确率(预测100个数据正确,其中有多少个是真的正确,这个值越高说明模型精度比较好),召回率可以看作是预测数据的实用性(预测的100个正确数据中真的正确占原本正确数据的百分比,这个值越高模型的价值越大。)有的模型预测精度很高,比如说预测出来的值都正确,但还有很多正确数据没预测出来,就可以说这个模型的价值不高。有的模型召回率很高,即所有正确的数据它全覆盖到了,但有点过拟合,存在错误数据也预测成了正确的,所以F1值就是一个对p和r的加权均值。一般来说,精度、召回率、F1值能很好地评估一个模型是否合适,F1值越高,模型越合适。
举个例子:
用经典的病人诊断例子:
则精度P为55.6%,召回率R为83.3%,F1值就不再算了。
当精度P和召回率R都很高的时候,F1值也会较高。
用代码演示:假设有10个病人问诊,7个是真有病,3个只是心理作用,诊断就是分类器(模型),1代表确有病,0代表没有病。
import numpy as np
from sklearn.metrics import precision_score,recall_score,f1_score
from sklearn.tree import DecisionTreeClassifier
y_true=np.array([1,0,1,0,1,0,1,1,1,1])
y_pred=np.array([1,1,1,1,1,0,1,1,1,1])
p = precision_score(y_true, y_pred)
r = recall_score(y_true, y_pred)
f1 = f1_score(y_true, y_pred)
print('jingdu:',p)
print('zhaohui:',r)
print('f1:',f1)
结果为:
jingdu: 0.7777777777777778
zhaohui: 1.0
f1: 0.8750000000000001
accrucy_score分类准确率分数指的是分类正确的百分比。
accrucy_score(y_true,y_hat,normalize=True,sample_weight=None),其中normalize默认为True,这时候算出的分类正确的百分比,如果改为False,则算出分类正确的样本数。
import numpy as np
from sklearn.metrics import accuracy_score
y_true=[1,2,3,4]
y_hat=[1,6,3,8]
print(accuracy_score(y_true,y_hat))
print(accuracy_score(y_true,y_hat,normalize=False))
自己试一下更有体会。
最后附一段体会的代码:
import numpy as np
from sklearn.metrics import accuracy_score
#sklearn中的评估方法,指分类正确的百分比,返回的是一个百分比
from sklearn.metrics import precision_score, recall_score, f1_score, fbeta_score
#metrics用来评估预测误差,上式分别是精度、召回率和f1值,f_beta值
from sklearn.metrics import precision_recall_fscore_support
if __name__ == "__main__":
y_true = np.array([1, 1, 1, 1, 0, 0,1,1])
y_hat = np.array([1, 0, 1, 1, 1, 1,1,1])
print ('Accuracy:\t', accuracy_score(y_true, y_hat))
precision = precision_score(y_true, y_hat)
print ('Precision:\t', precision)
recall = recall_score(y_true, y_hat)
print ('Recall: \t', recall)
print ('f1 score: \t', f1_score(y_true, y_hat))
print ('F-beta:')
for beta in np.logspace(-3, 3, num=7, base=10):
#np.logspace是创建等比数列,-3和3表示10的-3次方和3次方,7代表7个数,base比值;
fbeta = fbeta_score(y_true, y_hat, beta=beta)
print ('\tbeta=%9.3f\tF-beta=%.5f' % (beta, fbeta))
#print (1+beta**2)*precision*recall / (beta**2 * precision + recall)
print (precision_recall_fscore_support(y_true, y_hat, beta=1))