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/