最近学到机器学习中的Friedman检验及Nemenyi后续检验[1],注意到Nemenyi检验的临界值域
$$CD=q_\alpha\sqrt{\dfrac{k(k+1)}{6N}}$$
其中的$q_\alpha$是由显著性水平$\alpha$及算法个数$k$查表得到的。
在[1]中,表2.7已给出Nemenyi检验中常用的临界值,表旁边注提示此值与“Tukey分布的临界值”相关,亦给出此值在R语言中的计算方法:
|
|
前文提及过的二项检验、$t$检验、$\chi^2$检验、$F$检验,[1]中除给出部分临界值表之外,边注亦同时给出了临界值在R和MATLAB中的计算方法。对于这几种检验,用Python也同样容易实现,只需利用scipy.stats
模块中的相应模块的ppf()
方法即可。以$\chi^2$检验为例,得到显著性水平为alpha
、自由度为k - 1
的$\chi^2$检验临界值的Python代码如下:
|
|
scipy.stats
中虽有binom
、t
、chi2
、f
等模块,但似乎并没有提供Nemenyi检验或Tukey检验相关的模块。发现其中虽然存在名称相近的tukey_hsd()
方法,但也不能用来计算Nemenyi检验的临界值。
查找Tukey检验相关内容,发现其基于学生化极差分布(studentized range distribution)。再次在scipy.stats
模块中查看,发现了studentized_range
模块,其中提供了熟悉的ppf()
方法。参考[1]中的R代码,可以使用:
|
|
另外在查找过程中偶然发现statsmodels
库的stats.libqsturng
模块中提供的qsturng()
方法也可用于计算学生化极差分布的临界值。statsmodels
库并未就此方法提供文档,查阅此方法源代码[2]中的注释,确认此函数与R中的qtukey()
函数等价,也不难给出:
|
|
不过,在确认这两个方法计算的临界值是否正确(毕竟不像$t$、$\chi^2$那样同名,同名的肯定是同一个分布就不用确认了)时,意外发现部分结果在四舍五入至千分位后,与[1]中表2.7所给临界值表相差0.001:
$\alpha$值 | $k$值 | [1]中所给临界值 | scipy 库计算的临界值 |
statsmodels 库计算的临界值 |
---|---|---|---|---|
0.05 | 7 | 2.949 | 2.948 | 2.948 |
0.10 | 5 | 2.459 | 2.460 | 2.459 |
0.10 | 6 | 2.589 | 2.589 | 2.588 |
0.10 | 7 | 2.693 | 2.693 | 2.692 |
0.10 | 9 | 2.855 | 2.855 | 2.854 |
不禁好奇为何会出现0.001的偏差。考虑到[1]中给出了R代码,尝试利用R计算上述几组$\alpha$、$k$值对应的临界值,结果更加出人意料:
$\alpha$值 | $k$值 | [1]中所给临界值 | R计算的临界值 | scipy 库计算的临界值 |
statsmodels 库计算的临界值 |
---|---|---|---|---|---|
0.05 | 7 | 2.949 | 2.94832 | 2.948320017529675 | 2.9482857187201383 |
0.10 | 5 | 2.459 | 2.459516 | 2.4595157642714183 | 2.459359694834468 |
0.10 | 6 | 2.589 | 2.588521 | 2.588520601922348 | 2.5882688946620926 |
0.10 | 7 | 2.693 | 2.692732 | 2.6927321009677594 | 2.692460382234158 |
0.10 | 9 | 2.855 | 2.854606 | 2.854606431198026 | 2.854379183347442 |
除了$\alpha=0.05,k=7$和$\alpha=0.10,k=5$这两组之外,[1]中所给临界值都与R的计算结果四舍五入至千分位后相等。R与scipy
库的结果基本一致,但是statsmodels
库的计算结果居然在万分位就开始出现了巨大的偏差!而$\alpha=0.10,k=5$这一组,[1]中的临界值却和statsmodels
库计算的临界值相近。
考虑到可能三者的实现方法不同。阅读qtukey()
函数的文档[3]、studentized_range
模块的文档[4]和qsturng()
方法的源代码[2],发现确实如此:R中qtukey()
函数的实现基于Copenhaver和Holland(1988)[5]的方法,scipy
库中studentized_range.ppf()
方法的实现基于Lund和Lund(1983)[6]的方法,而statsmodels
库中qsturng()
方法的实现基于Gleason(1999)[7]的方法。[7]认为自己提出的计算方法比[6]更简单、更准确。关于三者具体有何不同、何者更优,已偏离“机器学习”的主题甚远,本文不再深入讨论。
至于[1]中为何给出了异于以上任何一种实现算得的临界值,在该章末尾的参考文献[8]中可以找到答案。[8]中表5(a)与[1]中表2.7所给数据完全相同,[8]也是博主目前能找到的最早给出$\alpha=0.05,k=7$时临界值$q_\alpha=2.949$的文献,可能也是最早提出将Nemenyi方法用于模型比较的。[8]中只提及$q_\alpha$的计算方法是学生化极差的数据除以$\sqrt2$,并未提及具体如何计算学生化极差的临界值,或许是采用的数据来源有舍入而损失了精度吧。
参考资料
- ↑周志华.机器学习[M].北京:清华大学出版社.2016:42-44.
- ↑↑statsmodels.
qsturng_.py [CP/OL]. [2024-02-02]. https:// github.com/ .statsmodels/ statsmodels/ blob/ main/ statsmodels/ stats/ libqsturng/ qsturng_.py - ↑DataCamp.
Tukey function [EB/OL]// RDocumentation [2024-02-03]. https:// www.rdocumentation.org/ .packages/ stats/ versions/ 3.6.2/ topics/ Tukey - ↑The SciPy community.
scipy.stats.studentized_range [EB/OL]// SciPy v1.12.0 Manual [2024-02-03]. https:// docs.scipy.org/ .doc/ scipy/ reference/ generated/ scipy.stats.studentized_range.html - ↑Copenhaver M D,
Holland B. Computation of the distribution of the maximum studentized range statistic with application to multiple significance testing of simple effects [J]. Journal of Statistical Computation and Simulation, 1988, 30(1): 1-15. - ↑Lund R E,
Lund J R. Algorithm AS 190: Probabilities and Upper Quantiles for the Studentized Range [J]. Journal of the Royal Statistical Society, 1983, 32(2), 204-210. - ↑Gleason J R.
An accurate, non-iterative approximation for studentized range quantiles [J]. Computational Statistics& Data Analysis, 1999, 31(2): 147-158. - ↑Demšar J.
Statistical comparisons of classifiers over multiple data sets [J]. Journal of Machine learning research, 2006, 7: 1-30.