对学习器的泛化性能进行评估,不仅需要有效可行的实验估计方法,还需要有衡量模型泛化能力的评价标准,这就是性能度量(performance measure)。
性能度量反映了任务需求,在对比不同模型的能力时,使用不同的性能度量往往会导致不同的评判结果,这意味着模型的“好坏”是相对的,什么样的模型是好的,不仅取决于算法和数据,还决定于任务需求。
在预测任务中,给定数据集 D = ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x m , y m ) D = {(x_1, y_1), (x_2, y_2), \ldots, (x_m, y_m)} D=(x1,y1),(x2,y2),…,(xm,ym),其中 y i y_i yi 是示例 x i x_i xi 的真实标记。要估计学习器 f 的性能,就要把学习器预测结果 f ( x ) f(x) f(x) 与真实标记 y 进行比较。
为了说明各性能度量指标,我们以波士顿房价数据集为例,模型选择决策树算法,通过 train_test_split() 划分数据集,最后评估各项性能指标。
from sklearn.datasets import load_boston
from sklearn.tree import DecisionTreeRegressor
from sklearn.model_selection import train_test_split
# 引入数据集
dataset = load_boston()
data = dataset.data
target = dataset.target
features = dataset.feature_names
# 划分数据集以及模型训练
data_train, data_test, target_train, target_test = train_test_split(data, target, test_size=0.33, random_state=7)
model = DecisionTreeRegressor()
model.fit(data_train, target_train)
均方误差
均方误差(mean squared error)是回归问题中最常用的性能度量。
【计算公式】:
E
(
f
;
D
)
=
1
m
∑
i
=
1
m
(
f
(
x
i
)
−
y
i
)
2
E(f; D) = \frac{1}{m}\sum_{i=1}^{m}(f(x_i) - y_i)^2
E(f;D)=m1i=1∑m(f(xi)−yi)2
均方误差计算过程中可以不用考虑 f(x) - y 的正负性,因为无论是正值还是负值,平方后都为正值。因此,均方误差可以简化计算过程。
但均方误差也存在一个明显的缺陷:假设,现在有三个样本,它们的预测值与真实值的差分别为 3、4、5,通过均方误差的计算公式,我们可以分别计算出这三个样本的误差为 9、16 和 25;第三个样本的误差等于前两个样本的误差和,也就是说样本的预测值离真实值越远,误差也越大,且增长幅度越来越大,这相当于给误差大的样本更大的权重,你可以理解为在原有的误差上再乘以一个权重,而这个权重就是自身,例如差为 5,误差为 5 x 5;差为 4,误差为 4 x 4。
模型为了降低误差,势必会想办法优先让偏差最大的样本尽可能靠近真实值。换言之,偏差越大的样本对模型的影响也越大,如果这个样本是噪声,那么这对模型的精度产生重大负面影响。简单地说,均方误差对噪声不鲁棒。
【代码实现】:
from sklearn.metrics import mean_squared_error
print(mean_squared_error(target_test, model.predict(data_test)))
# 输出:23.77700598802395
关于 mean_squared_error 更多内容请参考官方文档 传送门
平均绝对误差
平均绝对误差(mean absolute error)的计算公式如下:
E
(
f
;
D
)
=
1
m
∑
i
=
1
m
∣
f
(
x
i
)
−
y
i
∣
E(f; D) = \frac{1}{m}\sum_{i=1}^{m}|f(x_i) - y_i|
E(f;D)=m1i=1∑m∣f(xi)−yi∣
相比均方误差,平均绝对误差对噪声鲁棒,因为无论样本的预测值与真实值的偏差是大还是小,其权重都是相同的。但平均绝对误差也存在一个缺陷,即 |f(x) - y| 函数整体不连续,下图是一个 |x - 1| = y 的绝对值函数。
可以看到,绝对值函数关于 1 对称,在 [ 1 , + ∞ ) [1, +\infty) [1,+∞) 以及 ( − ∞ , 1 ] (-\infty, 1] (−∞,1] 区间内连续,但在整个区间上不连续,这会产生什么影响呢?
- 相比均方误差不需要考虑正负性,平均绝对误差需要考虑计算结果的正负性,并将计算结果做绝对值处理;
- 因为平均绝对误差在整个区间上不连续,因此在使用梯度下降算法优化时,如果恰好落在对称轴所在的位置处(上图该点为 (1, 0)),该点的导数为 0,
【代码实现】:
from sklearn.metrics import mean_absolute_error
mean_absolute_error(target_test, model.predict(data_test))
# 输出:3.3149700598802405
关于 mean_absolute_error 的更多用法请参考官方文档 传送门
均方对数误差
均方对数误差(mean squared log error),计算公式如下:
E
(
f
;
D
)
=
1
m
∑
i
=
1
m
(
l
o
g
(
1
+
f
(
x
i
)
)
−
l
o
g
(
1
+
y
i
)
)
2
E(f; D) = \frac{1}{m}\sum_{i=1}^{m}(log(1 + f(x_i)) - log(1 + y_i))^2
E(f;D)=m1i=1∑m(log(1+f(xi))−log(1+yi))2
均方对数误差对噪声鲁棒,且在整体区间上连续。
【代码实现】:
from sklearn.metrics import mean_squared_log_error
print(mean_squared_log_error(target_test, model.predict(data_test)))
# 输出:0.049787561024740724
关于 mean_squared_log_error 的更多用法请参考官方文档 传送门
决定系数
决定系数,反映因变量的全部变异能通过回归关系被自变量解释的比例。拟合优度越大,自变量对因变量的解释程度越高,自变量引起的变动占总变动的百分比越高,观察点在回归直线附近越密集。如 R2(可决系数) 为 0.8,则表示回归关系可以解释因变量 80% 的变异。换句话说,如果我们能控制自变量不变,则因变量的变异程度会减少 80%。
【决定系数的特点】:
- 可决系数是非负的统计量。
- 可决系数的取值范围:0 <= R2 <= 1。
- 可决系数是样本观测值的函数,是因随机抽样而变动的随机变量。为此,对可决系数的统计的可靠性也应进行检验。
【代码实现】:
from sklearn.metrics import r2_score
print(r2_score(target_test, model.predict(data_test)))
# 输出:0.6866725568139921
总结
除了从 sklearn.metrics 包中调用相应的方法外,还可以在 cross_val_score() 中通过指定 scoring 参数来实现,例如:
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
kfold = KFold(n_splits=10, random_state=7)
print(cross_val_score(model, data_test, target_test, cv=kfold, scoring='r2'))
# 输出:
array([ 0.75188518, 0.12123666, 0.6575216 , 0.68733528, -0.3255725 ,
0.63977947, 0.46980397, 0.44631556, 0.66207059, 0.8873598 ])
https://github.com/clvsit/Machine-Learning-Note/blob/master/模型评估/模型评估(回归问题).ipynb
scoring 参数表
Scoring | Function | Comment |
---|---|---|
Classification | ||
Accuracy | metrics.accuracy_score | |
average_precision | metrics.average_precision_score | |
f1 | metrics.f1_score | for binary targets |
f1_micro | metrics.f1_score | micro-averaged |
f1_macro | metrics.f1_score | macro-averaged |
f1_weighted | metrics.f1_score | weighted average |
f1_samples | metrics.f1_score | by multilabel sample |
neg_log_loss | metrics.log_loss | requires predict_proba support |
precision etc. | metrics.precision_score | suffixes apply as with f1 |
recall etc. | metrics.recall_score | suffixes apply as with f1 |
roc_auc | metrics.roc_auc_score | |
Clustering | ||
adjusted_mutual_info_score | metrics.adjusted_mutual_info_score | |
adjusted_rand_score | metrics.adjusted_rand_score | |
completeness_score | metrics.completeness_score | |
fowlkes_mallows_score | metrics.fowlkes_mallows_score | |
homogeneity_score | metrics.homogeneity_score | |
mutual_info_score | metrics.mutual_info_score | |
normalized_mutual_info_score | metrics.normalized_mutual_info_score | |
v_measure_score | metrics.v_measure_score | |
Regression | ||
explained_variance | metrics.explained_variance_score | |
neg_mean_absolute_error | metrics.mean_absolute_error | |
neg_mean_squared_error | metrics.mean_squared_error | |
neg_mean_squared_log_error | metrics.mean_squared_log_error | |
neg_median_absolute_error | metrics.median_absolute_error | |
r2 | metrics.r2_score |
参考
- 《机器学习Python实践》
- sklearn 官方文档