对于分类问题,我们可能会使用k近邻算法、决策树、逻辑回归、朴素贝叶斯法、支持向量机、随机森林;对于回归问题,我们可能会使用线性回归、决策树、随机森林。在工业上,我们不可能会对客户说,这是我训练的几个模型,你想用哪个我就给你哪个。一般而言这是不可能的,通常对于这几个模型,我们会通过某种度量模型的工具,选择一个最优的模型推给客户。
在训练模型那一章节,对于每个模型我们都使用了模型自带的score()方法对模型的性能进行了一个度量,但是score()方法对于分类模型,只是简单的度量了模型的性能;对于回归模型,score()方法只是计算了R2报告分数。这样的度量是很片面的,通常我们会使用sklearn.metics和sklearn.model_selection库下的模块对度量模型性能。
模块提供了各种评估指标,并且用户可以自定义评估指标,对于metrics评估指标,主要分为以下两种类型:
| * 以_score结尾的为模型得分,一般情况越大越好 |
| * 以_error或_loss结尾的为模型的偏差,一般情况越小越好 |
接下来我们将通过分类模型、回归模型来详细讲解metrics评估指标。
| import numpy as np |
| import pandas as pd |
| import matplotlib.pyplot as plt |
| from matplotlib.font_manager import FontProperties |
| from sklearn import datasets |
| %matplotlib inline |
| font = FontProperties(fname='/Library/Fonts/Heiti.ttc') |
| /Applications/anaconda3/lib/python3.7/importlib/_bootstrap.py:219: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88 |
| return f(*args, **kwds) |
| /Applications/anaconda3/lib/python3.7/importlib/_bootstrap.py:219: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88 |
| return f(*args, **kwds) |
回归模型常用的metrics评估指标有:r2_score、explained_variance_score等
| * explained_variance_score(y_true, y_pred, sample_weight=None, multioutput='uniform_average'):回归方差(反应自变量与因变量之间的相关程度) |
| * mean_absolute_error(y_true, y_pred, sample_weight=None, multioutput='uniform_average'):平均绝对值误差 |
| * mean_squared_error(y_true, y_pred, sample_weight=None, multioutput='uniform_average'):均方差 |
| * median_absolute_error(y_true, y_pred):中值绝对误差 |
| * r2_score(y_true, y_pred, sample_weight=None, multioutput='uniform_average'):R平方值 |
r2score即报告决定系数$(R^2)$,可以理解成MSE的标准版,$R^2$的公式为
$$
R^2 = 1-{\frac {{\frac{1}{n}\sum{i=1}^n(y^{(i)}-\hat{y^{(i)}})^2}} {{\frac{1}{n}}\sum{i=1}^n(y^{(i)}-\mu{(y)})^2} }
$$
其中$\mu{(y)}$是$y$的平均值,即${{\frac{1}{n}}\sum{i=1}^n(y^{(i)}-\mu_{(y)})^2}$为$y$的方差,公式可以写成
$$
R^2 = 1-{\frac{MSE}{Var(y)}}
$$
$R^2$的取值范围在$0-1$之间,如果$R^2=1$,则均方误差$MSE=0$,即模型完美的拟合数据。
| |
| from sklearn.linear_model import LinearRegression |
| from sklearn.metrics import r2_score |
| |
| boston = datasets.load_boston() |
| X = boston.data |
| y = boston.target |
| |
| lr = LinearRegression() |
| lr.fit(X, y) |
| lr_predict = lr.predict(X) |
| |
| lr_r2 = r2_score(y, lr_predict) |
| print('报告决定系数:{:.2f}'.format(lr_r2)) |
| |
| from sklearn.linear_model import LinearRegression |
| from sklearn.metrics import explained_variance_score |
| |
| boston = datasets.load_boston() |
| X = boston.data |
| y = boston.target |
| |
| lr = LinearRegression() |
| lr.fit(X, y) |
| lr_predict = lr.predict(X) |
| |
| ex_var = explained_variance_score(y, lr_predict) |
| print('解释方差:{:.2f}'.format(ex_var)) |
回归模型常用的metrics评估指标有:accuracy_socre、precision_score、recall_score、f1_score等
| * accuracy_score(y_true,y_pre): 精度 |
| * auc(x, y, reorder=False): ROC曲线下的面积;较大的AUC代表了较好的performance。 |
| * average_precision_score(y_true, y_score, average='macro', sample_weight=None):根据预测得分计算平均精度(AP) |
| * brier_score_loss(y_true, y_prob, sample_weight=None, pos_label=None):越小的brier_score,模型效果越好 |
| * confusion_matrix(y_true, y_pred, labels=None, sample_weight=None):通过计算混淆矩阵来评估分类的准确性 返回混淆矩阵 |
| * f1_score(y_true, y_pred, labels=None, pos_label=1, average='binary', sample_weight=None): F1值 |
| * log_loss(y_true, y_pred, eps=1e-15, normalize=True, sample_weight=None, labels=None):对数损耗,又称逻辑损耗或交叉熵损耗 |
| * precision_score(y_true, y_pred, labels=None, pos_label=1, average='binary',):查准率或者精度; precision(查准率)=TP/(TP+FP) |
| * recall_score(y_true, y_pred, labels=None, pos_label=1, average='binary', sample_weight=None):查全率 ;recall(查全率)=TP/(TP+FN) |
| * roc_auc_score(y_true, y_score, average='macro', sample_weight=None):计算ROC曲线下的面积就是AUC的值,the larger the better |
| * roc_curve(y_true, y_score, pos_label=None, sample_weight=None, drop_intermediate=True);计算ROC曲线的横纵坐标值,TPR,FPR |
二分类问题中根据样例的真实类别和模型预测类别的组合划分为真正例(true positive)、假正例(false positive)、真反例(true negative)、假反例(false negative)四种情形,令TP、FP、TN、FN分别表示对应的样例数,$样例总数 = TP+FP+TN+FN$。
- TP——将正类预测为正类数
- FP——将负类预测为正类数
- TN——将负类预测为负类数
- FN——将正类预测为负类数
误差矩阵 |
– |
– |
– |
– |
– |
真实值 |
真实值 |
– |
– |
1 |
0 |
预测值 |
1 |
True Positive(TP) |
False Positive(FP) |
预测值 |
0 |
True Negative(TN) |
False Negative(FN) |
准确度(accuracy_socre)定义为
$$
P = {\frac{TP+FN}{TP+FP+TN+FN}} = \frac{正确预测的样本数}{样本总数}
$$
| |
| from sklearn import datasets |
| from sklearn.metrics import accuracy_score |
| from sklearn.linear_model import LogisticRegression |
| |
| iris_data = datasets.load_iris() |
| X = iris_data.data |
| y = iris_data.target |
| |
| lr = LogisticRegression(solver='lbfgs', multi_class='auto', max_iter=200) |
| lr = lr.fit(X, y) |
| |
| y_pred = lr.predict(X) |
| print('准确度:{:.2f}'.format( |
| accuracy_score(y, y_pred))) |
查准率(precision_score)定义为
$$
P = {\frac{TP}{TP+FP}} = \frac{正确预测为正类的样本数}{预测为正类的样本总数}
$$
| |
| from sklearn import datasets |
| from sklearn.metrics import precision_score |
| from sklearn.linear_model import LogisticRegression |
| |
| iris_data = datasets.load_iris() |
| X = iris_data.data |
| y = iris_data.target |
| |
| lr = LogisticRegression(solver='lbfgs', multi_class='auto', max_iter=200) |
| lr = lr.fit(X, y) |
| |
| y_pred = lr.predict(X) |
| print('查准率:{:.2f}'.format( |
| precision_score(y, y_pred, average='weighted'))) |
查全率(recall_score等)定义为
$$
R = {\frac{TP}{TP+FN}} = \frac{正确预测为正类的样本数}{正类总样本数}
$$
| |
| from sklearn.metrics import recall_score |
| from sklearn import datasets |
| from sklearn.linear_model import LogisticRegression |
| |
| iris_data = datasets.load_iris() |
| X = iris_data.data |
| y = iris_data.target |
| |
| lr = LogisticRegression(solver='lbfgs', multi_class='auto', max_iter=200) |
| lr = lr.fit(X, y) |
| |
| y_pred = lr.predict(X) |
| print('查全率:{:.2f}'.format(recall_score(y, y_pred, average='weighted'))) |
通常情况下通过查准率和查全率度量模型的好坏,但是查准率和查全率是一对矛盾的度量工具,查准率高的时候查全率低;查全率高的时候查准率低,因此工业上对不不同的问题对查准率和查全率的侧重点会有所不同。
例如癌症的预测中,正类是健康,反类是患有癌症。较高的查准率可能会导致健康的人被告知患有癌症;较高的查全率可能会导致患有癌症的患者会被告知健康。
$F_1$值(f1_score等)定义为
$$
F_1 = {\frac{2PR}{P+R}} = {\frac{2TP}{2TP+FP+FN}} = {\frac{2TP}{样例总数+TP-TN}}
$$
$F\beta$定义为:
$$
F\beta = {\frac{(1+\beta^2)PR}{\beta^2*P+R}}
$$
$F_\beta$是在$F_1$值的基础上加权得到的,它可以更好的权衡查准率和查全率。
- 当$\beta<1$时,$P$的权重减小,即$R$查准率更重要
- 当$\beta=1$时,$F_\beta = F_1$
- 当$\beta>1$时,$P$的权重增大,即$P$查全率更重要