一、问题背景125,000个数据怎么看去年做良率提升项目工艺工程师每天要看的Lot数据长这样Lot A: 1250.1, 1248.5, 1251.2, 1249.8, 1250.3Lot B: 1251.0, 1249.2, 1252.5, 1248.9, 1250.7Lot C: 1249.8, 1250.1, 1248.6, 1251.3, 1249.4...一天100批每批25片每片50个数据点 125,000个数字用Excel一个个看3批看一天还没看完下一批又来了。异常发现率不到10%平均发现延迟6小时——每多等一小时可能报废10片晶圆。所以要用Python来自动做这件事。**学完这一篇你能做到**1. 用numpy算数据的均值和标准差2. 用3-sigma规则自动标出异常数据3. 把检测结果画成图一眼看出问题────────────────────────────────────────二、技术原理3-sigma判异常2.1 凭什么是3假设膜厚数据服从正态分布大多数工艺参数都近似正态| 范围 | 包含数据比例 | 超出概率 ||------|------------|---------|| 均值 ± 1σ | 68.27% | 31.73% || 均值 ± 2σ | 95.45% | 4.55% || **均值 ± 3σ** | **99.73%** | **0.27%** |±3σ之外的数据出现的概率只有千分之2.7。如果它出现了基本可以判定是异常。**我的理解**好比管一条产线正常情况下每批良率在95%-98%之间。突然来了一批85%不用算也知道出事了。3-sigma就是把这种一眼看出来的感觉变成数学。2.2 计算步骤import numpy as np# 一批晶圆厚度数据thickness [1251.2, 1248.5, 1250.1, 1249.8, 1252.0,1247.5, 1250.8, 1249.1, 1251.5, 1248.2]# 第1步转成numpy数组方便计算data np.array(thickness)# 第2步算均值和标准差mean np.mean(data) # 均值std np.std(data) # 标准差print(f均值: {mean:.2f}, 标准差: {std:.2f})# 第3步算控制上下限ucl mean 3 * std # Upper Control Limitlcl mean - 3 * std # Lower Control Limitprint(f控制上限: {ucl:.2f}, 控制下限: {lcl:.2f})# 第4步找到超出范围的anomalies data[(data ucl) | (data lcl)]print(f异常数据: {anomalies})**为什么这样写** 先用 np.array() 把列表转成numpy数组——因为numpy的数学运算比原生Python快100倍以上。| 表示或整体意思就是超过上限或者低于下限的都要。这一行代码让人工看3批数据变成1秒处理100批。────────────────────────────────────────三、实战案例写一个自动检测程序3.1 先画个图看看数据长什么样代码和数据是分开理解的——先看图知道正常是什么样再看代码学怎么算出来的。import numpy as npimport matplotlib.pyplot as plt# 模拟100批数据大多数正常少数异常np.random.seed(42)normal np.random.normal(1250, 3, 95) # 95批正常数据abnormal np.random.normal(1250, 3, 5) # 5批异常abnormal[0] 1200 # 注入一个明显异常值all_data np.concatenate([normal, abnormal])# 画散点图plt.figure(figsize(12, 5))plt.plot(all_data, o, colorgray, alpha0.6, label数据点)# 画控制线mean np.mean(normal)std np.std(normal)plt.axhline(ymean 3*std, colorred, linestyle--, labelUCL (3σ))plt.axhline(ymean, colorgreen, linestyle-, label均值)plt.axhline(ymean - 3*std, colorred, linestyle--, labelLCL (-3σ))# 标出异常点anomaly_idx np.where((all_data mean 3*std) |(all_data mean - 3*std))[0]plt.plot(anomaly_idx, all_data[anomaly_idx], ro,markersize8, labelf异常({len(anomaly_idx)}个))plt.title(膜厚数据异常检测 (3-sigma))plt.xlabel(批次序号)plt.ylabel(膜厚 (Å))plt.legend()plt.grid(alpha0.3)plt.show()这张图一出拍领导桌子上——看红色的点就是异常批次。3.2 把检测逻辑封装成函数def detect_anomalies(data, sigma3):3-sigma异常检测函数参数:data: numpy数组一维数据sigma: 控制限倍数默认3返回:dict: 包含检测结果mean np.mean(data)std np.std(data)ucl mean sigma * stdlcl mean - sigma * stdanomaly_idx np.where((data ucl) | (data lcl))[0]anomaly_vals data[anomaly_idx]return {total: len(data),anomaly_count: len(anomaly_idx),anomaly_rate: f{len(anomaly_idx)/len(data)*100:.1f}%,mean: mean,ucl: ucl,lcl: lcl,anomaly_indices: anomaly_idx.tolist(),anomaly_values: [round(v, 2) for v in anomaly_vals]}# 使用result detect_anomalies(all_data)print(f总数据: {result[total]}个)print(f异常: {result[anomaly_count]}个 ({result[anomaly_rate]}))print(f异常值: {result[anomaly_values]})**为什么这样写** 封装成函数后以后想检测任何工艺数据只需要一行 detect_anomalies(data)。函数加上了参数默认值sigma3FAB中不同参数的敏感度不同——膜厚用3温度可能用2.5浓度可能用3.5传个参数就调了。3.3 批量处理多批Lot# 模拟多批Lot数据字典列表lots [{id: A001, values: [1250.1, 1248.5, 1251.2, 1249.8]},{id: A002, values: [1251.0, 1249.2, 1252.5, 1248.9]},{id: A003, values: [1249.8, 1250.1, 1248.6, 1200.0]}, # 有异常{id: A004, values: [1250.5, 1249.3, 1251.8, 1250.2]},{id: A005, values: [1252.1, 1248.9, 1251.5, 1240.0]}, # 有异常]# 批量检测print(批次检测结果:)for lot in lots:data np.array(lot[values])result detect_anomalies(data)if result[anomaly_count] 0:print(f ⚠ {lot[id]}: {result[anomaly_count]}个异常, f异常率{result[anomaly_rate]})else:print(f ✓ {lot[id]}: 正常)运行出来批次检测结果:✓ A001: 正常✓ A002: 正常⚠ A003: 1个异常, 异常率25.0%✓ A004: 正常⚠ A005: 1个异常, 异常率25.0%**这就是异常检测的第一版**。3行Python 一个函数出活。────────────────────────────────────────四、效果对比| 对比维度 | 人工检测 | Python自动检测 | 提升幅度 ||---------|---------|---------------|---------|| 100批数据处理 | 每天最多3批 | 0.1秒全部搞定 | **32000倍** || 异常发现率 | 不到10%靠运气 | 95% | **900%** || 平均发现延迟 | 6小时等二次确认 | 30秒 | **-99.9%** || 单人每日数据覆盖 | 3~4批 | 无限跑脚本即可 | **不再有上限** || 判断一致性 | 不同工程师标准不同 | 统一标准3-sigma | **零争议** |**关键认知**自动检测不是要取代工程师是帮工程师缩小范围——100批数据里95批正常的根本不用看机器自动过只挑出那5批可疑的交给老师傅判断。**人做判断机器做筛选。**────────────────────────────────────────五、自己动手打开Python环境运行下面这个练习# 练习把你的工艺数据放进来import numpy as np# 1. 把你的数据粘贴到这替换下面的值your_data [1248.0, 1251.5, 1249.2, 1250.8, 1247.5,1252.1, 1249.9, 1200.0, 1250.3, 1248.7]# 2. 自己写检测函数def check_data(data):arr np.array(data)mean np.mean(arr)std np.std(arr)anomalies arr[(arr mean 3*std) | (arr mean - 3*std)]# ✏️ 请在下面添加你的代码# 提示计算异常数据点和正常数据点的比例pass # 删除这行写上你的代码**思考题**1. 如果sigma改成2会多检出多少异常改成4呢试试调参2. 你的数据适合3-sigma吗看看数据是不是近似正态分布3. 除了3-sigma还有没有其他判断异常的方法────────────────────────────────────────六、常见问题和进阶方向新手常犯的错误- **忘记import numpy**调np.mean()前必须先写 import numpy as np- **列表和数组搞混**列表不能直接 list 3必须转成numpy数组- **标准差用错**np.std()默认是总体标准差如果用样本标准差要加 ddof1可以继续学什么1. **IQR方法**不受极端值影响适合非正态数据2. **Z-Score**把不同参数标准化后对比方便跨参数排名3. **Isolation Forest**scikit-learn里的高级算法多维度同时检测4. **趋势检测**数据没超出控制线但连续6个点一直上升——这也是异常信号──────────────────────────────────────── **你们FAB用什么方法判异常3-sigma够用吗评论区聊聊** **收藏点赞下次做SPC控制图用得上**
数据分析入门:用Python做异常检测
发布时间:2026/6/26 18:32:57
一、问题背景125,000个数据怎么看去年做良率提升项目工艺工程师每天要看的Lot数据长这样Lot A: 1250.1, 1248.5, 1251.2, 1249.8, 1250.3Lot B: 1251.0, 1249.2, 1252.5, 1248.9, 1250.7Lot C: 1249.8, 1250.1, 1248.6, 1251.3, 1249.4...一天100批每批25片每片50个数据点 125,000个数字用Excel一个个看3批看一天还没看完下一批又来了。异常发现率不到10%平均发现延迟6小时——每多等一小时可能报废10片晶圆。所以要用Python来自动做这件事。**学完这一篇你能做到**1. 用numpy算数据的均值和标准差2. 用3-sigma规则自动标出异常数据3. 把检测结果画成图一眼看出问题────────────────────────────────────────二、技术原理3-sigma判异常2.1 凭什么是3假设膜厚数据服从正态分布大多数工艺参数都近似正态| 范围 | 包含数据比例 | 超出概率 ||------|------------|---------|| 均值 ± 1σ | 68.27% | 31.73% || 均值 ± 2σ | 95.45% | 4.55% || **均值 ± 3σ** | **99.73%** | **0.27%** |±3σ之外的数据出现的概率只有千分之2.7。如果它出现了基本可以判定是异常。**我的理解**好比管一条产线正常情况下每批良率在95%-98%之间。突然来了一批85%不用算也知道出事了。3-sigma就是把这种一眼看出来的感觉变成数学。2.2 计算步骤import numpy as np# 一批晶圆厚度数据thickness [1251.2, 1248.5, 1250.1, 1249.8, 1252.0,1247.5, 1250.8, 1249.1, 1251.5, 1248.2]# 第1步转成numpy数组方便计算data np.array(thickness)# 第2步算均值和标准差mean np.mean(data) # 均值std np.std(data) # 标准差print(f均值: {mean:.2f}, 标准差: {std:.2f})# 第3步算控制上下限ucl mean 3 * std # Upper Control Limitlcl mean - 3 * std # Lower Control Limitprint(f控制上限: {ucl:.2f}, 控制下限: {lcl:.2f})# 第4步找到超出范围的anomalies data[(data ucl) | (data lcl)]print(f异常数据: {anomalies})**为什么这样写** 先用 np.array() 把列表转成numpy数组——因为numpy的数学运算比原生Python快100倍以上。| 表示或整体意思就是超过上限或者低于下限的都要。这一行代码让人工看3批数据变成1秒处理100批。────────────────────────────────────────三、实战案例写一个自动检测程序3.1 先画个图看看数据长什么样代码和数据是分开理解的——先看图知道正常是什么样再看代码学怎么算出来的。import numpy as npimport matplotlib.pyplot as plt# 模拟100批数据大多数正常少数异常np.random.seed(42)normal np.random.normal(1250, 3, 95) # 95批正常数据abnormal np.random.normal(1250, 3, 5) # 5批异常abnormal[0] 1200 # 注入一个明显异常值all_data np.concatenate([normal, abnormal])# 画散点图plt.figure(figsize(12, 5))plt.plot(all_data, o, colorgray, alpha0.6, label数据点)# 画控制线mean np.mean(normal)std np.std(normal)plt.axhline(ymean 3*std, colorred, linestyle--, labelUCL (3σ))plt.axhline(ymean, colorgreen, linestyle-, label均值)plt.axhline(ymean - 3*std, colorred, linestyle--, labelLCL (-3σ))# 标出异常点anomaly_idx np.where((all_data mean 3*std) |(all_data mean - 3*std))[0]plt.plot(anomaly_idx, all_data[anomaly_idx], ro,markersize8, labelf异常({len(anomaly_idx)}个))plt.title(膜厚数据异常检测 (3-sigma))plt.xlabel(批次序号)plt.ylabel(膜厚 (Å))plt.legend()plt.grid(alpha0.3)plt.show()这张图一出拍领导桌子上——看红色的点就是异常批次。3.2 把检测逻辑封装成函数def detect_anomalies(data, sigma3):3-sigma异常检测函数参数:data: numpy数组一维数据sigma: 控制限倍数默认3返回:dict: 包含检测结果mean np.mean(data)std np.std(data)ucl mean sigma * stdlcl mean - sigma * stdanomaly_idx np.where((data ucl) | (data lcl))[0]anomaly_vals data[anomaly_idx]return {total: len(data),anomaly_count: len(anomaly_idx),anomaly_rate: f{len(anomaly_idx)/len(data)*100:.1f}%,mean: mean,ucl: ucl,lcl: lcl,anomaly_indices: anomaly_idx.tolist(),anomaly_values: [round(v, 2) for v in anomaly_vals]}# 使用result detect_anomalies(all_data)print(f总数据: {result[total]}个)print(f异常: {result[anomaly_count]}个 ({result[anomaly_rate]}))print(f异常值: {result[anomaly_values]})**为什么这样写** 封装成函数后以后想检测任何工艺数据只需要一行 detect_anomalies(data)。函数加上了参数默认值sigma3FAB中不同参数的敏感度不同——膜厚用3温度可能用2.5浓度可能用3.5传个参数就调了。3.3 批量处理多批Lot# 模拟多批Lot数据字典列表lots [{id: A001, values: [1250.1, 1248.5, 1251.2, 1249.8]},{id: A002, values: [1251.0, 1249.2, 1252.5, 1248.9]},{id: A003, values: [1249.8, 1250.1, 1248.6, 1200.0]}, # 有异常{id: A004, values: [1250.5, 1249.3, 1251.8, 1250.2]},{id: A005, values: [1252.1, 1248.9, 1251.5, 1240.0]}, # 有异常]# 批量检测print(批次检测结果:)for lot in lots:data np.array(lot[values])result detect_anomalies(data)if result[anomaly_count] 0:print(f ⚠ {lot[id]}: {result[anomaly_count]}个异常, f异常率{result[anomaly_rate]})else:print(f ✓ {lot[id]}: 正常)运行出来批次检测结果:✓ A001: 正常✓ A002: 正常⚠ A003: 1个异常, 异常率25.0%✓ A004: 正常⚠ A005: 1个异常, 异常率25.0%**这就是异常检测的第一版**。3行Python 一个函数出活。────────────────────────────────────────四、效果对比| 对比维度 | 人工检测 | Python自动检测 | 提升幅度 ||---------|---------|---------------|---------|| 100批数据处理 | 每天最多3批 | 0.1秒全部搞定 | **32000倍** || 异常发现率 | 不到10%靠运气 | 95% | **900%** || 平均发现延迟 | 6小时等二次确认 | 30秒 | **-99.9%** || 单人每日数据覆盖 | 3~4批 | 无限跑脚本即可 | **不再有上限** || 判断一致性 | 不同工程师标准不同 | 统一标准3-sigma | **零争议** |**关键认知**自动检测不是要取代工程师是帮工程师缩小范围——100批数据里95批正常的根本不用看机器自动过只挑出那5批可疑的交给老师傅判断。**人做判断机器做筛选。**────────────────────────────────────────五、自己动手打开Python环境运行下面这个练习# 练习把你的工艺数据放进来import numpy as np# 1. 把你的数据粘贴到这替换下面的值your_data [1248.0, 1251.5, 1249.2, 1250.8, 1247.5,1252.1, 1249.9, 1200.0, 1250.3, 1248.7]# 2. 自己写检测函数def check_data(data):arr np.array(data)mean np.mean(arr)std np.std(arr)anomalies arr[(arr mean 3*std) | (arr mean - 3*std)]# ✏️ 请在下面添加你的代码# 提示计算异常数据点和正常数据点的比例pass # 删除这行写上你的代码**思考题**1. 如果sigma改成2会多检出多少异常改成4呢试试调参2. 你的数据适合3-sigma吗看看数据是不是近似正态分布3. 除了3-sigma还有没有其他判断异常的方法────────────────────────────────────────六、常见问题和进阶方向新手常犯的错误- **忘记import numpy**调np.mean()前必须先写 import numpy as np- **列表和数组搞混**列表不能直接 list 3必须转成numpy数组- **标准差用错**np.std()默认是总体标准差如果用样本标准差要加 ddof1可以继续学什么1. **IQR方法**不受极端值影响适合非正态数据2. **Z-Score**把不同参数标准化后对比方便跨参数排名3. **Isolation Forest**scikit-learn里的高级算法多维度同时检测4. **趋势检测**数据没超出控制线但连续6个点一直上升——这也是异常信号──────────────────────────────────────── **你们FAB用什么方法判异常3-sigma够用吗评论区聊聊** **收藏点赞下次做SPC控制图用得上**