scikit-posthocs中AttributeError:模块无critical_difference_diagram属性求助
问题分析
出现AttributeError的直接原因是scikit_posthocs模块不存在critical_difference_diagram这个函数——该库当前版本的API中并没有提供这个方法,你可能混淆了其他统计库的函数名。
修正方案
要绘制Nemenyi检验的临界差异图,需要手动计算各模型的平均秩次,再根据临界差值(Critical Difference, CD)来绘制。以下是完整的修正代码:
核心步骤
- 基于Friedman检验计算各模型的平均秩次
- 按标准公式计算临界差值CD
- 按平均秩次排序后绘制CD图
修正后的可运行代码
import scipy.stats as ss import scikit_posthocs as sp import numpy as np import matplotlib.pyplot as plt # 示例数据(10次交叉验证,5个模型的结果) np.random.seed(42) data = np.random.rand(10, 5) # 维度:(样本数, 模型数) # 1. 计算每个模型的平均秩次 ranks = ss.rankdata(data, axis=1) # 对每个样本的模型结果求秩 mean_ranks = ranks.mean(axis=0) num_models = mean_ranks.size num_samples = data.shape[0] # 2. 执行Nemenyi事后检验(保留原逻辑) result = sp.posthoc_nemenyi_friedman(data) sp.sign_plot(result) plt.show() # 3. 计算临界差值CD # Nemenyi检验CD公式:CD = q_alpha * sqrt(k*(k+1)/(6*N)) # q_alpha为学生化极差分布的临界值(alpha=0.05) q_alpha = ss.studentized_range.ppf(1 - 0.05, num_models, np.inf) cd = q_alpha * np.sqrt(num_models * (num_models + 1) / (6 * num_samples)) # 4. 绘制临界差异图 plt.figure(figsize=(10, 3), dpi=100) plt.title('Critical difference diagram of average score ranks') # 按平均秩次排序模型 sorted_idx = np.argsort(mean_ranks) sorted_ranks = mean_ranks[sorted_idx] model_names = [f'Model {i+1}' for i in sorted_idx] # 绘制平均秩次散点 plt.scatter(sorted_ranks, np.zeros_like(sorted_ranks), s=100, zorder=5) # 添加模型名称标签 for rank, name in zip(sorted_ranks, model_names): plt.text(rank, 0.1, name, ha='center', fontsize=10) # 绘制CD标记线 plt.hlines(y=0, xmin=sorted_ranks.min()-cd/2, xmax=sorted_ranks.max()+cd/2, color='gray', linestyle='--') plt.hlines(y=-0.1, xmin=sorted_ranks.min(), xmax=sorted_ranks.min()+cd, color='red', lw=2) plt.text(sorted_ranks.min()+cd/2, -0.2, f'CD = {cd:.2f}', ha='center', color='red') # 优化图表样式 plt.yticks([]) plt.xlabel('Average Rank') plt.tight_layout() plt.show()
关键说明
- CD值的计算严格遵循Nemenyi检验的标准公式,确保统计有效性
- 手动实现CD图绘制逻辑,无需依赖不存在的库函数
- 保留了你原有的
sign_plot调用逻辑,同时补充了完整的临界差异图实现
内容的提问来源于stack exchange,提问作者Verner
相关产品推荐
相关产品推荐

