news 2026/4/7 7:46:08

深度学习中的McNemar检验

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深度学习中的McNemar检验

在深度学习模型中,McNemar检验(McNemar's Test,麦克尼马尔检验)是检验不同的深度学习分类器模型(准确率)或回归模型(命中率)在相同测试数据上性能是否存在显著差异的统计检验方法

McNemar检验基于两个模型预测结果的2x2列联表(contingency table),如下图所示:

1. 列联表:是对两个分类或回归变量进行列表或计数。列联表的依据是两个分类模型或回归模型均使用完全相同的训练数据进行训练,并使用完全相同的测试数据进行评估

2.McNemar检验仅关注两个条件存在差异的单元格:McNemar仅关心n01和n10。n00:模型A和模型B均未命中的样本数。n11:模型A和模型B均命中的样本数。n01:模型A未命中,但模型B命中的样本数。n10:模型A命中,但模型B未命中的样本数。

3. 判断逻辑:如果n01约等于n10:两模型差异可能是随机的。如果n01 >> n10:模型B显著优于模型A。如果n01 << n10:模型A显著优于模型B。

4. 卡方分布表(chi-square distribution table),如下图所示:

5. 公式:推荐使用连续性校正

(1).原始公式(未校正):10 <= n01 + n10 < 25,服从自由度df=1(或χ²(1))的卡方分布

(2).连续性校正(Yates)公式:n01 + n10 >= 25,服从自由度df=1(或χ²(1))的卡方分布

(3).精确检验:n01 + n10 < 10,scipy.stats.binomtest

6. 判断标准,计算pvalue得结论:

(1).pvalue < 0.05:两个模型有显著差异。

(2).pvalue >= 0.05:两个模型差异不显著。

以下测试代码是用McNemar检验两个回归模型是否有显著差异:

def parse_args(): parser = argparse.ArgumentParser(description="mcnemar test") parser.add_argument("--src_file", required=True, type=str, help="src file name") parser.add_argument("--src_file2", required=True, type=str, help="src file name") parser.add_argument("--threshold", type=float, default=0.5, help="error margin") args = parser.parse_args() return args def mcnemar_test(src_file, src_file2, threshold): if src_file is None or not src_file or not Path(src_file).is_file(): raise ValueError(colorama.Fore.RED + f"{src_file} is not a file") if src_file2 is None or not src_file2 or not Path(src_file2).is_file(): raise ValueError(colorama.Fore.RED + f"{src_file2} is not a file") def parse_csv(file): with open(file, "r", encoding="utf-8") as f: reader = csv.reader(f) all_rows = list(reader) data = all_rows[1:-1] # remove the first and last rows return data data1 = parse_csv(src_file) data2 = parse_csv(src_file2) if len(data1) != len(data2): raise ValueError(colorama.Fore.RED + f"length mismath: {src_file}:{len(data1)}, {src_file2}:{len(data2)}") print(f"number of data rows: {len(data1)}") is_same = all(row1[0] == row2[0] for row1, row2 in zip(data1, data2)) if not is_same: raise ValueError(colorama.Fore.RED + f"image name mismatch: {src_file}, {src_file2}") n11 = 0; n10 = 0; n01 = 0; n00 = 0 for i in range(len(data1)): value1 = abs(float(data1[i][1]) - float(data1[i][2])) value2 = abs(float(data2[i][1]) - float(data2[i][2])) if value1 <= threshold and value2 <= threshold: n11 += 1 elif value1 > threshold and value2 > threshold: n00 += 1 elif value1 <= threshold and value2 > threshold: n10 += 1 elif value1 > threshold and value2 <= threshold: n01 += 1 else: raise ValueError(colorama.Fore.RED + f"unsupported conditions: value: {value1}, {value2}") print(f"n11: {n11}; n10: {n10}; n01: {n01}; n00: {n00}") if n10 + n01 == 0: print(colorama.Fore.YELLOW + "unable to test differences") return def calculate_pvalue(n10, n01, method): # method: 0:Yates; 1:original; 2:exact binomial test if method == 0: stat = (abs(n01 - n10) - 1) ** 2 / (n10 + n01) return chi2.sf(stat, df=1) elif method == 1: stat = (n01 - n10) ** 2 / (n10 + n01) return chi2.sf(stat, df=1) else: return binomtest(k=min(n10, n01), n=n10+n01, p=0.5, alternative="two-sided").pvalue if n10 + n01 >= 25: pvalue = calculate_pvalue(n10, n01, 0) elif 10 <= n10 + n01 < 25: pvalue = calculate_pvalue(n10, n01, 1) else: pvalue = calculate_pvalue(n10, n01, 2) if pvalue < 0.05: print(colorama.Fore.GREEN + f"pvalue: {pvalue:.4f}, the two models show a significant difference") else: print(colorama.Fore.YELLOW + f"pvalue: {pvalue:.4f}, the two models no not show a significant difference") if __name__ == "__main__": colorama.init(autoreset=True) args = parse_args() mcnemar_test(args.src_file, args.src_file2, args.threshold) print(colorama.Fore.GREEN + "====== execution completed ======")

执行结果如下图所示:

GitHub:https://github.com/fengbingchun/NN_Test

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/3 22:05:44

军储库区空间结构透视与人车作业态势一体化感知技术方案

军储库区空间结构透视与人车作业态势一体化感知技术方案摘要军需仓储库区作为高价值物资集中存储与高频作业的重要基础设施&#xff0c;对作业安全性、过程合规性及事后可追溯性具有极高要求。然而&#xff0c;传统基于二维视频画面的监控方式&#xff0c;难以真实反映人员与车…

作者头像 李华
网站建设 2026/4/3 1:42:49

透明物体渲染的步骤(大白话生动版:你以为是“画一下”,其实是“排队、算账、再排队”)

透明物体渲染这件事,表面看起来很简单:不就是玻璃、水、烟、火、UI、半透明布料嘛。 但做过的人都知道:透明一多,画面就开始“玄学”—— 玻璃前后顺序一乱,就像贴纸叠错了; 粒子一多,GPU 直接变“暖手宝”; 深度一开一关,边缘不是穿帮就是发灰; 折射、反射、雾、后处…

作者头像 李华
网站建设 2026/4/3 14:43:19

提示工程的容器编排技巧:优化提示响应时间的5个方法

提示工程的容器编排技巧&#xff1a;优化提示响应时间的5个方法 一、引入与连接 引人入胜的开场 想象一下&#xff0c;你是一家电商公司的客服主管&#xff0c;每天要处理成千上万条客户的咨询信息。客户们都希望能在最短的时间内得到准确的回复&#xff0c;就像你在饥饿时渴望…

作者头像 李华
网站建设 2026/3/25 5:59:04

2026-02-08 全国各地响应最快的 BT Tracker 服务器(联通版)

数据来源&#xff1a;https://bt.me88.top 序号Tracker 服务器地域网络响应(毫秒)1http://60.249.37.20:6969/announce广东肇庆联通282http://211.75.205.187:6969/announce广东肇庆联通293http://211.75.205.188:80/announce广西柳州联通334http://180.114.103.80:6969/annou…

作者头像 李华
网站建设 2026/3/25 12:21:49

基于Spark的豆瓣读书分析大屏可视化(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

基于Spark的豆瓣读书分析大屏可视化(设计源文件万字报告讲解)&#xff08;支持资料、图片参考_相关定制&#xff09;_文章底部可以扫码数据采集&#xff1a;豆瓣读书网站爬虫(requests、lxml、…) 数据存储&#xff1a;将爬取的数据保存为csv文件&#xff0c;保存到本地或上传到…

作者头像 李华
网站建设 2026/4/3 5:06:08

CentOS7高效部署WebRTC信令服务器:从选型到性能调优实战

背景痛点&#xff1a;CentOS7部署WebRTC信令的“拦路虎” 在实时音视频应用开发中&#xff0c;WebRTC负责端到端的媒体传输&#xff0c;而信令服务器则是整个通信的“交通指挥中心”&#xff0c;负责协商建立连接。然而&#xff0c;在经典的CentOS 7服务器上部署一个高性能、稳…

作者头像 李华