ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

机器人成功率测试的置信区间陷阱:9/10≠90%

机器人成功率测试的置信区间陷阱:9/10≠90% 先讲一个让我印象深刻的验收现场。去年做个视觉分拣机械臂项目客户验收标准写得清清楚楚抓取并放置的成功率不低于 90%。我先跑了一轮测试10 次里成功 9 次点开计算器一算90%。客户现场负责人挺满意说要签字。我当时多嘴问了一句“这 90% 靠谱吗”接着我用二项分布和置信区间重新算了一遍9/10 的 95% 置信区间大概是 [0.60, 0.98]。也就是说真实成功率可能只有六成运气好一点也能测出 9/10。这个项目最后没有按 10 次验收而是重新设计了一套连续测试方案。这件事让我下定决心凡是涉及“成功率”“通过率”“完成任务概率”的场景都不能只看点估计必须把样本量、置信区间、测试口径一起摆上台面。今天这篇博文就把我后来总结的这套思路完整写出来。1. 两个 90% 不是同一个 90%1.1 机器人测试里的“9/10”到底说明了什么机器人领域的成功率测试几乎天天都在和“二分类试验”打交道机械臂抓取抓起来并放到目标位置算成功掉件、撞件、放偏算失败。移动机器人导航从点 A 避开障碍到点 B算成功撞墙、卡死、超时算失败。视觉引导装配识别、抓取、插入一次完成算成功中间任何一步退出重试算失败。工业机器人焊接/涂胶工艺参数稳定输出一条合格轨迹算成功出现焊穿、漏涂、轨迹偏移算失败。这些测试的共同点每次试验只有成功或失败两种结果试验之间互相独立理论上每次成功的概率有一个真实值但我们永远无法直接看到这个真实值只能用有限的实验次数去估算它。问题就出在这里。估算出来的“样本成功率”不等于“真实成功率”。样本量越小估算结果的随机波动越大。9/10 和 900/1000点估计都是 90%但一个是 10 次试验里的结果一个是 1000 次试验里的结果背后的信息量差了 100 倍可信度差了不止一个数量级。1.2 置信区间一算差距立刻暴露“点估计”回答“大概是多少”“置信区间”回答“真实值大概在哪个范围”。按 95% 置信水平用 Wilson 区间算两组数据观测结果点估计95% Wilson 置信区间是否敢下“成功率≥90%”的结论9/1090%[0.60, 0.98]不敢真实值可能只有 60%27/3090%[0.74, 0.97]不敢下限还是低90/10090%[0.82, 0.93]接近但严格验收仍不够900/100090%[0.88, 0.92]点估计很稳但有点强迫症的话要证明下限也过线还得加样本9/10 的置信区间宽得吓人下限 0.60 意味着真实成功率可能只有六成900/1000 的置信区间收窄到了 [0.88, 0.92]总算有点底了。同一个 90%可信度天差地别。这个差异本质上来自标准误。二项分布的成功率标准误是 √(p(1-p)/n)p90% 时n10 的标准误大约是 9.5 个百分点n1000 时只有 0.95 个百分点。样本量每增加 100 倍置信区间宽度大约缩小到原来的 1/10。这不是什么高深理论而是工程上必须尊重的基本规律。1.3 为什么机器人测试特别容易中招做软件测试的人早就习惯了要跑几千个用例才敢说稳定但机器人领域有点特殊一是测试成本高。跑一次机械臂完整抓放循环可能要几秒到几十秒做移动机器人导航测试单次可能要跑好几分钟。跑 1000 次听起来简单实际却涉及电量和耗材消耗、故障恢复、现场值守时间成本让人本能地倾向“少测几次”。二是环境不稳定。光照变化、工件摆放偏移、地面打滑、电池电压波动都会影响结果。环境一变试验就不再是严格意义上的“同条件重复”。三是工程节奏着急。项目验收日期通常是定死的今天测了 10 次觉得差不多了结果被置信区间泼了一盆冷水——重新补测的代价极大。四是很多机器人团队的背景偏控制、规划、机械设计统计基础薄弱。大家习惯用平均值、百分比作为评价指标很少意识到百分比背后还挂着一道置信区间。这几点叠加起来让“9/10 90%”这种误判在机器人项目里反复发生。我甚至有段时间把这种情况叫做“验收期乐观症”样本越少越容易偶然通过反而让真实水平不够的系统蒙混过关。2. 误判从哪里来三个被忽视的统计陷阱2.1 小样本下“极端值”会伪装成“高水平”小样本的问题不只是置信区间宽更危险的是它可能测出极端漂亮的结果。比如测试 5 次全成功点估计 100%。初看完美实际用 Wilson 区间算一下95% 置信区间下限只有 0.478连 50% 都不到。也就是说测 5 次全成功真实成功率甚至可能只有一半不到只是这次运气好全中了。再看 10 次成功 9 次点估计 90%置信下限约 0.60。如果恰好前 9 次都成功、最后 1 次失败团队很容易产生“系统很稳只是最后偶尔抖了一下”的错觉。但从统计上看10 次里的任何一次失败都是随机波动的正常表现不能说明系统“只是小问题”。这也解释了为什么“跑一遍就过”的报告没有参考价值。任何机器人在参数基本合理的前提下跑 3 次全成功的概率都不低。如果真实成功率只有 60%跑 3 次全成功的概率是 0.6³ 21.6%差不多五分之一。拿 5 次全成功的小样本来证明系统成熟本质上是在赌运气。2.2 正态近似不是万能的小样本会算得离谱很多人算成功率误差时习惯直接用“均值 ± 3σ”的正态近似公式。这个公式在样本量足够大时才成立而二项分布逼近正态分布有前提条件通常要求 np 和 n(1-p) 都大于 5更保守的建议是大于 10。回到 9/10 这个例子n10p0.9n(1-p)1远远小于 5。此时用正态近似计算p 0.9标准误 √(0.9×0.1/10) ≈ 0.095均值 ± 1.96 标准误 → [0.9-0.186, 0.90.186] → [0.714, 1.086]上限超过了 1这在比例数据上显然是荒谬的。比例不可能大于 1但正态近似模型根本不知道“边界”存在。更麻烦的是下限 0.714 跟 Wilson 区间的 0.596 差了不少——在样本量不足时正态近似会高估精度让人误以为“大概在 71% 以上”而实际情况可能低到 60% 以下。所以在机器人成功率计算这块我的建议是不要用正态近似公式直接用 Wilson 区间它对小样本和大样本都成立边际效应也被校正过是工程场景里最实用的选择。2.3 “重试次数”和“人工干预”最会稀释成功率这是我在检查机器人测试数据时最喜欢问的第一个问题你的“成功”定义里允不允许重试举个例子。机械臂抓取工件第一次没抓起来自动重新定位后第二次成功。按“最终放置成功”算这是成功按“一次通过率”算这是失败。两种口径算下来一个系统可能从 60% 飙升到 95%。工厂精益管理里有个概念叫“一次通过率”First Pass Yield, FPY它比最终的良率更严格、更能暴露问题。机器人测试也应该采用类似思想把“一次执行成功”和“重试之后成功”分开统计。如果重试后才成功至少说明第一次的执行逻辑存在缺陷这个缺陷可能是识别不稳、轨迹干涉、力度不当或时序错误。人工干预更不可取。有人盯着看机器人快撞了操作员急停改路径然后算“成功”。这样的数据除了自我安慰没有任何意义。要阻止误判第一步就是让测试条件尽量接近无人值守的自动化条件把人为干预的行为记录下来并默认算作“失败”或“无效样本”而不是悄悄归为“成功”。再往后我还见过把一次失败拆成“半成功”的情况比如“工件掉落了但至少没撞坏机器人算 50% 成功”。这种模糊评分会彻底摧毁统计有效性。成功率必须用二分类的结果成功就是成功失败就是失败。评分可以另做一套连续指标不要跟成功率混在一起。3. 正确的成功率计算器应该长什么样标题里的“计算器”不是指一个单纯做除法的工具而是指一套把“样本量、点估计、置信区间、验收阈值、失败模式”统筹起来的判断框架。我自己更喜欢写成一个 Python 模块因为机器人团队的测试记录通常都在代码和日志里脚本处理最方便。3.1 先定口径再谈计算任何成功率计算器第一步永远是确认计数规则。我给团队定的默认规则是这样每次任务触发算一次试验无论成功与否。允许自动重试的任务把“首次成功率”和“最终成功率”分开统计验收以首次成功率为准。人工介入、急停、手动接管一律算失败并在备注里写明原因。环境条件光照、负载、电池电量、场地发生变化时重启一个新的统计会话不要混进前一个批次。重复测试之间的间隔要保证状态充分复位回到起始位置、清空误差累积否则下一次测试就不是独立试验。这些规则看着繁琐但缺了它们再漂亮的置信区间计算也没有意义——输入本身就是脏数据输出自然就是误判。3.2 Wilson 区间公式一个函数搞定Wilson 区间不需要依赖复杂的统计包一个 20 行的 Python 函数就能实现import math def wilson_ci(success: int, total: int, z1.96): 计算二项比例的双侧 Wilson 置信区间。 z 取 1.96 对应 95% 置信水平。 if total 0: return (0.0, 0.0) p success / total denom 1 z * z / total center (p z * z / (2 * total)) / denom margin (z * math.sqrt(p * (1 - p) / total z * z / (4 * total * total))) / denom return (center - margin, center margin) # 示例9/10 和 900/1000 print(wilson_ci(9, 10)) # (0.596, 0.982) print(wilson_ci(900, 1000)) # (0.880, 0.918)这个函数我用了很久结果和 statsmodels 的proportion_confint一致。在机器人测试脚本里丢几行日志数据进去马上就能看到置信区间比手动估算靠谱太多。3.3 最小样本量连续多少次全成功才敢验收在机器人项目里最常被问到的问题是“到底要测多少次才算数”这个问题没有统一答案取决于你定的验收标准和置信水平。如果要求“在 95% 置信水平下证明真实成功率不低于 90%”一个很实用的做法是看“连续全成功”的最小样本量。用 Wilson 区间的下限作为判断标准可以写一个循环def min_continuous_success(target0.90, z1.96, max_trials1000): for n in range(1, max_trials 1): lower, _ wilson_ci(n, n, zz) if lower target: return n return None print(min_continuous_success()) # 输出 35意思是如果要求双侧 95% 置信区间的下限也超过 0.90你需要连续 35 次全成功。如果只做单侧检验只关心“真实成功率是否显著低于 90%”门限会更松一些。用 z1.645 代入上面的函数结果是 29 次。两种口径相差不少所以验收前一定要确认好是单侧还是双侧。我给客户做验收时默认按双侧来理由很简单双侧区间给出的结果更保守也更不容易被质疑。这里有一个工程上很实用的“截尾”思想不一定非要跑满 35 次如果中途出现了 1 次失败就可以做一次“继续跑 vs 提前判定不通过”的判断。真实成功率达标时35 次里出现失败的概率是 1-0.9³⁵ ≈ 0.975如果真实成功率刚好 90%能一次性 35 连中的概率才 2.5%。所以中途出现失败时按“当前数据还不支持通过”处理大概率是正确的。这种提前终止策略能替项目省下大量测试时间。3.4 一个可以直接抄走的成功率计算模块我在上一个项目中把前面这些逻辑封装成了一个类每次测试后把结果追加进去报表自动生成省了很多沟通成本from typing import List, Tuple class RobotSuccessRate: def __init__(self, target: float 0.90, ci_level: float 0.95): self.target target self.z 1.96 if ci_level 0.95 else 1.645 self.results: List[bool] [] def add_trial(self, success: bool): self.results.append(success) def summary(self) - dict: total len(self.results) success sum(self.results) point_estimate success / total if total else 0.0 lower, upper wilson_ci(success, total, zself.z) return { total: total, success: success, point_estimate: point_estimate, ci_lower: lower, ci_upper: upper, pass: lower self.target, } def min_additional_success_needed(self, max_extra500) - Tuple[int, int] or None: base_success sum(self.results) base_total len(self.results) for extra in range(1, max_extra 1): new_success base_success extra new_total base_total extra lower, _ wilson_ci(new_success, new_total, zself.z) if lower self.target: return (new_success, new_total) return None # 使用示例 calc RobotSuccessRate(target0.90) for flag in [True]*9 [False]: # 模拟 9/10 calc.add_trial(flag) print(calc.summary()) # {total: 10, success: 9, point_estimate: 0.9, # ci_lower: 0.596, ci_upper: 0.982, pass: False}注意min_additional_success_needed这个方法它解决的是实际测试中最棘手的问题已经跑了 10 次成功 9 次现在放弃重来成本太高能不能继续跑能。它会告诉你在不改变当前数据的前提下还需要追加多少次全成功置信下限才能站到 90% 以上。跑完 10 次 9 胜之后继续追加 45 次全成功总数据变成 54/55Wilson 下限才可能越过 0.90。所以我才坚持在项目一开始就把置信区间算给客户看而不是等测完再补——早点知道测试预算比盲目跑十几次再撞墙要划算得多。4. 现场案例一次视觉分拣机械臂的验收全记录4.1 项目背景与验收争议说回开头的视觉分拣项目。客户的验收要求是“自动化抓取放置成功率不低于 90%”。我第一轮测试跑了 10 次9 次成功1 次失败。失败原因是视觉识别到了一个反光工件抓取姿态解算出现偏移工件滑落。客户现场经理当场就说“90%达标了。”我那时候已经养成了先算置信区间的习惯看到 Wilson 区间下限 0.596心里知道不能签这个验收单。为了说服客户我把 9/10 的置信区间图打印出来又特意补做了一个对比如果真实成功率只有 60%随机跑 10 次也有不低的概率测出 9/10——计算一下真实成功率 60% 时10 次里成功 9 次及以上的概率是 C(10,9)×0.6⁹×0.4 0.6¹⁰ ≈ 0.006 0.006 1.2%虽然不高但考虑到对方只用 10 个样本这个风险不该被忽略。客户听了之后认同我的判断同意重新设计测试方案。4.2 把测试方案改成“连续全成功”之后协商后的验收规则很简单按双侧 95% 要求连续 35 次全成功即判定通过如果中途出现失败从失败点开始重新起算同时要分析失败根因调整后必须重新跑。这个规则很硬核团队内部也有人担心“35 次太多”。但算过账之后发现其实合理如果真实成功率是 95%35 次全成功的概率是 0.95³⁵ ≈ 16.6%有点难但也不是不可能。如果真实成功率是 98%35 次全成功的概率是 0.98³⁵ ≈ 49.3%接近一半。如果真实成功率确实只有 90%35 次全成功的概率只有 2.5%基本上很难蒙混过关。所以这个验收规则对真实水平 90% 的系统是“几乎过不去”对 98% 以上的系统是“有一半概率一把过”对 95% 左右的系统则是“多跑几轮总能过”。这套逻辑摆给客户看客户也说公平。首轮调整后团队把反光工件的识别算法加了一层滤波又改了抓取角度补偿。结果一口气跑了 41 次中间断过一次第 18 次出现了一次运动规划偶发抖动导致的放置偏差从第 19 次开始重算最后连续成功 23 次。接着又排查了抖动来源发现是传送带到位信号时序问题修了一个 PLC 点位配置然后重新计时连续成功 37 次通过验收。4.3 过程中踩过的三个坑第一个坑是“失败重算”的口径不清。刚开始我们定义“连续 35 次全成功”但第一次中断后有人问是从头开始算还是从失败后继续算团队里有人觉得从头算太苛刻有人觉得从失败那一刻重算才公平。最后只能白纸黑字写清楚从失败后的下一轮试验重新起算失败前的记录保留在报告里但不计入验收区间。这样规则明确大家都无话可说。第二个坑是“中断后立刻回归”的问题。有一次测试跑到一半更换了工件托盘我没重启统计会话。结果后面连续成功几次数据跟换托盘前混在一起看很漂亮但严格来说不同批次工件的尺寸公差不同属于不同试验条件。后来我把所有数据打上“批次标签”换条件就新建会话问题才消停。第三个坑是“复测时环境悄悄变了”。白天测试光照充足视觉识别成功率高晚上车间只开部分灯管识别成功率明显下降。头几次测试我们没记录光照强度导致白天数据特别好看晚间复测就翻车。后来所有验收测试都固定在同一时段、同一光照条件下进行并且记录环境参数。这条经验后来写进了部门的测试规范。5. 常见误判与排查技巧实录5.1 一张表看清常见误判误判类型典型表现根源正确做法忽略样本量“10 次成功 9 次90%通过”只用点估计加算置信区间看下限是否达标小样本正态近似用“均值 ± 3σ”算 9/10套用大样本公式改 Wilson 区间或样本量足够大时再用正态近似重试混入成功重试 3 次后成功算成功指标定义不清首次通过率与最终通过率分列验收以首次为准人工干预不记录操作员临时改路径后算成功测试管理缺陷人工接管一律算失败并留存日志数据跨条件混批不同光照、不同工件批次混一起统计试验设计缺失按条件分段统计最后看整体加权结果只报平均值不报方差只说“平均成功率 90%”统计习惯差同时报告置信区间、失败模式分布这张表是我每次给团队做评审时都会带的。排查一个机器人项目是否被成功率误判第一件事就是对照这张表看测试数据有没有中招。5.2 怎么跟客户或老板解释“9/10 不等于通过”把置信区间讲给非技术背景的人听不能摆公式。我试过最管用的一套说法是“9/10 只是这次抽样的结果不代表机器人真实水平。如果真实水平勉强到 60%运气好一点也能在跑 10 次时抽出 9 次成功。所以我们不能说‘大概率超过 90%’。再跑 35 次如果全部成功才能把这种偶然性压到 5% 以下。”配合一个类比更容易理解这就像抽查 10 个人的平均身高不能根据他们算出全国平均身高是 175cm置信区间会宽到让你怀疑人生。要让人相信全国平均身高真的在那附近至少得测几百个样本。机器人在不同光照、不同负载下的表现波动比身高还大样本更不能少。必要时可以直接演示把 9/10 的成功率往wilson_ci(9, 10)里一丢显示[0.596, 0.982]再让客户自己看那个 0.596通常不需要更多解释了。5.3 工具选型从 Excel 到 Python 怎么选如果你完全不想写代码Excel 也能算 Wilson 区间。在单元格里输入 B2/(B2C2)然后手动代入公式或者直接用 Excel 的BINOM.DIST做精确概率计算。只是稍微繁琐容易出错。我更推荐的是 Python 方案如果只是求置信区间用上面那段wilson_ci函数就够。如果需要完整假设检验可以用 SciPyfrom scipy.stats import binomtest result binomtest(9, 10, p0.9, alternativetwo-sided) print(result.proportion_ci(confidence_level0.95, methodwilson))如果测试记录已经存在 CSV 里Perl 或 Pandas 读进来批量算即可。机器人日志一般都有现成的success/fail字段写个脚本循环调用add_trial()最后直接输出报表。对于在线计算器只要它支持 Wilson score interval 且能显示置信区间上下限都可以用。但要小心很多在线计算器默认用的是正态近似小样本时别信它的输出。判断方法很简单输入 9/10如果输出上限显示超过 1说明它用了正态近似赶紧换。写在最后的一个小建议最近我把这套逻辑固化成了团队内部的“机器人任务成功率测试模板”新项目立项时直接套用第一步定口径第二步定置信水平和目标值第三步用脚本算出最小样本量第四步按顺序跑测试并把日志自动写进统计模块第五步出报告时同时附带置信区间和失败模式分类。我个人最深的体会是成功率误判不是统计知识不够而是“想快点看到好结果”的心理在作祟。每次看到漂亮的高成功率先别急着高兴多问一句“这结果是基于多少次试验”再追加一句“置信区间下限是多少”能帮你挡掉大量后续麻烦。做机器人项目慢一点、稳一点比什么都重要。
返回列表