Friedman检验及后续Nemenyi检验可视化

2024-01-02 09:29:30 浏览数 (2)

文章目录
  • Friedman 检验
  • Nemeny检验

Friedman 检验


弗里德曼检验(Friedman test)是一种非参数统计检验方法,用于比较来自不同群体或条件的相关样本。它是一种针对重复测量设计的方法,适用于有序分类变量或等级变量。Friedman 检验是一种非参数方法,它不依赖于数据的分布假设,因此在数据不满足正态分布或方差齐性的情况下也可以使用。它广泛应用于医学、社会科学和其他领域的研究中,特别适用于重复测量设计和相关样本的比较分析。

弗里德曼检验的目的是确定多个相关样本是否存在显著差异。它基于样本的秩次或等级信息,而不是具体的数值。该检验假设每个样本都来自同一总体,并且评估各组之间的差异是否显著。

具体来说,原假设是所有方法具有相同的秩。令

R_j

表示第

j

个方法的秩的均值,

k

表示涉及方法的数量,

N

表示涉及数据集/实验的数量我们有Friedman统计量:

chi_F^2=frac{12N}{k(k 1)}(sum_{j=1}^kR_j^2-frac{k(k 1)^2}{4})

服从自由度为

(k-1)

的 chi_F^2分布。以及

F_F=frac{(N-1)chi_F^2}{N(k-1)-chi_F^2}

是自由度为

(k-1)

(k-1)(N-1)

F

分布。如果原假设被拒绝,那么接下来Nemenyi后续检验就会被执行。

比如对于7中方法,进行了5次实验,实验排名如下表所示:

实验1

实验2

实验3

实验4

实验5

3

2

3

4

1

5

5

7

5

4

2

3

2

1

3

1

1

1

2

2

4

6

4

3

5

6

4

6

7

6

7

7

5

6

7

在这个例子里面,我有

k=7,N=5

,那么根据上述公式,我们可以计算得到

chi_F^2=-27.1714

F_F=16.5882

。因此,对于显著水平

alpha=0.05

,我们可以计算

F_alpha=F_{0.05}(6,24)=2.5082

,由于

F_F>F_alpha

,我们拒绝原假设,也就是说方法间存在显著差异。接下来执行Nemeny检验。

给出对应计算的python代码:

代码语言:javascript复制
from scipy.stats import f


def friedman(R, k, N):
    xf = 0
    for i in range(len(R)):
        xf = xf   R[i] * R[i]
    xf = xf - k * (k   1) * (k   1) / 4
    xf = xf * 12 * N / k / (k   1)

    ff = (N - 1) * xf / (N * (k - 1) - xf)
    return xf, ff


def CD(q, k, N):
    CD = q * math.sqrt(k * (k   1) / 6 / N)
    return CD

def F_alpha(alpha,n,d):
	return f.isf(q=alpha, dfn=n, dfd=d)

插播反爬信息 )博主CSDN地址:https://wzlodq.blog.csdn.net/

Nemeny检验


在拒绝原假设后,如果两个方法间的平均秩的差异,达到了显著差异critical difference (

CD

)的话,就称这两个方法间存在显著差异。:

CD=q_alphasqrt{frac{k(k 1)}{6N}}

器中

alpha

表示显著水平,通常取0.05或0.1。

q_alpha

是对应查表对应的常量。

还是对于上述例子,对于显著水平

alpha=0.05

,我们有

q_{0.05}=2.9480

,然后根据公式计算得到

CD=4.0277

。也就是说两个方法的平均秩达到4.0277的话,它们间存在显著差异。最后我们可以通过以下matlab代码进行可视化:

代码语言:javascript复制
%function cd = criticaldifference(s,labels,alpha)
s=[
3 2 3 4 1
5 5 7 5 4
2 3 2 1 3
1 1 1 2 2
4 6 4 3 5
6 4 6 7 6
7 7 5 6 7
]';
labels={'A','B','C','D','E','F','G'};%方法的标签
alpha=0.05; %显著性水平0.1,0.05或0.01%

if nargin < 3
   alpha = 0.1;
end

% convert scores into ranks 
[N,k] = size(s);
[S,r] = sort(s');
idx   = k*repmat(0:N-1, k, 1)'   r';
R     = repmat(1:k, N, 1);
S     = S';

for i=1:N
    for j=1:k
        index    = S(i,j) == S(i,:);
        R(i,index) = mean(R(i,index));
    end
end

r(idx)  = R;
r       = r';

% compute critical difference
if alpha == 0.01
   qalpha = [0.000 2.576 2.913 3.113 3.255 3.364 3.452 3.526 3.590 3.646 ...
             3.696 3.741 3.781 3.818 3.853 3.884 3.914 3.941 3.967 3.992 ...
             4.015 4.037 4.057 4.077 4.096 4.114 4.132 4.148 4.164 4.179 ...
             4.194 4.208 4.222 4.236 4.249 4.261 4.273 4.285 4.296 4.307 ...
             4.318 4.329 4.339 4.349 4.359 4.368 4.378 4.387 4.395 4.404 ...
             4.412 4.420 4.428 4.435 4.442 4.449 4.456 ];
         
elseif alpha == 0.05 
   qalpha = [0.000 1.960 2.344 2.569 2.728 2.850 2.948 3.031 3.102 3.164 ...
             3.219 3.268 3.313 3.354 3.391 3.426 3.458 3.489 3.517 3.544 ...
             3.569 3.593 3.616 3.637 3.658 3.678 3.696 3.714 3.732 3.749 ...
             3.765 3.780 3.795 3.810 3.824 3.837 3.850 3.863 3.876 3.888 ...
             3.899 3.911 3.922 3.933 3.943 3.954 3.964 3.973 3.983 3.992 ...
             4.001 4.009 4.017 4.025 4.032 4.040 4.046]; 

elseif alpha == 0.1
   qalpha = [0.000 1.645 2.052 2.291 2.460 2.589 2.693 2.780 2.855 2.920 ...
             2.978 3.030 3.077 3.120 3.159 3.196 3.230 3.261 3.291 3.319 ...
             3.346 3.371 3.394 3.417 3.439 3.459 3.479 3.498 3.516 3.533 ...
             3.550 3.567 3.582 3.597 3.612 3.626 3.640 3.653 3.666 3.679 ...
             3.691 3.703 3.714 3.726 3.737 3.747 3.758 3.768 3.778 3.788 ...
             3.797 3.806 3.814 3.823 3.831 3.838 3.846];

else
    error('alpha must be 0.01, 0.05 or 0.1');
end
cd = qalpha(k)*sqrt(k*(k 1)/(6*N));

disp(alpha)
disp(qalpha(k))
disp(k)
disp(N)
disp(cd)

figure(1);
clf
axis off
axis([-0.2 1.2 -20 140]);
axis xy 
tics = repmat((0:(k-1))/(k-1), 3, 1);
line(tics(:), repmat([100, 101, 100], 1, k), 'LineWidth', 1.5, 'Color', 'k');
line([0 0 0 cd/(k-1) cd/(k-1) cd/(k-1)], [113 111 112 112 111 113], 'LineWidth', 1, 'Color', 'r');
text(0.03, 116, ['Critical Distance=' num2str(cd)], 'FontSize', 12, 'HorizontalAlignment', 'left', 'Color', 'r');

for i=1:k
    text((i-1)/(k-1), 105, num2str(k-i 1), 'FontSize', 12, 'HorizontalAlignment', 'center');
end

% compute average ranks
r       = mean(r);
[r,idx] = sort(r);

% compute statistically similar cliques
clique           = repmat(r,k,1) - repmat(r',1,k);
clique(clique<0) = realmax; 
clique           = clique < cd;

for i=k:-1:2
    if all(clique(i-1,clique(i,:))==clique(i,clique(i,:)))
        clique(i,:) = 0;
    end
end

n                = sum(clique,2);
clique           = clique(n>1,:);
n                = size(clique,1);


b=linspace(0,1,k);
% labels displayed on the right
for i=1:ceil(k/2)
   line([(k-r(i))/(k-1) (k-r(i))/(k-1) 1], [100 100-3*(n 1)-10*i 100-3*(n 1)-10*i], 'Color', [0 0 b(i)]);
   text(1.02, 100 - 3*(n 1) - 10*i, labels{idx(i)}, 'FontSize', 12, 'VerticalAlignment', 'middle', 'HorizontalAlignment', 'left', 'Color', [0 0 b(i)]);
end

% labels displayed on the left
for i=ceil(k/2) 1:k
   line([(k-r(i))/(k-1) (k-r(i))/(k-1) 0], [100 100-3*(n 1)-10*(k-i 1) 100-3*(n 1)-10*(k-i 1)], 'Color', [0 0 b(i)]);
   text(-0.02, 100 - 3*(n 1) -10*(k-i 1), labels{idx(i)}, 'FontSize', 12, 'VerticalAlignment', 'middle', 'HorizontalAlignment', 'right', 'Color', [0 0 b(i)]);
end

% group cliques of statistically similar classifiers
for i=1:size(clique,1)
   R = r(clique(i,:));
   line([((k-min(R))/(k-1)) ((k-min(R))/(k-1)) ((k-min(R))/(k-1)) ((k - max(R))/(k-1)) ((k - max(R))/(k-1)) ((k - max(R))/(k-1))], [100 1-5*i 100-1-5*i 100-5*i 100-5*i 100-1-5*i 100 1-5*i], 'LineWidth', 1, 'Color', 'r');
end

可视化结果:

图中横坐标从右到左依次是各个方法的平均秩,颜色从黑色渐变蓝色。若它们的平均秩差异达到CD,则用红线显示出来。如方法D显著优于B、F、G。方法C显著优于F、G。

只需修改数组s为你的方法排名,以及对应的方法名labels,即可算出CD,以及打印对应的

q_alpha

原创不易,请勿转载本不富裕的访问量雪上加霜 ) 博主首页:https://wzlodq.blog.csdn.net/ 来都来了,不评论两句吗

0 人点赞