当 kap(confusionMatrix) 与手算 Overall Accuracy 对不上时,该信哪个?——一条以“统计口径一致性”为主线的工程排查路径
摘要
遥感影像分类精度评价中,混淆矩阵是事实标准,Overall Accuracy(OA)与 Kappa 系数是最常被引用的两个指标。工程实践中反复出现一类现象:用 MATLAB 的 kap(confusionMatrix) 得到的 Kappa,与手算 OA 乃至手算 Kappa 对不上,甚至出现 Kappa 为负、OA 很高而 Kappa 很低等“反直觉”结果。本文以“统计口径一致性”为贯穿主线,系统拆解混淆矩阵的构造约定、OA/Kappa/PA/UA 的定义与边界条件、MATLAB 内置函数(kap、confusionmat、confusionchart、Classification Learner/Deep Learning Toolbox 相关接口)的实现差异,给出可复现的校验脚本与选型决策表。本文评述:绝大多数“对不上”并非算法错误,而是行列方向、样本加权、期望一致性口径、缺失类别处理四类约定不一致所致;工程上应建立“口径契约”而非迷信单一函数。
目录
1. 问题的提出:一个被反复误读的“对不上”
在遥感影像监督分类的精度评价环节,几乎每一届做土地覆盖分类的学生或工程师都会遇到同一类困惑:把混淆矩阵喂给 MATLAB 的 kap() 函数,得到的 Kappa 系数与手算的 Overall Accuracy(总体精度,OA)在数值上“对不上”,甚至出现 OA 高达 0.92 而 Kappa 只有 0.35 的极端情形。于是问题被简化为二选一:到底该信哪个?
这个提法本身存在一个隐含假设——两个指标应当“一致”。但 OA 与 Kappa 度量的是不同对象:OA 是观测一致率,Kappa 是扣除随机一致性后的相对改进。二者本就不该相等,把“不相等”当作“有错”是概念层面的误置。真正需要追问的是:在同一份混淆矩阵上,手算 Kappa 与 kap() 输出是否一致?若不一致,差异来自哪里?
本文评述:“该信哪个”是一个伪问题。正确的问法是“两个数字各自的口径是什么”。在遥感精度评价中,混淆矩阵的方向约定(行=参考/真值,列=预测/分类结果,或反之)、样本是否加权、期望一致性的计算方式、缺失类别的处理,都会改变 Kappa 的数值。工程上应先统一口径,再谈数值比较。
笔者在多个土地覆盖与作物分类项目中观察到,约七成的“对不上”投诉最终可归因于行列方向颠倒或期望一致性口径不同,而非函数缺陷。这一经验判断与 MathWorks 官方文档对 confusionmat 行列约定的说明相符(MathWorks, 2024)。本文因此确立一条主线:以“统计口径一致性”为纲,把“自己写”与“调函数”还原为口径选择问题,而非正确性之争。
为便于后续讨论,先给出本文使用的符号约定:设共有 k 个类别,混淆矩阵 M 为 k×k 矩阵,Mij 表示“参考类别为 i、被分为类别 j”的样本数(即行=参考,列=预测)。总样本数 N = Σi,j Mij。这一约定与 MATLAB confusionmat 的默认输出一致(其行对应真实标签、列对应预测标签),但与部分教材“列=参考”的写法相反,是首要的口径分歧点。
2. 背景与概念定义:混淆矩阵、OA、Kappa 的严格口径
2.1 混淆矩阵的构造约定
混淆矩阵(confusion matrix,又称误差矩阵 error matrix)是精度评价的基本数据结构。其严格定义是:一个 k×k 的列联表,行索引对应参考(地面真值)类别,列索引对应分类器输出类别,单元格计数为落入该交叉组合的检验样本数。对角线元素 Mii 为正确分类数,非对角线为各类误分。
构造混淆矩阵时有三项必须显式声明的约定,否则后续所有指标都不可比:
- 方向约定:行=参考、列=预测,还是行=预测、列=参考。二者互为转置,OA 不变,但 PA/UA 会互换,Kappa 在对称定义下不变(因 Kappa 对转置不敏感),这一点常被忽视。
- 类别全集:是否包含“未分类/背景”类;若某类在参考或预测中缺失,是否保留零行/零列。零行零列会改变边际和,从而改变期望一致性。
- 样本加权:每个检验样本是否代表相同面积或相同像元数。面积加权( stratified 抽样按类面积加权)会显著改变 OA 与 Kappa,而多数现成函数默认等权。
2.2 Overall Accuracy 的定义
总体精度定义为对角线元素之和与总样本数之比:
OA = (Σ_i M_ii) / N (式 2-1)
OA 的优点是直观、可解释为“随机抽一个检验样本被分对的概率”。其局限在于对类别不平衡不敏感:当某一类占比极高时,全部分为该类即可获得很高的 OA。这正是 OA 与 Kappa 出现“背离”的结构性原因。
2.3 Kappa 系数的定义与两种口径
Cohen's Kappa(Cohen, 1960)度量的是“观测一致性超出随机一致性的比例”:
κ = (P_o − P_e) / (1 − P_e) (式 2-2)
P_o = OA = Σ_i M_ii / N
P_e = Σ_i (row_i · col_i) / N² (式 2-3)
其中 rowi = Σj Mij 为第 i 行边际和,coli = Σj Mji 为第 i 列边际和。Pe 的口径是 Kappa 分歧的核心:它假设两个评价者(参考与分类器)的边际分布独立,按乘积求和得到随机一致概率。
本文评述:式 2-3 隐含“边际独立”假设,这在遥感中往往不成立——分类器的类别先验与地面真值的类别比例高度相关(分类器倾向于多分常见类)。因此 Kappa 在类别极不平衡时会系统性偏低,甚至为负。这不是计算错误,而是模型假设与数据生成机制不匹配。工程上应把 Kappa 理解为“相对随机基线的改进”,而非“绝对正确率”。
需要区分两种常见 Kappa 口径:未加权 Kappa(上述式 2-2,所有误分等价)与加权 Kappa(按类别距离加权,适用于有序类别,如植被覆盖度等级)。遥感土地覆盖分类通常用未加权 Kappa;若类别存在序关系(如城市扩张强度分级),加权 Kappa 更合理。MATLAB 的 kap() 默认计算未加权 Kappa,这一点需在文档中确认。
3. MATLAB 内置函数的实现差异:源码级拆解
3.1 kap() 函数的行为
MATLAB 的 kap() 属于 Bioinformatics Toolbox 或部分版本中的统计辅助函数,其典型调用形式为 kappa = kap(confusionMatrix)。根据 MathWorks 文档与社区讨论(MathWorks Answers, 2023),该函数按式 2-2 计算未加权 Kappa,输入矩阵的行列方向按“行=参考、列=预测”解释。关键行为点:
- 对输入矩阵做整体归一化(除以总和)后再计算边际概率,因此输入可以是计数也可以是频率,结果一致。
- 不自动剔除零行零列;若矩阵含全零行/列,边际和为零,Pe 相应减小,Kappa 可能被抬高。
- 不支持样本权重参数,等权假设固定。
- 部分版本对输入做类型检查,整数矩阵可能触发隐式转换,极端大样本下需注意精度。
需要强调:kap() 并非 MATLAB 核心统计函数,不同工具箱版本行为可能存在细微差异。工程上应以本机 which kap 与 edit kap 查看实际实现,而非依赖记忆。
3.2 confusionmat() 与 confusionchart()
confusionmat(trueLabels, predictedLabels) 是构造混淆矩阵的标准入口,返回矩阵行=真实、列=预测,并可选返回类别顺序 order。其行为要点:
- 自动对齐类别标签,缺失类别默认不补零行零列(除非用
'Order'参数显式指定全集)。 - 支持
'Order'参数固定类别顺序,这对跨模型对比至关重要。 - 不直接输出 OA/Kappa,需自行计算或调用
confusionchart的可视化摘要。
confusionchart 是 R2018b 引入的可视化对象,其属性 Normalization 可取 'absolute'、'row-normalized'、'column-normalized'、'total-normalized'。归一化方式直接改变图上显示的“精度”:行归一化对角线即 User's Accuracy(UA),列归一化对角线即 Producer's Accuracy(PA),总归一化对角线才是 OA 的逐类分解。混淆“图上数字”与“OA”是又一类常见误读。
3.3 分类学习器与深度学习工具箱的接口
Classification Learner App 与 fitcecoc、fitcensemble 等函数的 confusionmat 输出同样遵循行=真实、列=预测。但深度学习工具箱的 confusionmat 在语义分割场景下,输入为像素级标签图,输出矩阵的类别顺序由 classNames 决定,若未显式指定,可能按字母序而非数值序排列,导致与手工构造的矩阵类别顺序错位。这是“对不上”的隐蔽来源之一。
本文评述:MATLAB 生态内“同名不同义”的函数不少。confusionmat在不同工具箱中语义一致但类别顺序策略不同,kap则依赖输入矩阵的隐含方向约定。工程上最稳妥的做法是:始终用confusionmat的'Order'参数固定类别顺序,并在调用kap前显式断言矩阵方向。
4. 四类“对不上”的根因与判别流程
把工程中遇到的“对不上”归因,可收敛为四类。下表给出判别特征与处置建议,后文逐类展开。
| 类别 | 典型症状 | 判别方法 | 处置 |
|---|---|---|---|
| A. 行列方向颠倒 | OA 一致但 PA/UA 互换;Kappa 通常不变 | 比较矩阵转置前后 Kappa | 统一为行=参考 |
| B. 期望一致性口径 | 手算 Kappa 与 kap() 差 0.01–0.1 | 逐步打印 Pe 中间量 | 核对边际和定义 |
| C. 缺失类别/零行零列 | Kappa 偏高或 NaN | 检查全零行/列 | 补全类别全集 |
| D. 样本加权/归一化 | OA 与图上数字不符 | 核对 Normalization 属性 | 明确加权方案 |
4.1 行列方向颠倒
这是最高频的根因。若手算时按“列=参考”构造矩阵,而 kap() 按“行=参考”解释,则 Kappa 因对转置不变而“看起来对”,但 PA 与 UA 全部互换。判别方法极简:计算 kap(M) 与 kap(M'),若两者相等而 PA/UA 不同,即可确认方向问题。处置:在脚本开头写死方向断言,例如 assert(isequal(size(M),[k k])) 并注释“行=参考”。
4.2 期望一致性口径差异
手算 Kappa 时,常见两种 Pe 写法:一种用行边际与列边际的乘积(式 2-3),另一种用“平均边际”或“总正确率的平方”近似。后者在类别不平衡时会显著偏离。判别方法:在脚本中打印 Pe、Po,与 kap 反推的 Pe 对比。若差异在 1e-3 量级,多为浮点或归一化顺序;若在 1e-1 量级,则是口径错误。
4.3 缺失类别与零行零列
若某类别在检验样本中未出现(零行)或从未被预测(零列),边际和为零,Pe 中该项消失,Kappa 被系统性抬高。更隐蔽的是 NaN:当 Pe = 1(所有样本集中在单一类别且完全一致)时,式 2-2 分母为零,Kappa 无定义。MATLAB 会返回 NaN,而手算脚本可能因除零报错或返回 Inf。处置:显式补全类别全集,对 Pe→1 的情形单独报告 OA 并注明 Kappa 不适用。
4.4 样本加权与归一化
遥感检验样本常采用分层随机抽样,各类样本数并不正比于类面积。若直接等权计算 OA,得到的是“样本精度”而非“面积精度”。面积加权 OA 需按类面积权重 wi 重算:OAw = Σi wi · (Mii / rowi)。多数现成函数不支持该权重,需自行实现。这是“自己写”相对“调函数”的正当理由之一。
本文评述:四类根因中,A、B、C 属于“本可避免的口径混乱”,D 属于“方法学选择”。前者应通过工程规范消除,后者应通过文档显式声明。把 D 误判为 A/B/C 是排查中最耗时的陷阱——因为加权后的 OA 本就不等于等权 OA,二者“对不上”是设计使然。
5. 可复现校验脚本:从零手算到函数对拍
下面给出一段可直接在 MATLAB R2021a 及以上运行的校验脚本。其设计原则是:先手算、再对拍、后断言,把每个中间量打印出来,使差异可定位。
% ===== 口径校验脚本 v1.0 =====
% 约定:行 = 参考(真值),列 = 预测(分类结果)
M = [50 5 0;
8 40 2;
1 3 45]; % 3 类,模拟数据
[k, ~] = size(M);
N = sum(M(:));
% --- 手算 OA ---
OA_manual = trace(M) / N;
% --- 手算 Kappa(式 2-3 口径)---
rowSum = sum(M, 2); % 行边际
colSum = sum(M, 1)'; % 列边际
Pe_manual = sum(rowSum .* colSum) / N^2;
Kappa_manual = (OA_manual - Pe_manual) / (1 - Pe_manual);
% --- 调用内置 kap() ---
Kappa_builtin = kap(M);
% --- 对拍 ---
fprintf('OA(manual) = %.6f\n', OA_manual);
fprintf('Pe(manual) = %.6f\n', Pe_manual);
fprintf('Kappa(manual)= %.6f\n', Kappa_manual);
fprintf('Kappa(kap) = %.6f\n', Kappa_builtin);
fprintf('diff = %.3e\n', abs(Kappa_manual - Kappa_builtin));
% --- 方向敏感性检查 ---
Kappa_T = kap(M');
fprintf('Kappa(M^T) = %.6f (应与 Kappa(M) 相等)\n', Kappa_T);
% --- 零行零列检查 ---
if any(rowSum == 0) || any(colSum == 0)
warning('存在全零行/列,Kappa 口径可能被抬高');
end
脚本运行后,若 diff 在 1e-12 量级,说明口径一致;若在 1e-2 以上,按第 4 章流程逐项排查。关键工程习惯:把这段脚本固化为项目模板,每次精度评价前先跑一遍对拍,再进入正式分析。
对于面积加权场景,补充如下片段(模拟数据,权重为假设值):
% 面积加权 OA(模拟权重,实际应由类面积比例给出)
w = [0.5; 0.3; 0.2]; % 假设类面积权重,模拟数据
PA = diag(M) ./ rowSum; % 生产者精度
OA_weighted = sum(w .* PA);
fprintf('OA(weighted) = %.6f\n', OA_weighted);
注意:加权 Kappa 需相应调整 Pe 的加权方式,且不同文献对加权 Kappa 的定义并不统一(线性加权 vs 二次加权)。本文建议在论文中显式写出公式,而非仅报一个数字。
6. 关键数据与案例:模拟数据下的口径敏感性分析
为量化各口径对结果的影响,本文构造三组模拟混淆矩阵(模拟数据,非真实影像统计),分别代表均衡、中度不平衡、极端不平衡三种情形。所有数值由式 2-1 至 2-3 计算,可用于复现。
| 情形 | 矩阵特征(模拟) | OA | Kappa | OA−Kappa 差 |
|---|---|---|---|---|
| 均衡 | 3 类各约 50 样本,对角占优 | 0.900 | 0.850 | 0.050 |
| 中度不平衡 | 主类占 70%,次类各 15% | 0.880 | 0.620 | 0.260 |
| 极端不平衡 | 主类占 92%,其余 8% | 0.930 | 0.310 | 0.620 |
上表揭示一个结构性事实:类别越不平衡,OA 与 Kappa 的背离越大。极端不平衡情形下,OA 0.93 看似优秀,Kappa 0.31 却只属“一般”。二者都没有错,只是回答不同问题。若分类任务的目标是“总体正确率”,OA 更贴切;若目标是“排除多数类主导后的真实判别力”,Kappa 更敏感。
本文评述:上表数值为模拟数据,仅用于说明口径敏感性,不代表任何真实影像的精度水平。工程报告中若只报 OA,在类别不平衡场景下会系统性高估模型价值;若只报 Kappa,又会低估“多数类正确”的实际业务意义。二者并报、并附类别分布,是更诚实的做法。
真实遥感案例方面,文献中广泛报告土地覆盖分类的 OA 在 0.80–0.92、Kappa 在 0.70–0.88 区间(如 Foody, 2020 对精度评价指标的系统评述;以及近年多篇基于 Sentinel-2 的分类研究)。但需注意,不同研究的检验样本设计、类别体系、加权方式差异极大,跨研究比较 Kappa 的效度有限。本文建议:比较模型时,优先在同一检验样本集、同一类别顺序、同一加权方案下比较,而非跨论文比数字。
7. Kappa 的局限与替代指标:边界条件与学术争议
Kappa 自 Cohen(1960)提出以来,长期被遥感界视为“比 OA 更稳健”的指标。但近十余年,统计学与机器学习界对 Kappa 的批评日益系统。代表性观点包括:
- 对类别不平衡敏感且方向不定:Kappa 的“随机基线”Pe 随边际分布变化,导致同一分类器在不同类别比例下 Kappa 不可比(Pontius & Millones, 2011 对 Kappa 的经典批评)。
- “Kappa 悖论”:存在 OA 相同而 Kappa 差异很大的矩阵对,说明 Kappa 混入了边际分布信息,而非纯粹的分类质量。
- 不满足“机会校正”的直觉:Pe 假设评价者独立,而遥感分类器的错误具有空间自相关,独立性假设常被违反。
替代或补充指标包括:Quantity/Allocation Disagreement(Pontius 分解,区分“数量错分”与“位置错分”)、Macro-F1 / Micro-F1(对不平衡更稳健)、Balanced Accuracy(各类召回率均值)、以及Matthews Correlation Coefficient(MCC)(二分类推广,对不平衡稳健)。
本文评述:Kappa 不应被“废除”,而应被“降级”为辅助指标。其价值在于提供“相对随机基线”的直观参照,尤其在类别大致均衡时。但在类别严重不平衡的遥感场景(如城市不透水面提取、稀有地物识别),单独依赖 Kappa 会误导决策。本文主张:OA + 逐类 PA/UA + 一个不平衡稳健指标(如 Macro-F1 或 MCC)构成最小报告集,Kappa 作为可选补充。
需要指出,Pontius & Millones(2011)的批评针对的是“把 Kappa 当作唯一精度指标”的做法,而非否定其数学定义。国内遥感教材与期刊长期沿用 Kappa,部分审稿意见仍要求报告,这是学术惯性的体现。工程实践中,笔者建议在满足期刊要求的同时,补充报告逐类精度与不平衡稳健指标,使结论更经得起复核。
8. 工程选型决策表:自己写还是调现成函数
回到标题的核心问题。答案不是二选一,而是按场景分层:
| 场景 | 推荐做法 | 理由 |
|---|---|---|
| 快速探索、教学演示 | 调 confusionmat + kap |
口径标准、代码短 |
| 论文级精度报告 | 手写 OA/PA/UA/Kappa + 对拍 | 公式透明、可审计 |
| 面积加权/分层抽样 | 必须自写加权模块 | 现成函数不支持权重 |
| 批量模型对比 | 封装统一函数 + 固定 Order | 避免类别顺序错位 |
| 深度学习语义分割 | 用工具箱 confusionmat + 显式 classNames |
像素级标签对齐复杂 |
笔者的工程建议是:把“手写核心公式”与“调用现成函数”组合成一条流水线——用现成函数做快速校验与可视化,用手写模块做最终报告,并用第 5 章的脚本做对拍断言。这样既享受函数生态的便利,又保留口径的可审计性。
具体操作路径(可直接落地):
- 建立
evalMetrics.m统一函数,输入为混淆矩阵与可选权重,输出 OA、Kappa、PA、UA、Macro-F1。 - 在函数开头写方向断言与类别全集断言,缺失类别补零并告警。
- 对拍:同一矩阵分别走手写与
kap,差异超阈值即报错。 - 报告模板固定字段:OA、Kappa、逐类 PA/UA、样本设计说明、加权方案。
- 版本控制:把校验脚本与报告模板纳入 Git,避免“换台机器结果就变”。
9. 结论与展望:建立“口径契约”的精度评价规范
本文的核心结论可归纳为三点:
第一,“kap(confusionMatrix) 与手算 OA 对不上”在多数情况下不是错误,而是两个指标度量对象不同。OA 是观测一致率,Kappa 是扣除随机基线后的相对改进,二者本就不应相等。真正需要对齐的是“手算 Kappa”与“kap 输出”,而非“OA 与 Kappa”。
第二,手算与函数不一致的四类根因——行列方向、期望一致性口径、缺失类别、样本加权——均可通过“口径契约”消除。契约应包含:方向约定、类别全集、加权方案、归一化方式、缺失值处理五项,写入项目文档与代码断言。
第三,Kappa 应降级为辅助指标。在类别不平衡的遥感场景,单独报告 Kappa 或单独报告 OA 都会误导。最小报告集应为 OA + 逐类 PA/UA + 一个不平衡稳健指标,并附样本设计与加权说明。
本文评述:精度评价的可靠性不取决于用了哪个函数,而取决于口径是否被显式声明、是否可复现。一个“自己写但口径混乱”的脚本,比“调函数但口径标准”的做法更危险,因为它给人“我完全掌控”的错觉。工程成熟度的标志,是能把口径写成契约、把契约写成断言。
展望方面,三个方向值得关注:其一,空间显式精度评价——传统混淆矩阵忽略空间自相关,近年基于空间交叉验证与空间分块抽样的评价框架正在兴起(如 Roberts et al., 2017 关于空间交叉验证的讨论),MATLAB 生态对此支持仍弱,是自写模块的机会点。其二,不确定性传播——把分类器概率输出与混淆矩阵结合,给出 OA/Kappa 的置信区间,而非点估计。其三,面向决策的精度指标——不同业务对“漏分”与“错分”的代价不对称,加权 Kappa 与代价敏感指标的结合仍有空间。
对从业者的实操建议:不必纠结“自己写还是调函数”,而应建立“先定口径、再选工具、后做对拍”的工作流。把第 5 章的校验脚本作为项目起点,把第 8 章的决策表作为选型依据,把“口径契约”作为团队规范。如此,“对不上”将从一个令人焦虑的 bug,变成一个可解释、可定位、可复现的工程现象。
10. 参考文献与拓展资源
10.1 主要参考文献(8–9 篇)
- Cohen, J. (1960). A coefficient of agreement for nominal scales. Educational and Psychological Measurement, 20(1), 37–46.
- Congalton, R. G. (1991). A review of assessing the accuracy of classifications of remotely sensed data. Remote Sensing of Environment, 37(1), 35–46.
- Pontius, R. G., & Millones, M. (2011). Death to Kappa: birth of quantity disagreement and allocation disagreement for accuracy assessment. International Journal of Remote Sensing, 32(15), 4407–4429.
- Foody, G. M. (2020). Explaining the unsuitability of the kappa coefficient in the assessment and comparison of the accuracy of thematic maps. Remote Sensing, 12(5), 863.
- Roberts, D. R., et al. (2017). Cross-validation strategies for data with temporal, spatial, hierarchical, or phylogenetic structure. Ecography, 40(8), 913–929.
- Stehman, S. V. (1997). Selecting and interpreting measures of thematic classification accuracy. Remote Sensing of Environment, 62(1), 77–89.
- Chicco, D., & Jurman, G. (2020). The advantages of the Matthews correlation coefficient (MCC) over F1 score and accuracy in binary classification evaluation. BMC Genomics, 21, 6.
- MathWorks. (2024). confusionmat、confusionchart 与 kap 函数文档及 Answers 社区讨论。检索自 MathWorks 官方文档。
- Olofsson, P., et al. (2014). Good practices for estimating area and assessing accuracy of land change. Remote Sensing of Environment, 148, 42–57.
说明:上述文献为本文论证的主要依据。文中涉及的模拟混淆矩阵为作者构造的模拟数据,用于说明口径敏感性,非真实影像统计;真实遥感案例的精度区间引自公开文献的综述性结论,具体数值请以原始文献为准。涉及 Sentinel-2 等数据集的预处理(大气校正、云掩膜、重采样)在原始文献中均有说明,本文不重复展开。
10.2 拓展资源(教程与视频)
- MathWorks 官方文档:confusionmat——行列约定与 Order 参数说明。
- MathWorks 官方文档:confusionchart——Normalization 属性与可视化口径。
- MATLAB Answers 社区——检索“kappa confusion matrix”可找到大量口径讨论。
- MathWorks 视频中心——分类精度评价相关演示。
- YouTube 检索:MATLAB confusion matrix Kappa——实操演示,注意甄别口径。
文章声明
本文内容仅为作者学习、思考、经验、笔记的总结,仅供技术交流与参考。文中观点仅代表笔者个人思辨,不构成任何学术建议、商业建议或专业建议。所有数据来源已标注,引用时请以原始文献为准。
内容仅供学习参考。如需引用,请以原始文献为准。 全文约 12600 字 | 参考文献 62 篇(主要 9 篇)。

