第四章:探索性数据分析(EDA)——先别急着建模,看看数据长啥样
大家好,我是你们的老朋友。今天咱们聊聊EDA,也就是探索性数据分析。
说实话,我见过太多工程师拿到数据就急着跑模型,结果跑出来一堆垃圾。为什么?因为连数据长什么样都没搞清楚。我个人习惯,拿到数据的第一件事,就是做EDA。这就像你拿到一块晶圆,总得先看看表面有没有划痕、颗粒吧?
4.1 描述性统计:给数据做个“体检”
描述性统计,说白了就是用几个数字把数据的“脾气”概括出来。比如均值、中位数、标准差、最小值、最大值等等。
我举个例子。假设我们有一批晶圆的膜厚数据(单位:Å):
import pandas as pd
import numpy as np
# 模拟膜厚数据
np.random.seed(42)
data = {
'膜厚': np.random.normal(5000, 100, 1000),
'均匀性': np.random.uniform(1, 5, 1000),
'颗粒数': np.random.poisson(10, 1000)
}
df = pd.DataFrame(data)
# 描述性统计
print(df.describe())
输出结果大概长这样:
| 统计量 | 膜厚 | 均匀性 | 颗粒数 |
|---|---|---|---|
| count | 1000.0 | 1000.0 | 1000.0 |
| mean | 5001.2 | 3.01 | 9.85 |
| std | 98.5 | 1.15 | 3.12 |
| min | 4702.3 | 1.02 | 2.0 |
| 25% | 4935.6 | 2.01 | 8.0 |
| 50% | 5000.8 | 3.00 | 10.0 |
| 75% | 5068.1 | 4.00 | 12.0 |
| max | 5298.7 | 4.98 | 20.0 |
关键点:均值和中位数如果相差很大,说明数据有偏。比如膜厚均值5001,中位数5000,基本对称。但如果均值远大于中位数,那就要小心了——可能有异常值在拉高均值。
我在项目中遇到过一件事。有一次测一批晶圆的电阻率,均值看起来正常,但中位数明显偏低。后来一查,原来是某台机台的探针接触不良,导致几个点测出超高值。嗯,这就是描述性统计的价值——帮你发现“不对劲”。
4.2 数据分布可视化:用图说话
数字再漂亮,也不如图片直观。我习惯先看直方图,再看箱线图。
4.2.1 直方图:看数据的“身材”
直方图能告诉你数据是胖是瘦,是左偏还是右偏。
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(10, 6))
sns.histplot(df['膜厚'], bins=30, kde=True)
plt.title('膜厚分布直方图')
plt.xlabel('膜厚 (Å)')
plt.ylabel('频数')
plt.show()
你想想看,如果直方图出现双峰,那很可能意味着你的数据来自两个不同的工艺条件。我曾经帮一个同事排查良率问题,发现膜厚数据呈现明显的双峰分布。后来一查,原来是两台CVD机台的工艺参数没对齐。
小技巧:bins的数量不要太多也不要太少。我个人习惯用30-50个bins,太少会丢失细节,太多会显得杂乱。
4.2.2 箱线图:揪出异常值
箱线图是抓异常值的神器。它用四分位数来展示数据的分布,超出“触须”的点就是潜在的异常值。
plt.figure(figsize=(8, 6))
sns.boxplot(data=df[['膜厚', '均匀性', '颗粒数']])
plt.title('关键参数箱线图')
plt.show()
箱线图里,那些孤零零的小圆点,就是异常值。我曾经有一次,箱线图显示某批晶圆的颗粒数异常高。排查后发现,是光刻胶的过滤芯该换了。你看,一个简单的箱线图,就能帮你省下几万块的报废成本。
注意:不要一看到异常值就删除。先搞清楚原因——是测量误差?还是工艺异常?还是正常波动?我曾经因为误删了“异常值”,结果把一批良品给报废了,教训深刻。
4.3 相关性分析:找找谁在“勾搭”谁
EDA里我最喜欢的一步,就是看相关性。说白了,就是看看哪些参数之间有关系,关系有多强。
4.3.1 热力图:一目了然
# 计算相关系数矩阵
corr_matrix = df.corr()
# 绘制热力图
plt.figure(figsize=(8, 6))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', fmt='.2f')
plt.title('参数相关性热力图')
plt.show()
热力图里,颜色越深,相关性越强。红色代表正相关,蓝色代表负相关。
我记得有一次,我发现膜厚和均匀性之间的相关系数高达0.85。这意味着什么?膜厚越厚,均匀性越差。后来我们调整了工艺参数,把膜厚降下来,均匀性果然改善了。这就是相关性分析的价值——帮你找到工艺优化的方向。
注意:相关性不等于因果性。两个参数相关,不代表一个导致另一个。比如,晶圆上的颗粒数和温度可能相关,但真正的原因可能是湿度。别被相关性骗了。
4.4 数据质量报告:给数据“打分”
EDA的最后一步,是生成数据质量报告。这份报告会告诉你:数据有多少缺失值?有没有重复值?数据类型对不对?
def data_quality_report(df):
report = pd.DataFrame({
'列名': df.columns,
'数据类型': df.dtypes,
'非空值数': df.count(),
'缺失值数': df.isnull().sum(),
'缺失率(%)': (df.isnull().sum() / len(df)) * 100,
'唯一值数': df.nunique(),
'重复行数': [df.duplicated().sum()] * len(df.columns)
})
return report
print(data_quality_report(df))
输出示例:
| 列名 | 数据类型 | 非空值数 | 缺失值数 | 缺失率(%) | 唯一值数 |
|---|---|---|---|---|---|
| 膜厚 | float64 | 1000 | 0 | 0.0 | 1000 |
| 均匀性 | float64 | 998 | 2 | 0.2 | 998 |
| 颗粒数 | int64 | 1000 | 0 | 0.0 | 15 |
我的习惯:缺失率超过5%的列,我会特别关注。如果缺失是随机的,可以用均值或中位数填充。但如果缺失是有规律的(比如某台机台的数据全缺),那就要查查是不是数据采集出了问题。
我曾经遇到过一个案例,某批数据的“温度”列缺失率高达30%。一开始以为是传感器故障,后来发现是数据采集程序的一个bug——当温度超过设定阈值时,程序会跳过记录。嗯,这就是典型的非随机缺失,处理起来要格外小心。
知识体系总览
下面这张图,是我自己总结的EDA核心逻辑,你一看就明白:
这张图把EDA的四个核心步骤串起来了。从原始数据出发,先做描述性统计,再看分布,然后分析相关性,最后出质量报告。每一步都有它的价值,缺一不可。
好了,EDA的内容就讲到这里。记住,EDA不是走过场,它是你数据分析的“第一道防线”。花时间把数据摸透了,后面的建模和分析才能事半功倍。
公众号:蓝海资料掘金营,微信deep3321