cochrans_q: Cochran's Q 检验,用于比较多个分类器
Cochran's Q 检验,用于比较多个分类器的性能。
from mlxtend.evaluate import cochrans_q
概览
Cochran's Q 检验可以视为 McNemar 检验的广义版本,可用于评估多个分类器。从某种意义上说,Cochran's Q 检验类似于 ANOVA 用于二元结果。
要比较两个以上的分类器,我们可以使用 Cochran's Q 检验,其检验统计量近似遵循(类似于 McNemar 检验)卡方分布,自由度为,其中 L 是我们评估的模型数量(因为对于 McNemar 检验,McNemar 检验统计量近似遵循自由度为 1 的卡方分布)。更为正式地,Cochran's Q 检验检验的假设是分类准确率之间没有差异 [1]
设
是一组分类器,它们都在相同的数据集上进行了测试。如果这 L 个分类器的表现没有差异,则以下 Q 统计量近似遵循自由度为的“卡方”分布此处,
是模型在个对象中正确分类的对象数量。; 是个分类器中正确分类对象的分类器数量,其中是用于测试分类器的测试数据集;并且是个分类器中正确分类票数的总数 [2]
为了执行 Cochran's Q 检验,我们通常将分类器预测组织成一个二元矩阵。如果分类器错误分类了数据示例(向量),则此矩阵的条目为 0;否则为 1(如果分类器正确预测了类别标签)[2]。以下示例取自 [2],说明了如何组织分类结果。例如,假设我们有测试数据集的真实标签 y_true
以及 3 个分类器(y_model_1
、y_model_2
和 y_model_3
)的以下预测结果:
然后,正确 (1) 和不正确 (0) 分类的表格可能如下所示:
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])
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])
正确 (1) 和 错误 (0) 分类 的 表格 可能 会 如下 所示
(模型 1) | (模型 2) | (模型 3) | 出现次数 | |
---|---|---|---|---|
1 | 1 | 1 | 80 | |
1 | 1 | 0 | 2 | |
1 | 0 | 1 | 0 | |
1 | 0 | 0 | 2 | |
0 | 1 | 1 | 9 | |
0 | 1 | 0 | 1 | |
0 | 0 | 1 | 3 | |
0 | 0 | 0 | 3 | |
准确率 | 84/100*100% = 84% | 92/100*100% = 92% | 92/100*100% = 92% |
将相应的值代入前面的等式,我们得到以下值 [2]
(注意,[2] 中的值由于排印错误列为 3.7647,与作者讨论后,正确值为 7.5294。)
现在,Q 值(近似于)对应于近似 0.023 的 p 值,假设分布为自由度的。假设我们选择的显著性水平为,我们将拒绝所有分类器表现相同的零假设,因为.
在实践中,如果我们成功拒绝了零假设,我们可以执行多个事后成对检验——例如,使用 Bonferroni 校正的 McNemar 检验——以确定哪些对的总体比例不同。
参考文献
- [1] Fleiss, Joseph L., Bruce Levin, and Myunghee Cho Paik. Statistical methods for rates and proportions. John Wiley & Sons, 2013.
- [2] Kuncheva, Ludmila I. Combining pattern classifiers: methods and algorithms. John Wiley & Sons, 2004.
示例 1 - Cochran's Q 检验
import numpy as np
from mlxtend.evaluate import cochrans_q
from mlxtend.evaluate import mcnemar_table
from mlxtend.evaluate import mcnemar
## 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 检验,以检验分类准确率没有差异的零假设,:
q, p_value = cochrans_q(y_true,
y_model_1,
y_model_2,
y_model_3)
print('Q: %.3f' % q)
print('p-value: %.3f' % p_value)
Q: 7.529
p-value: 0.023
由于 p 值小于,我们可以拒绝零假设并得出结论:分类准确率之间存在差异。正如引言中提到的,我们现在可以执行多个事后成对检验——例如,使用 Bonferroni 校正的 McNemar 检验——以确定哪些对的总体比例不同。
最后,让我们说明 Cochran's Q 检验确实只是 McNemar 检验的一个广义版本
chi2, p_value = cochrans_q(y_true,
y_model_1,
y_model_2)
print('Cochran\'s Q Chi^2: %.3f' % chi2)
print('Cochran\'s Q p-value: %.3f' % p_value)
Cochran's Q Chi^2: 5.333
Cochran's Q p-value: 0.021
chi2, p_value = mcnemar(mcnemar_table(y_true,
y_model_1,
y_model_2),
corrected=False)
print('McNemar\'s Chi^2: %.3f' % chi2)
print('McNemar\'s p-value: %.3f' % p_value)
McNemar's Chi^2: 5.333
McNemar's p-value: 0.021
API
cochrans_q(y_target, *y_model_predictions)
Cochran's Q 检验,用于比较 2 个或更多模型。
参数
-
y_target
: array-like, shape=[n_samples]作为 1D NumPy 数组的真实类别标签。
-
*y_model_predictions
: array-likes, shape=[n_samples]可变数量的 2 个或更多数组,包含模型预测的类别标签,作为 1D NumPy 数组。
返回值
-
q, p
: float 或 None, float返回 Q (chi-squared) 值和 p 值
示例
有关使用示例,请参阅 https://mlxtend.cn/mlxtend/user_guide/evaluate/cochrans_q/