第四章:数据预处理与探索性分析

各位工程师朋友,大家好。欢迎来到可靠性建模的实战环节。

说实话,很多初学者一上来就急着建模型、算寿命。但我得泼盆冷水——数据没处理好,后面全是白搭。我见过太多项目,因为一个异常值没揪出来,整个Weibull分析全偏了。今天咱们就聊聊数据预处理和探索性分析,这是可靠性工程的「地基」。

4.1 数据清洗:缺失值与异常值处理

实际工程数据,从来都不是干干净净的。传感器掉线、人为记录遗漏、测试中断……各种情况都会导致数据缺失。我个人习惯,拿到数据第一件事不是算统计量,而是先画个缺失值热力图,看看哪些位置是「黑洞」。

4.1.1 缺失值处理

缺失值怎么处理?分情况讨论:

  • 完全随机缺失(MCAR):比如某个传感器偶尔抽风。可以直接删除,或者用均值/中位数填充。
  • 随机缺失(MAR):缺失跟其他变量有关。比如高温下传感器容易坏。这时候用回归插补或KNN插补更靠谱。
  • 非随机缺失(MNAR):缺失本身跟失效有关。比如产品坏了,数据就传不回来了。这最麻烦,得用专门的方法,比如多重插补。
我的经验: 对于可靠性数据,我一般优先用「中位数填充」。因为寿命数据往往右偏,均值会被极端值拉偏,中位数更稳健。当然,如果缺失率超过30%,建议重新审视数据采集流程。

代码示例(Python):

import pandas as pd
import numpy as np

# 模拟数据
data = pd.DataFrame({
    'time': [100, 200, np.nan, 400, 500],
    'status': [1, 1, 0, 1, 0]
})

# 中位数填充
data['time'].fillna(data['time'].median(), inplace=True)
print(data)

4.1.2 异常值处理

异常值,说白了就是「看着不对劲」的数据。比如某台设备运行了10万小时还没坏,但同批次其他设备平均寿命才5000小时。这要么是记录错误,要么是这台设备根本没在用。

我常用的方法:

  • 箱线图法:超出1.5倍IQR的算异常。简单粗暴,适合快速筛查。
  • Z-score法:假设正态分布,|Z|>3的算异常。但寿命数据往往不服从正态,慎用。
  • 领域知识法:最靠谱。比如你知道某型号轴承的寿命不可能超过2万小时,那超过的直接标记。
注意: 千万不要机械地删除异常值!我曾经处理一批风电齿轮箱数据,有个异常点显示「运行1小时就坏了」。后来一查,是安装时螺栓没拧紧导致的早期失效。这个异常值恰恰反映了制造缺陷,是宝贵的质量反馈信息。

4.2 右删失数据的识别

可靠性数据有个独特的特点——右删失。什么意思?就是试验结束了,有些产品还没坏。你只知道它「至少活了这么久」,但不知道具体什么时候坏。

举个例子:你测试10个灯泡,到1000小时时,有3个还亮着。这3个的数据就是右删失的。你不能说它们寿命是1000小时,只能说「寿命≥1000小时」。

识别右删失数据,关键看一个标志位:

  • status=1:失效(完整数据)
  • status=0:右删失(只知道存活时间≥记录时间)

代码示例:

# 识别右删失数据
data['is_censored'] = (data['status'] == 0)
print(f"右删失比例: {data['is_censored'].mean():.2%}")
核心要点: 右删失数据不是「没用的数据」,它包含了「至少存活了这么久」的信息。如果直接删除,你会低估产品的真实寿命。这就是为什么可靠性分析必须用专门的方法,比如Kaplan-Meier估计。

4.3 非参数估计:Kaplan-Meier曲线

好了,数据洗干净了,右删失也标记好了。接下来该看看产品的「生存状况」了。Kaplan-Meier曲线,就是干这个的。

它不假设寿命服从任何分布(所以叫非参数),直接根据数据画出生存概率随时间的变化。说白了,就是回答一个问题:「到某个时间点,还有多少比例的产品没坏?」

4.3.1 KM估计的原理

公式我就不写了,咱们说人话:

  1. 把所有失效时间从小到大排序。
  2. 在每个失效时间点,计算「到该时刻还存活的产品中,有多少个失效了」。
  3. 生存概率 = 之前所有时间点的存活概率连乘。

右删失数据在失效时间点不贡献「失效事件」,但贡献「风险集」(即还活着的产品数)。

4.3.2 实战代码

import matplotlib.pyplot as plt
from lifelines import KaplanMeierFitter

# 模拟数据
T = [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]
E = [1, 1, 0, 1, 0, 1, 1, 0, 1, 0]  # 1=失效, 0=右删失

kmf = KaplanMeierFitter()
kmf.fit(T, event_observed=E)

# 绘制KM曲线
kmf.plot_survival_function()
plt.title('Kaplan-Meier 生存曲线')
plt.xlabel('时间 (小时)')
plt.ylabel('生存概率')
plt.grid(True, alpha=0.3)
plt.show()

# 输出中位生存时间
median_time = kmf.median_survival_time_
print(f"中位生存时间: {median_time} 小时")

4.3.3 如何解读KM曲线

KM曲线有几个关键特征:

  • 阶梯状下降:只在失效时间点下降,右删失数据不引起下降。
  • 尾部平坦:如果曲线尾部很长一段是平的,说明大部分产品已经失效或删失,剩余样本太少,估计不可靠。
  • 置信区间:通常用阴影表示95%置信区间。区间越宽,说明估计越不确定。
避坑指南: 我曾经遇到一个项目,KM曲线在尾部突然陡降,但样本量只剩3个。后来发现是这3个样本在同一时间点失效了,导致生存概率从0.8直接掉到0.2。这种尾部估计其实很不稳定,建议在报告中标注「剩余样本量」。

4.4 本章知识体系

下面这张图,是我自己总结的数据预处理与探索性分析流程,帮你理清思路:

数据预处理与探索性分析流程 原始数据 缺失值处理(删除/填充/插补) 异常值处理(箱线图/Z-score/领域知识) 右删失数据识别(status标志位) Kaplan-Meier 生存曲线估计 关键输出 • 清洗后的完整数据 • 异常值标记报告 • 右删失比例统计 • KM生存曲线图 • 中位生存时间 • 置信区间

这张图把整个流程串起来了。你想想看,从原始数据到KM曲线,中间每一步都不能跳过。缺失值不处理,KM估计会偏;异常值不揪出来,曲线形状可能完全走样;右删失不识别,你连生存概率都算不对。

好了,数据预处理和探索性分析就聊到这儿。下一章咱们会基于清洗好的数据,开始真正的可靠性建模——参数估计和分布拟合。到时候你会发现,前面花的时间,绝对值。


专注资料整理