排列测试评分是一种统计方法,用于评估交叉验证得分的显著性。通过这种方法,可以确定模型预测的准确性是否具有统计学意义。本文将使用Iris植物数据集进行演示,该数据集包含了从三种不同类型的鸢尾花中获取的测量数据。
首先,从sklearn.datasets库中导入Iris数据集。这个数据集包含了150个样本,每个样本有四个特征。还将生成一些与Iris数据集类别标签无关的随机特征数据。
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data
y = iris.target
import numpy as np
n_uncorrelated_features = 20
rng = np.random.RandomState(seed=0)
X_rand = rng.normal(size=(X.shape[0], n_uncorrelated_features))
接下来,使用原始的Iris数据集和随机生成的特征数据来计算排列测试评分。将使用支持向量机(SVC)分类器和准确率评分来评估每一轮的模型。排列测试评分通过计算1000次数据集的不同排列的分类器准确率来生成一个零分布,其中特征保持不变,但标签经过不同的排列。这是零假设的分布,即特征和标签之间没有依赖关系。然后计算经验p值,作为获得的分数大于原始数据获得的分数的排列的百分比。
from sklearn.model_selection import StratifiedKFold, permutation_test_score
from sklearn.svm import SVC
clf = SVC(kernel="linear", random_state=7)
cv = StratifiedKFold(2, shuffle=True, random_state=0)
score_iris, perm_scores_iris, pvalue_iris = permutation_test_score(
clf, X, y, scoring="accuracy", cv=cv, n_permutations=1000
)
score_rand, perm_scores_rand, pvalue_rand = permutation_test_score(
clf, X_rand, y, scoring="accuracy", cv=cv, n_permutations=1000
)
在下面的图表中,绘制了排列得分的直方图(零分布)。红线表示分类器在原始数据上获得的分数。这个分数明显优于使用排列数据获得的分数,因此p值非常低。这表明,仅凭偶然性获得如此高分的可能性很低,为Iris数据集包含特征和标签之间的真实依赖关系提供了证据,分类器能够利用这种依赖关系获得良好的结果。
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.hist(perm_scores_iris, bins=20, density=True)
ax.axvline(score_iris, ls="--", color="r")
score_label = f"Score on original\ndata: {score_iris:.2f}\n(p-value: {pvalue_iris:.3f})"
ax.text(0.7, 10, score_label, fontsize=12)
ax.set_xlabel("Accuracy score")
ax.set_ylabel("Probability density")
在下面的图表中,绘制了随机数据的零分布。排列得分与使用原始Iris数据集获得的得分相似,因为排列总是破坏任何特征标签依赖关系。然而,在这种情况下,原始随机数据上获得的分数非常差。这导致了一个很大的p值,证实了原始数据中没有特征标签依赖关系。
fig, ax = plt.subplots()
ax.hist(perm_scores_rand, bins=20, density=True)
ax.set_xlim(0.13)
ax.axvline(score_rand, ls="--", color="r")
score_label = f"Score on original\ndata: {score_rand:.2f}\n(p-value: {pvalue_rand:.3f})"
ax.text(0.14, 7.5, score_label, fontsize=12)
ax.set_xlabel("Accuracy score")
ax.set_ylabel("Probability density")
plt.show()
另一个可能获得高p值的原因是分类器无法利用数据中的结构。在这种情况下,只有能够利用数据中依赖关系的分类器才会有低p值。在上述的随机数据案例中,所有分类器都会有高p值,因为数据中没有结构存在。最后,请注意,即使数据中只有微弱的结构,这种测试也已被证明可以产生低p值。
Ojala和Garriga. "Permutation Tests for Studying Classifier Performance". The Journal of Machine Learning Research (2010) vol. 11