分类算法评价
image在之前分类中我们常用MSE MAE等 算法来做分类评价。举个例子,极度偏斜的情况。在1000个人中,有1个是生病的。假设生病为1,没生病为0。那么我们只需要预测所有人都没有生病,那么我们的评估算法会给我们的算法评价为99.99%正确率。这样在现实生活中一定会出现问题。如何解决呢?
上图为混淆矩阵,我们可以换一个角度进行评价,原本是判断预测结果和真实结果是否相同,现在我们这里分成了4个角度,分别如下。假设我们做了10000次预测,预测结果有两种,一种为有病1,一种为没病0。
- TN:我们预测无病,真实无病的人数
- FN:我们预测无病,真实有病的人数
- FP:我们预测有病,真实无病的人数
- TP:我们预测有病,真实有病的人数
精准率 precision
预测正确有病的人在所有预测到有病的人中的概率。换句话说,预测到这么多人中有多少是预测准确的。
召回率 recall
预测正确有病的人在所有有病的人中的概率。换句话说,真实这么多人中,有多少被预测准确了。
scikit-learn
from sklearn.metrics import confusion_matrix
# 获得混淆矩阵
confusion_matrix(y_test, y_log_predict)
from sklearn.metrics import precision_score
# 计算精准度
precision_score(y_test, y_log_predict)
from sklearn.metrics import recall_score
# 计算召回率
recall_score(y_test, y_log_predict)
精准率和召回率哪个重要呢?
根据具体情况而定,例如股票预测中,当我们预测股票为涨,结果却跌了,那么就是精准率不高,容易亏钱。所以这个情况应该是要精准率高一些。而在医疗诊断系统中。如果一个病人被诊断为没病,那么病人病情就会恶化下去,后果会非常严重,所以召回率比较重要。
F1 Score
兼顾了精准率和召回率,是精准率和召回率的调和平均值。
调和平均值算法,优势,当两者同时高时,最终得分才会高。否则仅仅一端高时结果也是低的
image
变形
imagefrom sklearn.metrics import f1_score
f1_score(y_test, y_predict)
精准率和召回率曲线
阈值
image在逻辑回归中,当结果分为是和否的时候。我们把计算出来的值如果大于0则为是,小于0则为否。0这个值就是阈值,当我们调整阈值时,就会造成不同的精准率和召回率,阈值越高,精准率越高,召回率越低。阈值越低则相反。
精准率:蓝色曲线
召回率:黄色曲线
X:阈值
Y:精准率和召回率各自的值
精准率-召回率 曲线
imageX:精准率
Y:召回率
scikit-learn
from sklearn.metrics import precision_recall_curve
#precisions精准率,recalls召回率,thresholds阈值向量
precisions, recalls, thresholds = precision_recall_curve(y_test, decision_scores)#y_test真实标签,decision_scores分类的评分
plt.plot(thresholds, precisions[:-1])#精准率曲线,[:-1]因为thresholds比precisions个数少1
plt.plot(thresholds, recalls[:-1])#召回率曲线
plt.show()
plt.plot(precisions, recalls)#精准率-召回率曲线
plt.show()
ROC曲线
image-
FPR
所有真实值为0,预测为1的概率
-
TPR
所有真实值为1中,预测为1的概率
image如上图,不难看出当阈值越低时,TPR和FPR同时在增大,否则反之
X:FPR
Y:TPR
image当FPR越小时,TPR越高则说明分类算法越好。所以衡量一个模型分类的效果就是看这条曲线包住的块的面积的大小, 越大则效果越好
scikit-learn
from sklearn.metrics import roc_curve
fprs, tprs, thresholds = roc_curve(y_test, decision_scores)
plt.plot(fprs, tprs)
plt.show()
from sklearn.metrics import roc_auc_score
roc_auc_score(y_test, decision_scores)#求面积
多分类问题中的混淆矩阵
手写数字为例
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn import datasets
from sklearn.metrics import precision_score
digits = datasets.load_digits()
X = digits.data
y = digits.target
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.8, random_state=666)
log_reg = LogisticRegression()
log_reg.fit(X_train, y_train)
log_reg.score(X_test, y_test)
y_predict = log_reg.predict(X_test)
# 计算精准率
precision_score(y_test, y_predict, average="micro")# average="micro"选择多分类的算法来计算精准率
from sklearn.metrics import confusion_matrix
# 混淆矩阵
cfm = confusion_matrix(y_test, y_predict)
# 看正确的分类混淆矩阵图
plt.matshow(cfm, cmap=plt.cm.gray)# 使用灰度图来展示混淆矩阵,越白为越正确
plt.show()
# 看错误的分类混淆矩阵图(我们主要目的是分析错误的情况,看错误的比较常用)
row_sums = np.sum(cfm, axis=1)# 将混淆举证按列相加(求得各分类总样本数)
err_matrix = cfm / row_sums # 获取个元素的比重
np.fill_diagonal(err_matrix, 0)# 将对角线设为0,对角线为预测和实际相同的情况
plt.matshow(err_matrix, cmap=plt.cm.gray)# 按照比重绘制,比重越大越白
plt.show()
网友评论