ftest: 用于比较分类器的 F 检验
用于比较多个分类器性能的 F 检验。
from mlxtend.evaluate import ftest
概述
在评估机器学习模型的上下文中,George W. Snedecor [1] 的 F 检验可以被视为类似于 Cochran 的 Q 检验,后者可用于评估多个分类器(即,它们在测试集上估计的准确率是否不同),正如 Looney [2][3] 所描述的那样。
更正式地,假设任务是检验分类准确率之间没有差异的零假设 [1]
设是所有都在相同数据集上测试过的分类器集合。如果分类器表现没有差异,则 F 统计量服从自由度为和的 F 分布,其中是测试集中的样本数。F 统计量的计算包含几个组成部分,如下所列(摘自 [2])。
我们首先定义作为不同模型准确率的平均值
然后计算分类器的平方和,如下所示:
其中是个被分类器正确分类的样本的比例.
对象的平方和计算如下:
此处,是个分类器中正确分类了对象的分类器数量,其中是分类器测试所用的测试数据集。
最后,我们计算总平方和,
这样我们就可以计算分类-对象交互作用的平方和
为了计算 F 统计量,接下来我们计算 SSA 和 SSAB 的均值
和
由 MSA 和 MSAB,我们可以计算出 F 值
计算出 F 值后,我们可以从相应的自由度的 F 分布表中查找 p 值,或通过累积 F 分布函数计算得到。在实践中,如果在预设的显著性阈值下成功拒绝了零假设,我们可以执行多重事后配对检验——例如,使用 Bonferroni 校正的 McNemar 检验——以确定哪些对的总体比例不同。
参考文献
- [1] Snedecor, George W. 和 Cochran, William G. (1989),统计方法,第八版,爱荷华州立大学出版社。
- [2] Looney, Stephen W. "一种比较多个分类器准确率的统计技术。" Pattern Recognition Letters 8, no. 1 (1988): 5-9。
- [3] Kuncheva, Ludmila I. 组合模式分类器:方法与算法。John Wiley & Sons, 2004。
示例 1 - F 检验
import numpy as np
from mlxtend.evaluate import ftest
## Dataset:
# ground truth labels of the test dataset:
y_true = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0])
# predictions by 3 classifiers (`y_model_1`, `y_model_2`, and `y_model_3`):
y_model_1 = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0])
y_model_2 = np.array([1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0])
y_model_3 = np.array([1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1])
假设显著性水平为,我们可以进行如下的 Cochran's Q 检验,以检验分类准确率之间没有差异的零假设,:
f, p_value = ftest(y_true,
y_model_1,
y_model_2,
y_model_3)
print('F: %.3f' % f)
print('p-value: %.3f' % p_value)
F: 3.873
p-value: 0.022
由于 p 值小于,我们可以拒绝零假设,并得出结论认为分类准确率之间存在差异。正如前文引言中提到的,我们现在可以执行多重事后配对检验——例如,使用 Bonferroni 校正的 McNemar 检验——以确定哪些对的总体比例不同。
API
ftest(y_target, *y_model_predictions)
用于比较 2 个或更多模型的 F 检验。
参数
-
y_target
: 类似数组, shape=[n_samples]真实的类别标签,为 1D NumPy 数组。
-
*y_model_predictions
: 类似数组, shape=[n_samples]包含来自模型预测类别标签的变量数量(2 个或更多)的 1D NumPy 数组。
返回
-
f, p
: float 或 None, float返回 F 值和 p 值
示例
使用示例请参见 https://mlxtend.cn/mlxtend/user_guide/evaluate/ftest/