ML(6) -Evaluate模型评估方法


线性回归算法评估方式


  • MSE/RMSE/MAE/R Squared

  1. 均方误差MSE(mean squared error): m s e = ∑ i = 1 m ( y ^ i − y i ) 2 m mse = \frac{\sum_{i=1}^m(\hat y_{i} - y_{i})^2}{m} mse=mi=1m(y^iyi)2
    (mse的标量是真实标量的平方,线性回归损失函数也用此公式)

  2. 均方根误差RMSE(root mean squared error): r m s e = ∑ i = 1 m ( y ^ i − y i ) m rmse = \sqrt \frac{\sum_{i=1}^m(\hat y_{i} - y_{i})}{m} rmse=mi=1m(y^iyi)
    (预测值与真实值误差为 ± r m s e \pm rmse ±rmse

  3. 均方绝对误差MAE(mean absolute error): m a e = ∑ i = 1 m ∣ y ^ i − y i ∣ m mae = \frac{\sum_{i=1}^m|\hat y_{i} - y_{i}|}{m} mae=mi=1my^iyi
    (预测值与真实值误差为 ± m a e \pm mae ±mae

  4. R Squared:
    在这里插入图片描述

  • 公式中:分式---->分子即为模型预测产生误差用MSE计算,分母为模型的基准误差(方差也就是最大误差)。预测产生的误差与最大误差的比。
  • 因为1减去分式,所以 R 2 &lt; = 1 R^2&lt;=1 R2<=1, R 2 R^2 R2越大越好,为1时表示分式为0,我们模型不犯任何错误。为0时表示预测误差等于基准误差。<0时表示还不如基准模型,很可能我们的数据不存在任何线性关系。
  • scikit-learn线性回归方法中score计算准确率,封装评估方式就是 R 2 R^2 R2

  • scikit-learn中的MSE/MAE/R Squared

from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import r2_score

mean_squared_error(y_test, y_predict)
mean_absolute_error(y_test, y_predict)
r2_score(y_test,y_predict)


分类算法评估方式

  • 准确率(accuracy)

    1. 公式: a c c u r a c y = 分 类 正 确 样 本 数 / 样 本 总 数 accuracy = 分类正确样本数 / 样本总数 accuracy=/
    2. 是最基本的评估方式,但是对于分布极度偏斜的数据,只是用准确度评估是不够的,就会出现问题。
      eg:有100人,其中90个健康,10个患病。假设100人经过模型预测,全部认定为健康。模型一个患病的都没有预测成功,但是模型准确率却有90%,因此将需要有更多的评估方式来评估模型的性能好坏。
  • 混淆矩阵

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    1. 最左边一列代表真实值,最上面一行代表预测值。
    2. 矩阵中按顺序:TN---->预测为0类且真值也为0类的样本。FP---->预测为1类但真值也为0类的样本。
      FN---->预测为0类但真值为1类的样本。TP---->预测为1类且真值也为1类的样本。
    3. 样本总数 = TN+FN+FP+TP
    4. 通常将1类别作为我们真正关注的对象,eg:医疗中判断是否患病1类作为患病类,金融中判断是否有风险1类作为风险类。

    查准率(precision)

    1. 模型判定为1类的样本中,正确的数量。
    2. p r e c i s i o n = T P F P + T P precision = \frac{TP}{FP+TP} precision=FP+TPTP

    查全率(recall)

    1. 真实为1类的样本中,模型判定对的数量。
    2. r e c a l l = T P F N + T P recall = \frac{TP}{FN+TP} recall=FN+TPTP

    F1 Score

    1. 有时候我们注重查准率,例如预测股票是升还是跌,查全率就显得不那么总要,我们不需要查出所有升的股票,我们只要保证我们预测出的升的股票准确率是高的。

    2. 有时候我们注重查全率,例如医疗领域,最好的就是把所有有病的患者都查出来,相对对于准确率的要求就没有那么高,就算没病判断成有病可再进一步检查,确诊。

    3. 当然有些情况下,不是完全偏向于某一方,是希望查全率和查准率均衡,兼顾二者。新的衡量标准 F1 Score:
      使用了查全率和查准率的调和平均值:

      1 F 1 = 1 2 ( 1 p r e c i s i o n + 1 r e c a l l l ) \frac{1}{F1} = \frac{1}{2}(\frac{1}{precision}+\frac{1}{recalll}) F11=21(precision1+recalll1)

      F 1 = 2 ⋅ p r e c i s i o n ⋅ r e c a l l l p r e c i s i o n + r e c a l l F1 = \frac{2\cdot precision\cdot recalll}{precision+recall} F1=precision+recall2precisionrecalll

      F1的范围[ 0 , 1 ]。只有在二者同时很高的情况下,F1的值才会很高,任何一方值是低的都会拉低F1评估值。

    scikit-learn中的API

#混淆矩阵
from sklearn.metrics import confusion_matrix
confusion_matrix(y_test, y_predict)
#查准率(percision)
from sklearn.metrics import precision_score
precision_score(y_test, y_predict,average=‘binary’)
#查全率(recall)
from sklearn.metrics import recall_score
recall_score(y_test, y_predict, average=‘binary’)
#F1 Score
from sklearn.metrics import f1_score
f1_score(y_test, y_predict)

'''
其中precision_score和recall_score有参数average,默认binary适用于二分类。
当为多分类任务需调整,主要有'macro'和'weigthed'。
以precision_score为例:'macro':不考虑各类别的样本数量,结果为:各类别p的均值。
'weigthed':考虑各类别的样本数量,结果为:各类别p乘各类别样本数量,求和,再除总样本数 。
若测试的各类别样本数量明显不均衡应采用weigthed。
'''

画混淆矩阵

from sklearn.metrics import confusion_matrix
import seaborn as sn
#多分类(3类)
cfm = confusion_matrix(y_test, y_predict)
>>> array(预测   0    1	   2
	  真实 0  [[147,   6,   0],
     	   1   [  7, 123,   0],
    	   2   [  1,   0, 134]])

#每行样本数
row_sums = np.sum(cfm, axis=1)
#新矩阵:每格占样本数的比
err_matrix = cfm / row_sums
#将新矩阵对角线都填成0,因为我们不关心正确的个数,剩下的每个格子都是预测错误的占比。
np.fill_diagonal(err_matrix, 0)
ax1 = sn.heatmap(err_matrix, annot= True ,linewidths = 0.05, xticklabels=['put on',"take off","scratch"],
yticklabels=['put on',"take off","scratch"])
ax1.set_title("Confusion Matrix")
ax1.set_ylabel("True label")
ax1.set_xlabel("Predict label")

在这里插入图片描述

  • 查全率和查准率的平衡(PR曲线)

  1. 查全率和查准率是互斥的,通常一个升高另一个便会下降,有时候我们需要查全率高,有时候我们又需要查准率高。
  2. 接下来要讨论的是一个很厉害的东西,通过决策边界(Threshold)来调整一个训练好的模型的查全率和查准率。
  3. 那什么是决策边界(Threshold)呢?以LogisticRegression为例:
      LogisticRegression是对线性回归模型计算的结果( y = X b ⋅ θ y = X_{b}\cdot \theta y=Xbθ),再用一个函数(sigmoid)进行转化得到[0,1]间的概率,定义以概率0.5为分界线,大于0.5归为1类,小于0.5的归为0类。根据sigmoid函数的性质,概率为0.5时, X b ⋅ θ X_{b}\cdot \theta Xbθ值是为0,所以也就变成 X b ⋅ θ &gt; 0 X_{b}\cdot \theta&gt;0 Xbθ>0 时归为1类, X b ⋅ θ &lt; 0 X_{b}\cdot \theta&lt;0 Xbθ<0 时归为0类。不清楚LogisticRegression算法的可以看我另一篇博客:[LogisticRegression详解]
      因此, X b ⋅ θ = 0 X_{b}\cdot \theta = 0 Xbθ=0 就称为决策边界,0即可替换为任意值的Threshold,当 X b ⋅ θ &gt; T h r e s h o l d X_{b}\cdot \theta &gt; Threshold Xbθ>Threshold 时分为1类,当 X b ⋅ θ &lt; T h r e s h o l d X_{b}\cdot \theta &lt; Threshold Xbθ<Threshold 时分为0类。
  4. 举个例子:
    一共有12个样本,五角星代表我们关注的对象为1类。
    当Threshold = 0 ,右边为大于0的部分分为1类, p r e c i s i o n = 0.8 , r e c a l l = 0.67 precision = 0.8, recall = 0.67 precision=0.8,recall=0.67
    在这里插入图片描述
    当Threshold = 2 ,右边为大于2的部分分为1类, p r e c i s i o n = 1.0 , r e c a l l = 0.33 precision = 1.0, recall = 0.33 precision=1.0,recall=0.33
    在这里插入图片描述
    当Threshold = -3 ,右边为大于-3的部分分为1类, p r e c i s i o n = 0.75 , r e c a l l = 1.0 precision = 0.75, recall = 1.0 precision=0.75,recall=1.0
    在这里插入图片描述
  5. 那应该如何修改Threshold调整预测结果呢?请看下面。
    首先要明确一点,是对已经训练好的模型,在predict时调整决策边界(threshold),改变预测分类结果。
    在scikit-learn中LogsticRegression默认的predict就是以 X b ⋅ θ = 0 X_{b}\cdot \theta = 0 Xbθ=0 为分界线,即sigmoid( X b ⋅ θ ) X_{b}\cdot \theta) Xbθ)大于0.5 为1,小于0.5为0。
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score

log_reg = LogisticRegression()
log_reg.fit(X_train, y_train)
#默认predict,threshold为0的预测结果
y_predict = log_reg.predict(X_test)
precision_score(y_test, y_predict)
>>> 0.9473549684225426
recall_score(y_test, y_predict)
>>> 0.8000000000000004

'''调整threshold的方式'''
#1.通过API:decision_function,获得未经过sigmoid函数的预测值,即 Xb⋅ θ 的值。
decision_scores = log_reg.decision_function(X_test)
>>> [-22.0315,-33.1241,-0.9412,4.1312,15.2345,......]
#2.不使用sigmoid,通过直接给Threshold值来生成预测结果。decision_scores中大于-5的分为1类,小于-5的分为0类。
y_predict_2 = np.array(decision_scores >= -5, dtype='int')
#3.看查全率和查准率的变化
precision_score(y_test, y_predict_2)
>>> 0.72727272727272729
recall_score(y_test, y_predict_2)
>>> 0.88888888888888884

  1. 那该如何决定最佳的threshold呢?PR曲线诞生。
'''scikit-learn 中的precision_recall_curve
   输入参数:测试集真值(y_test)和未经过sigmoid函数的预测值(由API:decision_function获取)
   返回值:查准率数组,记录了每一个threshold对应的precision,数组最后一个值是1,且没有对应的threshold。
   		  查全率数组,记录了每一个threshold对应的recall,数组最后一个值是0,且没有对应的threshold。
   		  threshold数组,记录了每一个threshold,这些threshold是skl自动规划间距得出有意义的threshold。
		  (自己手动选取阀值,通常取决策分数的最小和最大值,间隔0.1取阀值threshold。)
   		  threshold数组是比查准率数组和查全率数组少一个元素的。
'''
from sklearn.metrics import precision_recall_curve
precisions,recalls,thresholds = precision_recall_curve(y_test, decision_scores)

# 横坐标为threshold,纵坐标为对应的precison(蓝色)和recall(橘色)
# 因为precision数组和recall数组最后一个元素是没有对应的threshold,因此去掉。
plt.plot(thresholds, precisions[:-1])
plt.plot(thresholds, recalls[:-1])
plt.show()

交汇处即为查准率和查全率最平衡的threshold。
在这里插入图片描述

# PR曲线
plt.plot(precisions, recalls)
plt.show()

拐点处即为查准率和查全率最平衡的threshold。
在这里插入图片描述
  7.PR曲线除了可以用来权衡查全率和查准率,还可用于评价不同模型之间的性能。
在这里插入图片描述
   通常一条PR曲线能够包住另一条曲线,表示此曲线效能优于另一条曲线。


ROC曲线及其面积AUC

  • Receiver Operation Characteristic Curve 描述TPR和FPR之间的关系。

  • TPR = 查全率,预测1且对了的占真实1的多少。
    在这里插入图片描述

  • FPR,预测1且错了的占真实0的多少。
    在这里插入图片描述

  • TPR和FPR关系:
    在这里插入图片描述
    TPR升高时,FPR也同时升高。

  • scikit-learn中的ROC

'同precision_recall_curve使用方式一致'
from sklearn.metrics import roc_curve
fprs, tprs, thresholds = roc_curve(y_test, decision_scores)
plt.plot(fprs, tprs)
plt.show()

'''计算ROC曲线下方的面积AUC'''
from sklearn.metrics import roc_auc_score
roc_auc_score(y_test, decision_scores)

在这里插入图片描述

  • ROC通常用来比较两个模型孰优孰劣,ROC 曲线下,面积更大的模型,效能更好。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值