paired_ttest_5x2cv: 用于比较分类器的 5x2cv 配对 t 检验

比较两个模型性能的 5x2cv 配对 t 检验过程

from mlxtend.evaluate import paired_ttest_5x2cv

概述

5x2cv 配对 t 检验是一种比较两个模型(分类器或回归器)性能的过程,由 Dietterich [1] 提出,旨在解决其他方法(如重采样配对 t 检验 (见 paired_ttest_resampled) 和 K 折交叉验证配对 t 检验 (见 paired_ttest_kfold_cv))的缺点。

为了解释这种方法如何工作,让我们考虑两个估计器(例如,分类器)A 和 B。此外,我们有一个带标签的数据集 D。在常见的留出法中,我们通常将数据集分成两部分:训练集和测试集。在 5x2cv 配对 t 检验中,我们将这种分割(50% 训练数据和 50% 测试数据)重复进行 5 次。

在 5 次迭代中的每一次,我们将 A 和 B 拟合到训练分割数据上,并评估其性能()在测试分割数据上。然后,我们旋转训练集和测试集(训练集变成测试集,反之亦然),再次计算性能,从而得到 2 个性能差异度量

然后,我们估计差异的均值和方差

对 5 次迭代的差异计算方差,然后用于计算 t 统计量,如下所示

其中来自第一次迭代。在模型 A 和 B 性能相等的零假设下,假定 t 统计量近似服从自由度为 5 的 t 分布。使用 t 统计量,可以计算 p 值并与预先选择的显著性水平进行比较,例如,。如果 p 值小于,我们拒绝零假设,并接受这两个模型之间存在显著差异。

参考文献

  • [1] Dietterich TG (1998) Approximate Statistical Tests for Comparing Supervised Classification Learning Algorithms. Neural Comput 10:1895–1923.

示例 1 - 5x2cv 配对 t 检验

假设我们要比较两种分类算法:逻辑回归和决策树算法

from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from mlxtend.data import iris_data
from sklearn.model_selection import train_test_split


X, y = iris_data()
clf1 = LogisticRegression(random_state=1)
clf2 = DecisionTreeClassifier(random_state=1)

X_train, X_test, y_train, y_test = \
    train_test_split(X, y, test_size=0.25,
                     random_state=123)

score1 = clf1.fit(X_train, y_train).score(X_test, y_test)
score2 = clf2.fit(X_train, y_train).score(X_test, y_test)

print('Logistic regression accuracy: %.2f%%' % (score1*100))
print('Decision tree accuracy: %.2f%%' % (score2*100))
Logistic regression accuracy: 97.37%
Decision tree accuracy: 94.74%

请注意,这些准确率值在配对 t 检验过程中未使用,因为在重采样过程中会生成新的测试/训练分割,上面的值仅用于帮助理解。

现在,让我们假设显著性阈值为,用于拒绝两个算法在数据集上表现相同的零假设,并进行 5x2cv t 检验

from mlxtend.evaluate import paired_ttest_5x2cv


t, p = paired_ttest_5x2cv(estimator1=clf1,
                          estimator2=clf2,
                          X=X, y=y,
                          random_seed=1)

print('t statistic: %.3f' % t)
print('p value: %.3f' % p)
t statistic: -1.539
p value: 0.184

由于,我们无法拒绝零假设,因此可以得出结论,这两种算法的性能没有显著差异。

虽然通常不建议在不进行多重假设检验校正的情况下多次应用统计检验,但让我们看一个决策树算法被限制产生非常简单的决策边界从而导致相对较差性能的例子

clf2 = DecisionTreeClassifier(random_state=1, max_depth=1)

score2 = clf2.fit(X_train, y_train).score(X_test, y_test)
print('Decision tree accuracy: %.2f%%' % (score2*100))


t, p = paired_ttest_5x2cv(estimator1=clf1,
                          estimator2=clf2,
                          X=X, y=y,
                          random_seed=1)

print('t statistic: %.3f' % t)
print('p value: %.3f' % p)
Decision tree accuracy: 63.16%
t statistic: 5.386
p value: 0.003

假设我们也在显著性水平为的情况下进行了此检验,由于 p 值()小于.

API

paired_ttest_5x2cv(estimator1, estimator2, X, y, scoring=None, random_seed=None)

实现 Dieterrich (1998) 提出的 5x2cv 配对 t 检验,用于比较两个模型的性能。

参数

  • estimator1 : scikit-learn 分类器或回归器

  • estimator2 : scikit-learn 分类器或回归器

  • X : {类似数组, 稀疏矩阵},形状 = [n_样本, n_特征]

    训练向量,其中 n_样本 是样本数量,n_特征 是特征数量。

  • y : 类似数组,形状 = [n_样本]

    目标值。

  • scoring : str, 可调用对象, 或 None (默认: None)

    如果为 None (默认),则对 sklearn 分类器使用 'accuracy',对 sklearn 回归器使用 'r2'。如果为 str,则使用 sklearn 评分指标字符串标识符,例如,对分类器使用 {accuracy, f1, precision, recall, roc_auc},对回归器使用 {'mean_absolute_error', 'mean_squared_error'/'neg_mean_squared_error', 'median_absolute_error', 'r2'}。如果提供可调用对象或函数,则必须符合 sklearn 的签名 scorer(estimator, X, y);更多信息请参见 https://scikit-learn.cn/stable/modules/generated/sklearn.metrics.make_scorer.html。

  • random_seed : int 或 None (默认: None)

    用于创建测试/训练分割的随机种子。

返回值

  • t : float

    t 统计量

  • pvalue : float

    双尾 p 值。如果选择的显著性水平大于 p 值,则拒绝零假设,并接受两个被比较的模型之间存在显著差异。

示例

有关使用示例,请参见 https://mlxtend.cn/mlxtend/user_guide/evaluate/paired_ttest_5x2cv/