当前位置:首页 > Python 工业工具 > 正文内容

数据分析入门:用Python做异常检测

数据分析入门:用Python做异常检测

一、问题背景:125,000个数据怎么看?

去年做良率提升项目,工艺工程师每天要看的Lot数据长这样:

```

Lot A: 1250.1, 1248.5, 1251.2, 1249.8, 1250.3

Lot B: 1251.0, 1249.2, 1252.5, 1248.9, 1250.7

Lot 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 计算步骤

```python

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 Limit

lcl = mean - 3 * std # Lower Control Limit

print(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 先画个图,看看数据长什么样

代码和数据是分开理解的——先看图知道"正常是什么样",再看代码学"怎么算出来的"。

```python

import numpy as np

import 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', color='gray', alpha=0.6, label='数据点')

画控制线

mean = np.mean(normal)

std = np.std(normal)

plt.axhline(y=mean + 3*std, color='red', linestyle='--', label='UCL (+3σ)')

plt.axhline(y=mean, color='green', linestyle='-', label='均值')

plt.axhline(y=mean - 3*std, color='red', linestyle='--', label='LCL (-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',

markersize=8, label=f'异常({len(anomaly_idx)}个)')

plt.title('膜厚数据异常检测 (3-sigma)')

plt.xlabel('批次序号')

plt.ylabel('膜厚 (Å)')

plt.legend()

plt.grid(alpha=0.3)

plt.show()

```

这张图一出,拍领导桌子上——"看,红色的点就是异常批次"。

3.2 把检测逻辑封装成函数

```python

def detect_anomalies(data, sigma=3):

"""

3-sigma异常检测函数

参数:

data: numpy数组,一维数据

sigma: 控制限倍数(默认3)

返回:

dict: 包含检测结果

"""

mean = np.mean(data)

std = np.std(data)

ucl = mean + sigma * std

lcl = mean - sigma * std

anomaly_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)`。函数加上了参数默认值(`sigma=3`),FAB中不同参数的敏感度不同——膜厚用3,温度可能用2.5,浓度可能用3.5,传个参数就调了。

3.3 批量处理多批Lot

```python

模拟多批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环境,运行下面这个练习:

```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 + 3std) | (arr < mean - 3std)]

# ✏️ 请在下面添加你的代码

# 提示:计算异常数据点和正常数据点的比例

pass # 删除这行,写上你的代码

```

思考题

1. 如果sigma改成2会多检出多少异常?改成4呢?试试调参

2. 你的数据适合3-sigma吗?看看数据是不是近似正态分布

3. 除了3-sigma,还有没有其他判断"异常"的方法?

---

六、常见问题和进阶方向

新手常犯的错误

  • 忘记import numpy:调np.mean()前必须先写 `import numpy as np`
  • 列表和数组搞混:列表不能直接 `list > 3`,必须转成numpy数组
  • 标准差用错:`np.std()`默认是总体标准差,如果用样本标准差要加 `ddof=1`

可以继续学什么

1. IQR方法:不受极端值影响,适合非正态数据

2. Z-Score:把不同参数标准化后对比,方便跨参数排名

3. Isolation Forest:scikit-learn里的高级算法,多维度同时检测

4. 趋势检测:数据没超出控制线,但连续6个点一直上升——这也是异常信号

---

> 💬 你们FAB用什么方法判异常?3-sigma够用吗?评论区聊聊

> 📚 收藏+点赞,下次做SPC控制图用得上 👆

相关文章

FAB工程师学Python的正确路径(附学习地图)

FAB工程师学Python的正确路径(附学习地图)

FAB工程师学Python的正确路径(附学习地图) 我带过一个实习生,非科班出身,学了3个月Python,第一个月工资就涨了2000。 也有干了5年的工艺工程师,手动导数据画图画了5年,月薪还是那点钱...

Python+半导体数据工具完整自学路线(零基础→项目实战)

Python+半导体数据工具完整自学路线(零基础→项目实战)

Python+半导体数据工具完整自学路线(零基础→项目实战) 经常有人问我:我想学Python做FAB数据分析,从哪里开始? 今天我把完整路线画出来,从零基础到能独立做项目,按这个走,90天能出师。...

SPC/MES/FDC工具全家桶:工程师必备Python脚本合集

SPC/MES/FDC工具全家桶:工程师必备Python脚本合集

SPC/MES/FDC工具全家桶:工程师必备Python脚本合集 我在FAB干了15年,最值钱的东西不是经验,是一个攒了多年的Python工具箱。 今天把这个工具箱的核心部分分享出来,从数据采集到SP...

Python日报自动化:MES数据一键生成Excel报告(附完整源码)

Python日报自动化:MES数据一键生成Excel报告(附完整源码)

Python日报自动化:MES数据一键生成Excel报告(附完整源码) 1. 我的血泪史:每天2小时的日报工作 2018年,我在FAB做整合工程师的时候,每天早上第一件事不是分析数据,而是做日报。从M...

Python设备故障预测:XGBoost让FAB的设备维护从被动到主动

Python设备故障预测:XGBoost让FAB的设备维护从被动到主动

Python设备故障预测:XGBoost让FAB的设备维护从被动到主动 1. 问题背景:被动维修的代价 FAB里最贵的不是设备,是设备宕机造成的产能损失。一台光刻机价值$100M+,停机1小时损失约$...

Python晶圆良率分析实战:从数据清洗到可视化(附完整代码)

Python晶圆良率分析实战:从数据清洗到可视化(附完整代码)

Python晶圆良率分析实战:从数据清洗到可视化(附完整代码) 1. 问题背景:我的第一次良率分析 2016年,我在FAB做工艺工程师的时候,第一次被要求分析一批良率异常。工程师把数据发给我——一个E...