3、数据预处理优化:特征工程、数据清洗、归一化与标准化、降维技术(PCA)

大家好,我是你们的老朋友。今天咱们来聊聊数据预处理。说实话,我见过太多人一上来就调模型,结果跑出来的结果惨不忍睹。为什么?因为数据没洗干净,特征没选好。你想想看,垃圾进,垃圾出,这是铁律。

我个人习惯,拿到数据的第一件事,不是急着建模,而是先花 70% 的时间做预处理。这听起来有点夸张,但实际项目中,这一步往往决定了最终效果的 80%。

3.1 特征工程:从原始数据中挖金子

特征工程,说白了就是把原始数据变成模型能听懂的语言。我遇到过最典型的例子:一个电商数据集里,用户注册时间是个时间戳,模型根本看不懂。怎么办?拆!拆成年、月、日、星期几、是否节假日。模型一下子就开窍了。

常用的特征工程方法,我列几个:

  • 特征提取:从文本里提取 TF-IDF,从图片里提取像素值。
  • 特征构造:比如把「购买次数」和「总金额」组合成「客单价」。
  • 特征选择:去掉那些跟目标变量八竿子打不着的特征。
我的小技巧: 做特征工程时,多跟业务方聊聊。有一次我硬生生从业务日志里挖出「用户点击间隔时间」这个特征,模型 AUC 直接涨了 5 个点。业务知识,有时候比算法更值钱。

3.2 数据清洗:别让脏数据毁了你的模型

数据清洗,听着简单,做起来全是坑。我刚开始做项目时,就吃过一次大亏。一个回归任务,数据里有个字段是「年龄」,结果有人填了 200 岁。模型训练完,预测结果直接飘了。嗯,从那以后,我每次都会先做数据清洗。

常见的脏数据问题:

  • 缺失值:直接删掉?还是用均值/中位数填充?我建议先看看缺失比例。如果超过 50%,这列基本可以扔了。如果不多,用中位数填充更稳健。
  • 异常值:比如收入字段出现负数。我习惯用 3σ 原则或者 IQR 方法检测,然后视情况截断或剔除。
  • 重复数据:这个简单,直接去重。但要注意,有些重复是业务上合理的,别一刀切。
避坑指南: 我曾经在处理缺失值时,直接用 0 填充了所有空值。结果模型学出来一堆奇怪的规律。后来才发现,有些缺失值代表「用户未操作」,跟 0 完全是两码事。所以,填充前一定要搞清楚缺失值的含义。

3.3 归一化与标准化:让特征站在同一起跑线

为什么需要归一化和标准化?你想想看,如果特征 A 的取值范围是 0~1,特征 B 是 0~10000,模型会天然觉得 B 更重要。这显然不合理。

我常用的两种方法:

方法 公式 适用场景
归一化 (Min-Max Scaling) (x - min) / (max - min) 数据有明确边界,比如像素值 0~255
标准化 (Z-score Normalization) (x - μ) / σ 数据分布近似正态,或者有异常值

我个人习惯,如果数据里没有明显的异常值,优先用标准化。因为归一化对异常值太敏感了——一个 10000 的异常值,能把其他所有数据压缩到 0.0001 附近,模型直接废了。

代码实现也很简单:

from sklearn.preprocessing import StandardScaler, MinMaxScaler

# 标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 归一化
scaler = MinMaxScaler()
X_normalized = scaler.fit_transform(X)
注意: 一定要先拆分训练集和测试集,再用训练集的参数去变换测试集。千万别把测试集的数据混进来算均值和方差,否则会造成数据泄露,模型评估结果会虚高。

3.4 降维技术(PCA):化繁为简的艺术

降维,说白了就是用更少的特征,表达尽可能多的信息。PCA(主成分分析)是我最常用的方法。它的核心思想很简单:找到数据方差最大的方向,把数据投影上去。

为什么用 PCA?我遇到过这样一个项目:特征有 1000 多个,模型训练一次要 3 小时。用 PCA 降到 50 维后,训练时间缩短到 10 分钟,效果只掉了 1%。这买卖,划算。

下面这张图,展示了 PCA 的核心逻辑:

PC1 PC2 投影到 PC1 上 降维 PCA 降维示意图 二维数据 → 一维主成分

使用 PCA 时,有几个关键点:

  • 先标准化:PCA 对特征的尺度敏感。如果特征 A 是 0~1,特征 B 是 0~10000,PCA 会优先抓住 B 的方差。所以,跑 PCA 之前,一定要先做标准化。
  • 选择主成分数量:我一般看累计方差贡献率。保留 95% 的方差,通常就够了。代码里用 pca.explained_variance_ratio_ 就能看到。
  • 可解释性:降维后的特征,往往失去了物理含义。如果你需要跟业务方解释「为什么这个特征重要」,PCA 可能不太合适。这时候可以考虑 t-SNE 或者 UMAP。

代码示例:

from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

# 先标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# PCA 降维,保留 95% 方差
pca = PCA(n_components=0.95)
X_pca = pca.fit_transform(X_scaled)

print(f"原始特征数: {X.shape[1]}")
print(f"降维后特征数: {X_pca.shape[1]}")
print(f"各主成分方差占比: {pca.explained_variance_ratio_}")
我的经验: 有一次做图像识别,原始特征 4096 维,模型训练慢得要命。用 PCA 降到 100 维后,训练时间从 2 小时降到 5 分钟,准确率只掉了 0.3%。但要注意,PCA 是线性降维,如果数据是非线性的,效果可能不好。这时候可以试试核 PCA。

好了,数据预处理这块,核心就是这些。特征工程、数据清洗、归一化标准化、PCA 降维,每一步都值得你花时间打磨。记住,模型的好坏,90% 取决于数据质量。把数据收拾利索了,模型自然就听话了。


专注资料整理