wzy-1642 2024-04-30 16:57 采纳率: 16.7%
浏览 2

Nemenyi检验结果有疑问

请问这段代码哪里有错误吗?为什么最后得出的结果不对?(现实中lg和rf、clf的性能相差明显,而Nemenyi检验得出的结果是rf和clf性能相差有显著性,反而与lg性能相差无显著性)
代码如下:


# 初始化分类器
lg=LogisticRegression(random_state=42)
rf = RandomForestClassifier(n_estimators=100, random_state=42)
clf = DecisionTreeClassifier(random_state=42)
# 交叉验证
skfolds=StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
# 性能指标列表
performance_scores = {
    'lg': {'accuracy': [], 'precision': [], 'recall': [], 'f1': [], 'auc': []},
    'rf': {'accuracy': [], 'precision': [], 'recall': [], 'f1': [], 'auc': []},
    'clf': {'accuracy': [], 'precision': [], 'recall': [], 'f1': [], 'auc': []}
}

# 交叉验证过程
for train_index, test_index in skfolds.split(X, y):
    X_train, X_test = X.iloc[train_index], X.iloc[test_index]
    y_train, y_test = y.iloc[train_index], y.iloc[test_index]
    
    # 随机过采样
    ros = RandomOverSampler(random_state=42)
    X_resampled, y_resampled = ros.fit_resample(X_train, y_train)
    
    # 逻辑回归模型训练和评估
    lg.fit(X_resampled, y_resampled)
    y_pred1 = lg.predict(X_test)
    y_score1 = lg.predict_proba(X_test)[:, 1]
    fpr1, tpr1, _ = metrics.roc_curve(y_test, y_score1)
    roc_auc1 = metrics.auc(fpr1, tpr1)
    
    performance_scores['lg']['accuracy'].append(accuracy_score(y_test, y_pred1))
    performance_scores['lg']['precision'].append(precision_score(y_test, y_pred1))
    performance_scores['lg']['recall'].append(recall_score(y_test, y_pred1))
    performance_scores['lg']['f1'].append(f1_score(y_test, y_pred1))
    performance_scores['lg']['auc'].append(roc_auc1)
    
    # 随机森林模型训练和评估
    rf.fit(X_resampled, y_resampled)
    y_pred2 = rf.predict(X_test)
    y_score2 = rf.predict_proba(X_test)[:, 1]
    fpr2, tpr2, _ = metrics.roc_curve(y_test, y_score2)
    roc_auc2 = metrics.auc(fpr2, tpr2)
    
    performance_scores['rf']['accuracy'].append(accuracy_score(y_test, y_pred2))
    performance_scores['rf']['precision'].append(precision_score(y_test, y_pred2))
    performance_scores['rf']['recall'].append(recall_score(y_test, y_pred2))
    performance_scores['rf']['f1'].append(f1_score(y_test, y_pred2))
    performance_scores['rf']['auc'].append(roc_auc2)
    
    # 决策树模型训练和评估
    clf.fit(X_resampled, y_resampled)
    y_pred3 = clf.predict(X_test)
    y_score3 = clf.predict_proba(X_test)[:, 1]
    fpr3, tpr3, _ = metrics.roc_curve(y_test, y_score3)
    roc_auc3 = metrics.auc(fpr3, tpr3)
    
    performance_scores['clf']['accuracy'].append(accuracy_score(y_test, y_pred3))
    performance_scores['clf']['precision'].append(precision_score(y_test, y_pred3))
    performance_scores['clf']['recall'].append(recall_score(y_test, y_pred3))
    performance_scores['clf']['f1'].append(f1_score(y_test, y_pred3))
    performance_scores['clf']['auc'].append(roc_auc3)

# 进行Nemenyi检验
for metric in performance_scores['lg']:
    # 将两个模型的该性能指标得分转换为数组
    scores_lg = np.array(performance_scores['lg'][metric])
    scores_rf = np.array(performance_scores['rf'][metric])
    scores_clf = np.array(performance_scores['clf'][metric])
    
    # 执行Friedman检验
    # 将数据存储在numpy数组中
    df = np.array([scores_lg, scores_rf, scores_clf])

    # 进行Friedman检验
    friedman_stat, p_value = friedmanchisquare(*df)

print("Friedman检验统计量:", friedman_stat)
print("Friedman检验P值:", p_value)

    
    # 如果Friedman检验显著,执行Nemenyi后验检验
    if p < 0.05:
        data = np.array([scores_lg, scores_rf, scores_clf])
        nemenyi_results = posthoc_nemenyi(data.T)
        print("Nemenyi后验检验结果:")
        print(nemenyi_results)
    else:
        print("Friedman检验结果不显著,无需进行Nemenyi后验检验")

# 如果Friedman检验显著,执行Nemenyi后验检验
results =sp.posthoc_nemenyi_friedman (df.T )
print(results)

检验结果:

img


lg模型性能:

img


rf模型性能:

img


clf模型性能:

img

  • 写回答

5条回答 默认 最新

  • 专家-皆知 2024-04-30 16:57
    关注

    参考免费微信小程序:皆我百晓生 作答,经由专家-皆知整理回复,如问题解决,望采纳;如仍有疑问,请评论回复。

    根据您提供的信息,您的目标是对三种分类器(逻辑回归lg、随机森林rf、决策树clf)的性能进行Nemenyi检验。首先,让我们纠正并补充您代码中的一些问题和遗漏部分,这可能解释了为何您的检验结果与预期不符。

    1. Friedman检验后的条件判断错误:您在代码中没有正确设置p_value变量用于判断是否进行Nemenyi检验。正确的做法是在进行Friedman检验后立即定义p_value

    2. 调用Nemenyi检验的库函数错误:您使用了sp.posthoc_nemenyi_friedman(df.T),但没有导入正确的库或函数。通常,使用scipy.stats中的Friedman检验,但Nemenyi后验检验需要借助其他包,比如statsmodels.stats.multitest或特定的函数实现,但标准库中没有直接提供Nemenyi检验。您可能需要自定义Nemenyi检验的计算或使用第三方实现。

    3. 性能指标的选择:Nemenyi检验适用于多个模型的比较,您需要确保使用的性能指标是一致且合适的。您展示的最终结果似乎与中间过程不匹配,未直接展示Nemenyi检验的结果细节,但提到了不一致的性能表现。

    下面是一个修正后的示例代码框架,注意,由于Python标准库不直接提供Nemenyi检验的函数,您可能需要使用或实现额外的逻辑来完成Nemenyi检验部分。这里仅提供修正Friedman检验部分的代码,并说明如何准备进行Nemenyi检验的逻辑。

    from scipy.stats import friedmanchisquare
    import numpy as np
    
    # 假设这是您的性能分数收集部分,已省略
    
    # 进行Friedman检验
    for metric in performance_scores['lg']:
        scores_lg = np.array(performance_scores['lg'][metric])
        scores_rf = np.array(performance_scores['rf'][metric])
        scores_clf = np.array(performance_scores['clf'][metric])
        df = np.array([scores_lg, scores_rf, scores_clf])
    
        friedman_stat, p_value = friedmanchisquare(*df)
        print(f"Friedman检验统计量 for {metric}: {friedman_stat}")
        print(f"Friedman检验P值 for {metric}: {p_value}")
    
        # 正确判断进行Nemenyi检验的条件
        if p_value < 0.05:
            # 注意:这里需要您自己实现或找到Nemenyi检验的代码,以下为概念说明
            # nemenyi_results = perform_nemenyi_test(scores_lg, scores_rf, scores_clf)  # 假设函数存在
            # print("Nemenyi后验检验结果:", nemenyi_results)
            # 实际应用中,您需要实现或引用一个能执行Nemenyi检验的函数
            pass
        else:
            print(f"对于{metric},Friedman检验结果不显著,无需进行Nemenyi后验检验")
    

    对于Nemenyi检验的具体实现,您可能需要查找或开发一个适合您需求的实现方式,因为标准库并不包含这个检验。此外,确保您收集的性能指标在统计上是可靠的,且样本量足够进行这样的假设检验。如果您需要Nemenyi检验的详细实现逻辑,可能需要查阅相关的统计学文献或寻找社区中分享的实现代码。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 4月30日

悬赏问题

  • ¥15 路由器考试怎么办,有懂行的吗 ,eNSP
  • ¥20 前端 二进制文件流图片转化异常
  • ¥15 github上的这个C语言项目如何跑起来
  • ¥15 java 判断某个数 区间是否存在
  • ¥15 appium控制多个雷电模拟器问题
  • ¥15 C# iMobileDevice
  • ¥15 谁会做这个啊#ensp#Boson NetSim
  • ¥15 如何编写针对TPS6503320FRGE型号的电源管理芯片的编程代码?
  • ¥15 设计简单目录管理系统,要满足以下内容
  • ¥15 关于九十度混合耦合器信号分析问题