:
目标:
1 了解Friedman test的基本原理以及使用实践;
2 了解Post-hoc Nimenyi test 的基本原理以及使用实践,包括结果的可视化。
Friedman test
作用: 简单来说, Friedman test就是一种基于排序的统计方法用来比较多个方法/模型在多份数据集/实验中的平均性能是否存在显著差异。
Null H0 hypothesis: 用于比较的多个方法性能相当;
假设现在有N粉数据集,K个模型, 这K个模型在N的数据集上的测试结果组成结果矩阵,尺寸: [N, K]。
Step 1: 计算序值矩阵以及每个模型对应的Rank值。
对于每份数据集, 将K个模型按照其性能升序进行排序后的索引值作为对应模型在该数据集上的序值。
例如,K=4个模型在第一份数据集上的Accuracy分别为0.6, 0.5, 0.9, 0.2, 则对应的序值向量为3,2,4,1。
注, 当有不止一个模型在同一个数据集上的Accuracy相同时,去平均即可,但要保证序值总和不变。 如,Accuracy分别为0.6, 0.5, 0.5, 0.2,则对应的序值向量为4,2.5, 2.5,1。
得到序值矩阵后就可以计算每个模型的Rank值了。
记第i个模型在第j个数据集上的序值为 r a n k i , j rank_{i,j} ranki,j, 则第i个模型的Rank为:
r i = 1 N ∑ j = 1 N r a n k i , j r_{i}=\frac{1}{N}\sum_{j=1}^{N}rank_{i,j} ri=N1∑j=1Nranki,j
Step 2: 计算相应的统计量
假设每个模型的Rank服从正态分布,则对应的卡方统计量为,
τ X 2 = k − 1 k ∑ i = 1 k ( r i − k + 1 2 ) 2 / 12 N k 2 − 1 = 12 N k ( k + 1 ) { ∑ i = 1 k r i 2 − k ( k + 1 ) 2 4 } \tau_{X^{2}}=\frac{k-1}{k}\sum_{i=1}^{k}(r_{i} - \frac{k+1}{2})^{2}/{\frac{12N}{k^{2} - 1}}=\frac{12N}{k(k+1)}\{\sum_{i=1}^{k} r_{i}^{2} - \frac{k(k+1)^{2}}{4}\} τX2=kk−1∑i=1k(ri−2k+1)2/k2−112N=k(k+1)12N{∑i=1kri2−4k(k+1)2}
另外还有其改进统计量
τ F = ( N − 1 ) τ X 2 N ( k − 1 ) − τ X 2 \tau_{F}=\frac{(N-1)\tau_{X^{2}}}{N(k-1) - \tau_{X^{2}}} τF=N(k−1)−τX2(N−1)τX2
将算出来的统计量与临界检验值表进行比对,
实践
Python包Scipy的stats模块提供了Friedman test的API, 可直接调用。
Demo:
如下, data即为上面所说的NxK矩阵,
注意:friedmanchisquare
的输入中,每个参数表示每个模型的多次(N=4)测量值
最终输出结果:
p_value < α = 0.05 \alpha=0.05 α=0.05, 故拒绝H0假设, 换句话说,多个模型的测量结果之间有显著差异。
Post-hoc Nimenyi test
Friedman test只能用来确定多个模型的测量结果之间是否存在显著差异,却并不能知道任意两个模型之间是否存在差异,这正是Post-hoc Nimenyi test所要解决的。
Step 1, 首先计算所谓的临界值Critical Difference (CD)。
计算公式如下:
C D = q α k ( k + 1 ) 6 N CD=q_{\alpha} \sqrt{\frac{k(k+1)}{6N}} CD=qα6Nk(k+1)
其中 α \alpha α
CD的计算可直接调用
Orange.evaluation.compute_CD(avranks, num_exp, alpha=str(alpha))
Step 2,将两个算法的平均序值的差 (Average Rank Difference, ARD) 和 CD 进行比较,如果 ARD > CD,则两个算法的性能有明显差异
实践
Python包scikit_posthocs提供了用于Post-hoc Nimenyi test的API,可直接调用。
Demo:
最终输出结果:
可以看到输出为一个对称矩阵,表示不同模型的两两比较结果,
Post-hoc Nimenyi test结果可视化
这方面可供参考的资料非常少,刚开始好不容易找到一个, 结果发现虽然可以运行,但是图明显有错误。
最后发现Python包Orange3有Post-hoc Nimenyi test的可视化API。
Demo:
数据如下
names = list(methods_with_score.keys())
avranks = list(methods_with_score.values())‘’‘ cmpt Critical Difference (CD)’‘’
cd = Orange.evaluation.compute_CD(avranks, num_exp, alpha=str(alpha))
print('Critical difference (CD): {}'.format(cd))graph_ranks(avranks, names, cd=cd, width=6, textspace=1.5, filename=filename)
最终效果图如下,
可以看到: 从统计意义上讲模型3,4,5的结果是Comparable, 同时模型4,5,1的结果又是Comparable, 而模型1,3的结果差异非常显著。
References
1.Statistical comparisons of classifiers over multiple data sets
2. Distribution-free multiple comparisons
3. Python包orange3 API的官网介绍
4. https://blog.csdn.net/qq_38225713/article/details/103890338?utm_term=hoc%20post&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allsobaiduweb~default-0-103890338&spm=3001.4430