第二章:良率数据采集与预处理
各位工程师朋友,大家好。今天我们来聊聊良率分析中最基础、也最容易被忽视的一环——数据采集与预处理。
我做了十几年半导体,见过太多项目在数据上栽跟头。有的团队模型建得漂亮,结果数据一塌糊涂,最后分析结论全是错的。说白了,数据质量决定了分析的天花板。你想想看,垃圾数据进去,再牛的AI算法也白搭。
2.1 数据采集系统:EES与APC
先说说数据从哪来。半导体产线里,数据采集主要靠两套系统:EES(设备工程系统)和APC(先进过程控制)。
EES 负责从每台设备上抓取原始数据。比如刻蚀机的射频功率、温度、压力,光刻机的对准精度、曝光剂量。这些数据通常以秒级甚至毫秒级频率采集。
APC 则更偏重过程控制。它会根据实时数据调整工艺参数,同时记录调整前后的状态。APC的数据往往更结构化,但采样频率可能低一些。
我个人习惯把EES数据比作「体检报告」,APC数据比作「病历本」。一个告诉你当前状态,一个记录了你做过什么治疗。
关键点: 数据采集不是越多越好。我在项目中遇到过,某团队把100多个参数全采了,结果80%是冗余的。后来我们只保留了30个关键参数,模型效果反而更好。
下面这张图展示了数据采集到预处理的全流程:
2.2 数据清洗与缺失值处理
数据拿到手,第一件事不是建模,而是清洗。我见过太多人跳过这步,结果模型跑出来全是噪音。
常见的数据问题:
- 缺失值:传感器故障、通信中断、人为漏采
- 异常值:设备跳变、测量误差、记录错误
- 重复数据:同一批次被多次记录
- 时间戳错乱:不同系统时钟不同步
处理缺失值,我一般按这个优先级来:
- 直接删除:缺失比例超过50%的特征,果断删
- 均值/中位数填充:数值型特征,分布对称用均值,有偏态用中位数
- 前向/后向填充:时间序列数据,用前后值填充
- 模型预测填充:用其他特征预测缺失值,适合关键参数
我的经验: 曾经有个项目,刻蚀速率数据缺失了20%。我直接用均值填充,结果模型完全失效。后来发现缺失值集中在某个特定工艺步骤,用前向填充才解决问题。所以,一定要先分析缺失模式,再决定填充策略。
异常值处理,我常用3σ原则:
import numpy as np
def remove_outliers(data, column, n_sigma=3):
mean = data[column].mean()
std = data[column].std()
lower = mean - n_sigma * std
upper = mean + n_sigma * std
return data[(data[column] >= lower) & (data[column] <= upper)]
# 使用示例
clean_data = remove_outliers(raw_data, 'RF_Power', n_sigma=3)
注意: 3σ原则假设数据服从正态分布。半导体数据往往有偏态,比如缺陷密度分布。这时候用IQR(四分位距)法更靠谱。我曾经吃过这个亏,后来就改成IQR了。
2.3 数据标准化与归一化
数据清洗完了,下一步是统一量纲。为什么?因为不同参数的量级差太多了。比如温度是几百摄氏度,压力是几十帕斯卡,射频功率是几千瓦。如果不做处理,模型会天然偏向数值大的特征。
两种主流方法:
| 方法 | 公式 | 适用场景 | 特点 |
|---|---|---|---|
| Z-score标准化 | z = (x - μ) / σ | 数据近似正态分布 | 不改变分布形状,保留异常值信息 |
| Min-Max归一化 | x' = (x - min) / (max - min) | 数据有明确边界 | 将数据压缩到[0,1]区间 |
| Robust缩放 | x' = (x - median) / IQR | 数据有较多异常值 | 对异常值不敏感 |
我个人习惯:先用Z-score试试,如果效果不好再换Robust。Min-Max归一化我用的少,因为它对异常值太敏感了。
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
# Z-score标准化
scaler_std = StandardScaler()
X_std = scaler_std.fit_transform(X)
# Min-Max归一化
scaler_mm = MinMaxScaler()
X_mm = scaler_mm.fit_transform(X)
# Robust缩放
scaler_robust = RobustScaler()
X_robust = scaler_robust.fit_transform(X)
重要提醒: 标准化参数(均值、标准差、最小值、最大值)一定要从训练集计算,然后应用到测试集。千万别用全量数据计算,否则会造成数据泄露。我见过有人犯这个错,模型在测试集上表现虚高,实际部署后一塌糊涂。
2.4 特征工程基础
特征工程,说白了就是「造特征」。原始数据往往不够用,需要我们从领域知识出发,构造更有预测力的特征。
特征工程的三个层次:
- 特征选择:从现有特征中挑出最有用的。常用方法有方差阈值、相关系数、互信息、L1正则化。
- 特征提取:从原始数据中提取新特征。比如从时间序列中提取均值、方差、斜率、峰值。
- 特征构造:组合现有特征创造新特征。比如两个参数的比值、乘积、差值。
举个例子,在刻蚀工艺中,我经常构造这样的特征:
# 特征构造示例
data['RF_Power_Temp_Ratio'] = data['RF_Power'] / data['Temperature']
data['Pressure_Change_Rate'] = data['Pressure'].diff() / data['Pressure'].shift(1)
data['Time_Weighted_Avg'] = data['Etch_Rate'].rolling(window=5).mean()
我的经验: 特征工程最忌讳「闭门造车」。一定要和工艺工程师聊,了解哪些参数组合在物理上有意义。比如刻蚀速率和射频功率的比值,往往比单独看任何一个参数都更能反映设备状态。我曾经靠一个简单的比值特征,把模型准确率从82%提到了91%。
特征选择时,我常用这个方法:
from sklearn.feature_selection import SelectKBest, f_regression
# 选择与目标变量最相关的K个特征
selector = SelectKBest(score_func=f_regression, k=10)
X_selected = selector.fit_transform(X, y)
# 查看选中的特征
selected_features = X.columns[selector.get_support()]
print(f"选中的特征: {selected_features.tolist()}")
避坑指南: 特征数量不是越多越好。我见过有人构造了200多个特征,结果模型过拟合严重。一般来说,特征数量不要超过样本数量的1/10。如果样本只有1000条,特征控制在100个以内比较安全。
好了,以上就是数据采集与预处理的全部内容。数据准备阶段虽然枯燥,但它是整个良率分析的基石。你想想看,如果地基没打好,上面盖的房子再漂亮也是危房。下一章我们会进入真正的建模环节,到时候你就知道今天这些预处理工作有多重要了。
公众号:蓝海资料掘金营,微信deep3321