威布尔分布生存分析:右删失、极大似然与B10寿命

发布时间:2026/10/29 21:10:53
威布尔分布生存分析:右删失、极大似然与B10寿命

手里攥着一批部件的运行时长记录,四十个样本,一大半已经失效,剩下十几个到测试结束还在正常跑,这时候新人最常干的事就是把这些记录一平均,报一个"平均寿命"上去。我见过太多次这样的报表被推翻,原因不是算错了加减乘除,而是这批数据里混着两种完全不同性质的信息:一种是"确切的死亡时间",另一种是"我只知道它活到了这个点,之后的事我不清楚"。把后者当成前者参与算术平均,等于主动往低估方向拉了一把,后面的所有结论都建在流沙上。威布尔分布就是用来收拾这类局面的主力工具,它把生存时间数据的非负性、长尾特征和删失结构一次性装进一个只有两个参数的框架里,还能顺手把"故障是早期磨合问题还是累积磨损问题"这个机理信号从数据里读出来。这篇内容写给已经在跑寿命试验、做可靠性评估或者分析用户流失时间的同行,也写给刚接触生存分析、被指数分布拟合出一条直线的残差图搞得一头雾水的初学者,我会把参数化约定、似然函数怎么搭、B10寿命怎么算、哪些坑反复有人踩,一条一条摊开讲。

1. 生存时间数据的三处硬骨头:删失、非负、长尾

1.1 右删失把算术平均这条路堵死了

先把这个概念钉死。右删失指的是:观测在某个时间点结束时,对象还没有发生我们关心的事件。部件还在转,用户还在用,受试者还健在。这时候你手里唯一的确定信息是"它的生存时间大于等于这个观测时长",而不是"它的事件时间等于这个观测时长"。这两种解读的差别有多大?举个极端例子:一百个样本,九十个在第 50 小时失效,十个跑到第 500 小时还没坏。真实平均寿命一定高于 50 小时,如果把这十个样本按 500 小时算事件时间,正常情况下会高估,可如果干脆把它们从分母里剔掉、只算那九十个,你得到的 50 小时就是个明显的低估,因为存活到 500 小时的那些大概率还能继续跑。两种粗暴处理都会把结论带偏,方向还不一样。

正确的做法是从生存函数 S(t) = P(T > t) 出发,让每个样本按它"贡献的信息量"进入似然。失效样本贡献的是概率密度 f(t),删失样本贡献的是生存概率 S(t)。这一步转换看着只是一行公式,实际是整个生存分析的地基:删失样本不再是"缺失数据",而是"部分信息",它带着约束进来,把参数估计往正确的方向推。我一般会让新人先手推一遍两参数威布尔的似然函数,推到能自己写出δ标记怎么进指数为止,之后就很少犯"删失当事件"这类低级错误了。

还有一类更麻烦的:区间删失,你只知道事件发生在两次巡检之间,确切时间未知。工控设备的定期检查、体检随访都属于这种。两参数威布尔配合区间似然同样能处理,只是似然项变成两点 CDF 之差,代价是需要写一个自定义的负对数似然函数,现成的库未必直接支持。这块如果样本量不大,我倾向于退回离散化处理或者干脆用参数化 bootstrap 跳过解析式。

1.2 指数分布为什么总在关键时刻不够用

指数分布是威布尔在形状参数等于 1 时的特例,它的核心特征是风险率恒定。也就是说,一个用了几千小时的部件,下一小时失效的概率和一个刚上机的新件完全一样。这个假设在某些场景下勉强站得住,比如随机过载击穿、偶发外力冲击,但凡是涉及材料疲劳、润滑劣化、触点磨损、电池衰减的场合,它几乎必然错。

错在哪里?错在数据里明明有趋势,你硬套一个无趋势模型,后果不是"精度差一点",而是残差里留下系统性结构。我在早期做过一次轴承寿命拟合,用指数分布跑完,概率图上点子在低分位端向上弯、高分位端向下弯,形成一个明显的弧形。当时没在意,直接报了参数,后来拿外部验证集一跑,实际早期失效率远高于模型预期。换成威布尔,形状参数落在 2.3 附近,风险率随时间单调上升,概率图立刻拉直。那次之后我形成了一个习惯:任何生存数据,先用威布尔跑一遍看形状参数,它落在 [0.9, 1.1] 区间内,我再考虑退回指数模型简化,落在这个区间外,指数模型直接出局。

威布尔之所以能顶上来,还因为它和极值理论有血缘关系:一个系统由多个串联环节组成,系统失效时间取各环节失效时间的最小值,这类"最弱环"结构在弱条件下会趋近威布尔分布。这个背景解释了一件事——威布尔在工程可靠性里适用面这么宽不是巧合,背后有结构性的道理。

1.3 两个参数各自在管什么

两参数威布尔的生存函数写出来是 S(t) = exp(-(t/λ)^β),累积分布函数 F(t) = 1 - exp(-(t/λ)^β),概率密度 f(t) = (β/λ)(t/λ)^(β-1) exp(-(t/λ)^β),风险函数 h(t) = (β/λ)(t/λ)^(β-1)。四个式子看着差不多,但真正做工程决策时天天用的是风险函数,因为它直接对应"现在这个时点,下一单位时间出问题的强度"。

尺度参数 λ 管时间轴的横向拉伸,量纲和时间一致,含义是特征寿命:t = λ 时,S(λ) = exp(-1) ≈ 0.368,也就是大约 63.2% 的样本已经失效。注意它不等于平均寿命,这一点被搞混的频率高得吓人。形状参数 β 无量纲,管风险率的走向,是纯粹的机理参数:β < 1 风险递减,β = 1 恒定,β > 1 递增,β = 2 时风险率是一条过原点的直线,恰好对应瑞利分布。

这里有一个必须先说清楚的问题:参数化约定不统一。有的教材和软件用 rate 参数化的形式 f(t) = βλt^(β-1)exp(-λt^β),这里的 λ 量纲是时间的 -β 次方,数值上等于尺度参数的 -β 次方;另一些用 scale 参数化,λ 就是特征寿命。这两种写法的 λ 完全不是一回事,混用会得到一个荒谬的结果,比如算出特征寿命 0.0003 小时之类的。套任何现成代码之前,去文档里确认它用的是哪一种,或者干脆拿一个已知答案的小样本喂进去验一下,这一步花三分钟,能省掉后面三小时。

2. 形状参数 β 读出来的失效机理信号

2.1 β 小于 1:早期失效段的典型脸孔

β 落在 0.5 到 0.9 之间,风险率随时间单调下降,意味着"越新的东西越容易坏"。听起来反直觉,但制造业里这太常见了:焊接虚接、装配应力、材料内部缺陷、工艺参数漂移造成的批次性问题,都会在投入使用初期集中暴露。跑过一段时间的存活件反而越来越稳,因为它们已经筛掉了。

这类数据的处置思路和磨损失效完全不同。你不需要延长保修期或者加大备件库存,你要做的是把早期失效段的缺陷件筛出来,做老化筛选、加严出厂检验、追查工艺环节。我见过一个团队拿着 β = 0.7 的数据去论证"应该缩短更换周期",方向整个反了,按那个模型,缩短周期反而把设备推进了高风险的早期区间,维护成本上升,故障率却没降。

这里还有一个坑:β < 1 时,密度函数在 t = 0 处发散。有些数值优化器在这个区域会抖,初值给不好直接发散到边界。我一般的处理是给 β 加一个下界约束,比如 0.1,并且在似然里对 t = 0 的样本做单独处理,或者干脆把它们当作左删失。

2.2 β 接近 1:别急着下结论说随机失效

β 估计值在 1 附近的 10% 以内,很容易被解释成"失效是随机的,没有老化趋势"。这个结论有时候成立,有时候是样本量不够导致区间太宽——β 的 95% 置信区间可能是 [0.7, 1.4],你把点估计 1.02 当成真值在讲,其实是统计精度不足在骗自己。所以看到 β ≈ 1,第一件事是去看它的置信区间宽度,而不是直接下判断。

第二件事是看数据结构。如果数据本身是异质总体混在一起的,比如一批设备由两个供应商供货,一个供应商的件有磨损趋势,另一个是随机失效,混在一起做单峰拟合,形状参数会被拉向中间。这种"混合分布伪装成随机失效"的情况,用单参数威布尔永远看不出来,得上混合模型或者做分层分析。

真正意义上的随机失效在工程里对应的是过载、误操作、外部冲击这些与累积使用时间无关的机理。如果你确认了机理确实是这一类,那么指数模型的简化就是合理的,而且能省掉一个待估参数,在小样本下是实打实的收益。

2.3 β 大于 1:累积损伤的量化指标

β 超过 1,风险率单调上升,这是磨损失效、疲劳、腐蚀、绝缘老化的标准特征。β 越大,风险率上升越陡,失效越集中在特征寿命附近。β 在 2 到 4 之间是最常见的磨损区间,β 大于 5 的情况说明失效高度集中,往往是单一主导机理在起作用。

这里有个工程上很好用的推论:β 大于 1 时,预防性更换是有意义的,而且最优更换间隔可以直接从模型里算出来。β 越陡,这个窗口越窄,意味着更换时间点必须卡得比较准,早换浪费寿命,晚换故障率飙升。相反,β 小于 1 时,定期更换策略在数学上就是低效的,这时候该做的是筛选和 burn-in,不是维护计划。

β 区间风险率走势常见机理该做的动作
0.3 – 0.8快速下降装配缺陷、材料夹杂、工艺波动出厂筛选、老化跑合、追工艺
0.8 – 1.2基本恒定随机过载、外部冲击、误操作简化成指数模型,关注备件
1.2 – 2.5缓慢上升轻度磨损、润滑劣化定期巡检,可做预防更换
2.5 – 5明显上升疲劳、腐蚀、绝缘老化严格按周期更换,监控趋势
> 5陡峭上升单一主导机理,接近定时失效卡点更换,容错设计

这张表是我自己项目里常用的速查表,但必须强调它是经验区间不是定律,机理判断永远要回到失效分析报告上,数据只能提供线索,不能替代拆解。

3. 参数估计的三条路线,各有各的适用场景

3.1 极大似然:含删失样本下的标准解法

两参数威布尔在含右删失样本时的对数似然是这个形状:

log L(β, λ) = Σ_i δ_i · [ln β - ln λ + (β-1)(ln t_i - ln λ)] - Σ_i (t_i/λ)^β

其中 δ_i = 1 表示观测到失效,δ_i = 0 表示右删失。注意删失样本只进入第二项,它对参数的约束是"这个时间点之前别失效",体现在惩罚那些让 S(t_i) 太小的参数组合上。这个式子对 λ 有解析解,对 β 没有,实际求解用二维数值优化,或者先对 λ 做剖面化再对 β 一维搜索。

初值怎么给?β 给 1.0 或者用概率图法的斜率,λ 给样本中位数或者所有观测时间的几何均值。这两组初值在绝大多数情况下都能收敛。如果优化器报奇异 Hessian 或者参数跑到边界,八成是数据里有 t = 0 的记录,或者删失标记全为 0(那就是纯粹的参数拟合,没有生存结构了)。

import numpy as np from lifelines import WeibullFitter # durations: 观测时长;event_observed: 1=失效, 0=右删失 durations = np.array([...]) event_observed = np.array([...]) wf = WeibullFitter() wf.fit(durations, event_observed=event_observed) print("shape (rho):", wf.rho_) print("scale (lambda):", wf.lambda_) print("log-likelihood:", wf.log_likelihood_)

用 lifelines 的时候要留意它的参数名:rho_是形状参数,lambda_是尺度参数,生存函数定义成 S(t) = exp(-(t/λ)^ρ),和前面讲的 scale 参数化一致。不同版本对属性名的处理有过调整,代码跑不通先去查你装的版本,别急着怀疑数据。

如果不想依赖高层封装,用 scipy 自己写负对数似然也很直接,好处是完全掌控参数化,也方便加约束和自定义删失类型:

from scipy.optimize import minimize from scipy.stats import weibull_min def neg_log_lik(params, t, d): beta, lam = params if beta <= 0 or lam <= 0: return 1e12 ll = np.sum(d * (np.log(beta) - np.log(lam) + (beta - 1) * (np.log(t) - np.log(lam))) - (t / lam) ** beta) return -ll res = minimize(neg_log_lik, x0=[1.0, np.median(durations)], args=(durations, event_observed), method="Nelder-Mead", options={"xatol": 1e-8, "fatol": 1e-8})

我通常两种都写,互为交叉验证。两个实现给出的 β 差超过 1%,说明中间某一环的参数化或者删失标记出了问题,这时候停下来查比继续往下跑划算得多。

3.2 概率图法:现场没有计算环境时的快刀

概率图法的思路是把分布函数做两次对数变换,把曲线拉成直线。对 F(t) = 1 - exp(-(t/λ)^β) 取变换:

y = ln(-ln(1 - F(t))) = β · ln(t) - β · ln(λ)

于是 y 对 x = ln(t) 就是一条直线,斜率就是 β,截距是 -β ln λ。实操时横轴用 ln(t_i),纵轴用经验分布函数的估计值代入 y。

经验分布怎么估?样本量小的时候用中位秩公式 F_i ≈ (i - 0.3) / (n + 0.4),比 i/n 偏差小;样本量大用哪个都无所谓。这里有个细节容易忽略:排序和删失的关系。如果存在右删失,不能简单地按时间排序取秩次,必须用 Kaplan-Meier 估计或者专门的秩回归方法处理,否则删失点会被错误地分配到一个偏大的累积概率上,整条直线被拉歪。

import numpy as np t_sorted = np.sort(durations) n = len(t_sorted) i = np.arange(1, n + 1) F_hat = (i - 0.3) / (n + 0.4) x = np.log(t_sorted) y = np.log(-np.log(1 - F_hat)) slope, intercept = np.polyfit(x, y, 1) beta_hat = slope lambda_hat = np.exp(-intercept / slope)

这个方法我到现在还在用,原因是它极其直观:把点画上去,肉眼一看线性度就知道威布尔适不适合,弯曲的方向还能告诉你该往哪个分布上试。左端翘起、右端压平,往往提示数据里有早期失效的子总体;右端翘起则可能是磨损失效的尾部在作怪。这种判断速度是数值拟合给不了的。

当然它的精度不如极大似然,尤其在删失比例高的时候,因为删失点没有被充分利用。我的做法是拿它出初值和做直观判断,最终参数报极大似然的结果。

3.3 小样本和先验信息:贝叶斯这条路的性价比

样本量掉到个位数或者十几个的时候,极大似然估计会变得很不稳定,β 的点估计可能今天 1.8 明天 3.2,置信区间宽得没有实际意义。这时候引入先验是有实打实收益的,尤其当你手上有同系列产品、同类工艺的历史数据。

具体做法是在 β 和 λ 上放对数正态先验或者 Gamma 先验,β 的先验中心根据历史机理判断给,比如同类磨损件历史 β 在 2 附近,就给一个以 2 为中心、对数标准差 0.4 的弱信息先验。这个先验强度不能太大,否则数据说了不算,等于把历史结论硬塞进新数据。我的经验是:样本量低于 20 时先验带来的收缩是帮助;样本量超过 50,先验影响基本被数据淹没,放不放差别不大。

代价是计算复杂度和沟通成本。贝叶斯给的是后验分布,报给业务方的时候要解释清楚"这个区间是可信区间不是置信区间",很多人到这一步就绕晕了。所以我的选择是:常规项目走极大似然,小样本或者需要融合历史信息的场景走贝叶斯,两条路的结果碰一下,差异大就说明数据信息量不足,结论要谨慎表述。

4. 拟合质量怎么判:光看相关系数会翻车

4.1 对数似然和 AIC 的正确用法

判断威布尔拟合得好不好,最常见的错误是拿概率图上的 R² 说事。R² 高只说明点子在 log-log 坐标下接近直线,但这条直线的位置对不对、尾部拟合准不准,它一点都给不了。而且 R² 会随样本量增加自动变高,跟模型优劣没有必然关系。

我的判定顺序是:先看对数似然值,再做同维度模型的 AIC 对比,最后回到概率图看残差结构。AIC = 2k - 2lnL,k 是参数个数,两参数威布尔 k = 2。拿它和对数正态、Gamma、指数模型比,差值小于 2 说明区分度不够,别硬说谁更好;差值超过 10 才有明确的倾向性。

from lifelines import WeibullFitter, ExponentialFitter, LogNormalFitter models = { "Weibull": WeibullFitter(), "Exponential": ExponentialFitter(), "LogNormal": LogNormalFitter(), } for name, m in models.items(): m.fit(durations, event_observed=event_observed) print(name, "AIC =", m.AIC_partial_)

要提醒的是,这几个模型的参数个数不同,指数模型只有一个参数,AIC 对比时它天然占便宜一点,所以当威布尔和指数的 AIC 接近时,不能直接选指数,得回到机理上看风险率到底是不是恒定的。

4.2 尾部偏差为什么会被放大

生存分析里最有价值的信息往往在尾部:B1 寿命、B0.1 寿命这类极端分位点,恰恰是工程上最关心的。但尾部也是拟合误差被放大最厉害的地方,因为那里样本稀少,一两个点的位置变化就能让曲线大幅摆动。

具体表现是:概率图中间段拟合得漂漂亮亮,两端的点却系统性偏离。左端偏离说明早期失效段建模不准,通常是混合总体没拆开;右端偏离说明磨损尾部的形状和威布尔假设不符,可能是失效机理在后期发生了切换。这两种情况都不是换个优化算法能解决的,必须回到数据本身去找子总体。

我做尾部评估时会专门算几个低分位点的拟合值和 Kaplan-Meier 经验值的差,比如 B1、B5、B10,看偏差是否在置信带内。这一步比看整体 AIC 更能暴露问题。

4.3 和竞争分布的取舍逻辑

威布尔不是唯一选项,对数正态和 Gamma 在很多场景下表现相当甚至更好。三者的风险率行为差异明显:威布尔的风险率是幂函数,单调且没有上界;对数正态的风险率先升后降,存在一个峰值;Gamma 的风险率从某个非零值起步再上升。如果你的数据里风险率明显在某个时间点之后开始回落,威布尔是拟合不出来的,硬拟合会在高分区产生系统偏差。

我的经验判断是:失效由累积损伤主导、风险率单调上升,优先威布尔;失效由多因素叠加、早期有个爬升过程,试试对数正态;需要更灵活的形状控制,用 Gamma 或者广义 Gamma。实际项目里我一般三个都跑,AIC 差距不明显就选机理上说得通的,别为了小数点后的似然值去选一个解释不了的模型。

5. 从参数到工程指标:B10 寿命和置信区间的实操

5.1 MTTF 和 B 寿命的换算

拿到 β 和 λ 之后,最常被问到的是两个数:平均寿命和 B10 寿命。

平均寿命 MTTF = λ · Γ(1 + 1/β),其中 Γ 是伽马函数。这一步很多人直接用 λ 当平均寿命报上去,在 β = 2 的时候误差接近 11%,在 β = 3 的时候误差超过 10%,在小 β 时误差更夸张。所以务必走一遍 Γ 函数,代码里就是scipy.special.gamma(1 + 1/beta)。

B10 寿命指累积失效概率达到 10% 对应的时间,解 F(t) = 0.1 得 t_B10 = λ · (-ln 0.9)^(1/β) ≈ λ · 0.10536^(1/β)。同理 B1 = λ · 0.01005^(1/β)。这类低分位寿命是可靠性指标里最常被引用的,因为它对应的是"早期批次风险",比平均值更能反映用户实际感受。

举个具体例子,某批液压密封件,n = 40,测试结束时 28 个失效、12 个右删失,极大似然给出 β = 2.1、λ = 1800 小时。那么:

  • MTTF = 1800 × Γ(1 + 1/2.1) = 1800 × 0.8855 ≈ 1594 小时
  • B10 = 1800 × 0.10536^(1/2.1) = 1800 × 0.3425 ≈ 617 小时
  • B1 = 1800 × 0.01005^(1/2.1),0.01005^(0.4762) ≈ exp(-4.6002 × 0.4762) = exp(-2.1906) ≈ 0.1119,得约 201 小时

B1 和 MTTF 差了将近八倍,这个差距在跟业务方沟通时非常关键。你要是只报平均寿命,对方会以为产品能用一千五百小时,实际上有 1% 的件在两百小时就挂了,售后投诉全集中在那批。

5.2 置信区间:三种获取方式的选择

点估计单独报出去是不负责任的,尤其样本量不大的时候。三个常用路径:

Fisher 信息矩阵法,用负对数似然在最优点的 Hessian 求逆得到协方差,再取对角元素开方。速度快,但依赖大样本正态近似,样本小或者 β 接近边界时区间会失真,甚至出现负的下界。我会在对参数做对数变换后再求 Hessian,保证区间恒正,然后用 delta 方法换算回原尺度。

似然剖面法,固定一个参数扫另一个,找对数似然下降 1.92(对应 95% 单参数)的位置。这个方法在小样本下表现好得多,也能处理不对称的区间形状。代价是计算量大一点,但现在这点算力根本不算事。我现在基本默认用剖面法。

Bootstrap,对样本做有放回重抽样,每次重新拟合,取分位数。优点是几乎不依赖任何分布假设,实现简单,还能顺带给出 B10 的置信区间——这一点前两种方法做不到,因为 B10 是参数的非线性函数。缺点是对删失数据的重抽样需要注意,简单的样本重抽样可能把删失结构打乱,稳妥的做法是做条件 bootstrap 或者用参数 bootstrap:从拟合好的威布尔里生成新样本,保留原来的删失时间结构。

rng = np.random.default_rng(42) boot_b10 = [] for _ in range(2000): idx = rng.integers(0, len(durations), len(durations)) d_b = durations[idx] e_b = event_observed[idx] if e_b.sum() < 2: continue m = WeibullFitter().fit(d_b, event_observed=e_b) if not np.isfinite(m.rho_): continue boot_b10.append(m.lambda_ * 0.10536 ** (1 / m.rho_)) lo, hi = np.percentile(boot_b10, [2.5, 97.5])

这段代码我基本是复制粘贴改改就用的,2000 次重抽样在普通机器上几秒钟跑完。注意两个跳过条件:失效样本太少、拟合参数非有限值,这两种情况在重抽样里出现得比想象中频繁,不处理会让分位数被 NaN 污染。

5.3 把结论翻译成维护动作

参数算完只是中间产物,真正交付的是决策。β = 2.1 这个结果对应的动作是:失效由累积磨损主导,定期更换有效;B10 = 617 小时意味着如果要控制 10% 的早期失效率,更换窗口应该卡在 600 小时之前;MTTF 1594 小时说明平均表现还行,但尾部风险集中在早期,所以策略重心应该放在首检而不是后期维护。

如果算出来是 β = 0.7,结论就完全反过来:更换周期再密也压不住早期故障,该做的是加严出厂筛选、做 50 小时的跑合筛选,把缺陷件提前淘汰。同一套数据、同一个模型,形状参数不同,投入的方向就不同,这也是我一直强调 β 是机理参数而不是普通拟合系数的原因。

6. 反复踩到的几个坑,写下来省点时间

6.1 删失标记写反是最贵的错误

这个错误我见过不止一次,而且极难自己发现,因为模型照常收敛、参数照常输出、图照常漂亮,只是结论完全反了。原因在于不同的库对 event 标记的约定不一致:有的用 1 表示失效,有的用 True 表示观测到事件,还有的用 0 表示删失。一旦反了,模型会把大部分样本当成"活到了很久",把删失的少数当成"很快就坏了",形状参数和尺度参数都会跑偏到一个看起来很合理的假值上。

防守办法很简单:跑完先做一次合理性检查,拿 Kaplan-Meier 估计的经验中位生存时间,和你拟合出来的模型中位生存时间比一比,差得离谱就说明有环节错了。另外把event_observed.sum()打出来,跟你原始记录里的失效数量对一下,这个数字对不上,别的都不用看。

6.2 位置参数该不该上

三参数威布尔多了一个位置参数 γ,形式是 S(t) = exp(-((t-γ)/λ)^β),物理含义是"在 γ 之前绝对不会失效",也叫保证寿命或门槛值。理论上很吸引人,实际上是个大坑。

原因在于 γ 的估计极不稳定,它和 β、λ 高度相关,似然曲面在 γ 方向常常很平坦,样本量不够时估计值会贴着最小值乱跑。更麻烦的是,如果真实分布其实没有门槛(很多失效机理确实没有),硬拟合三参数会让另外两个参数的方差大幅膨胀,得不偿失。

我的原则是:除非有明确的物理证据支持存在一个无失效区间(比如某种涂层在厚度耗尽之前完全不失效),否则坚持两参数。真要用,也先固定 γ 做敏感性分析,看结论对 γ 的取值敏不敏感,敏感就别用。

6.3 混合总体把单峰模型骗了

一批产品来自两个工艺不同的批次,或者同一个系统有多个失效模式,数据里就会出现两个不同尺度的子总体。单峰威布尔拟合这种数据,卡在中间,形状参数被拉平,尾部严重失真,概率图上表现为一段一段的偏离而不是整体弯曲。

识别方法是画经验风险率的非参数估计,或者直接看概率图的残差模式。看到分段特征,就该考虑混合威布尔或者竞争风险模型了。做这一步之前先确认数据来源,很多"混合总体"其实是数据记录口径不一致造成的,比如某个批次的计时单位不同、或者起始时间点定义不同,先排除这个再上复杂模型。

6.4 外推这件事要克制

威布尔在观测区间内拟合得好,不意味着往观测范围外推还准。特别是往远尾外推,形状参数的微小不确定性会被指数放大。我用 1000 小时的数据去预测 10000 小时的失效率,β 的 95% 区间是 [1.9, 2.3],那么外推出的高分量预测区间会宽到没有实用价值。

诚实的做法是把外推的不确定性显式画出来,用参数 bootstrap 生成预测带,让对方看到"这个外推值可能在很大一个范围内"。比起到处给一个看起来精确的单点预测,我宁愿报一个宽区间,至少不会误导后续的备件和保修决策。

最后分享一个我自己在项目里养成的小习惯:每次做完威布尔拟合,我都会在报告首页画一张概率图,把原始点、拟合直线和置信带叠在一起,然后在旁边用一行字写清楚形状参数的机理判读。目的是让看报告的人第一眼就能判断"这个拟合靠不靠谱、结论能不能用",而不是被一堆参数表淹没。这张图被追问的次数,比所有数字加起来都多。