第三章 特征工程入门:从原始数据到模型养料
大家好,我是老张。今天咱们聊聊特征工程。说实话,这可能是整个模型训练里最“脏”最“累”的活,但也是回报最高的环节。我见过太多团队,模型结构调得飞起,最后效果上不去——十有八九是特征没做好。你想想看,模型再聪明,你喂给它的是垃圾,它也只能吐出垃圾。
核心观点:特征工程决定了模型效果的上限,算法只是逼近这个上限。
3.1 特征提取方法:把原始数据变成数字
特征提取,说白了就是把非结构化数据转成模型能理解的数值。我最早做运维日志分析时,面对一堆文本日志,完全不知道从哪下手。后来慢慢摸索出几套方法。
3.1.1 文本特征提取
运维系统里,日志、告警信息、配置文本,这些都是文本数据。常用的方法有:
- 词袋模型(Bag of Words):统计每个词出现的次数。简单粗暴,但会丢失词序信息。
- TF-IDF:不仅看词频,还看这个词在整个文档集合中的稀有程度。我个人习惯用这个做日志分类。
- Word2Vec / 词嵌入:把词映射到向量空间,能捕捉语义相似性。比如“宕机”和“故障”的向量距离会很近。
# 一个简单的TF-IDF示例
from sklearn.feature_extraction.text import TfidfVectorizer
logs = [
"服务器CPU使用率过高",
"内存泄漏导致服务重启",
"磁盘IO等待时间异常"
]
vectorizer = TfidfVectorizer()
features = vectorizer.fit_transform(logs)
print(features.toarray())
3.1.2 数值特征提取
数值型数据相对简单,但要注意尺度问题。我在项目中遇到过,CPU使用率(0-100)和内存大小(GB级别)放在一起,模型直接忽略了内存特征。所以标准化或归一化是必须的。
我的习惯:对于运维指标,我一般用Min-Max归一化,保留原始分布形态。对于异常检测,用Z-score标准化更合适。
3.2 特征选择策略:少即是多
特征不是越多越好。你想想看,100个特征里可能只有20个是真正有用的,剩下的全是噪声。我曾经接手过一个项目,同事提取了500多个特征,模型训练一次要3小时,效果还差。我帮他砍到50个,训练时间降到15分钟,准确率反而提升了5%。
3.2.1 过滤法
先算每个特征和目标变量的相关性,把相关性低的直接扔掉。常用的指标有:
- 皮尔逊相关系数:适合线性关系
- 卡方检验:适合分类问题
- 互信息:能捕捉非线性关系
3.2.2 包裹法
把特征选择看作一个搜索问题。比如递归特征消除(RFE),每次训练模型,去掉最不重要的特征,再训练,直到达到目标特征数。这种方法效果好,但计算量大。
3.2.3 嵌入法
在模型训练过程中自动选择特征。比如L1正则化(Lasso)会让不重要的特征系数变成0。决策树模型也会输出特征重要性排序。
避坑指南:我曾经用过滤法选了一堆高相关性的特征,结果模型过拟合严重。后来发现,特征之间如果高度相关(比如CPU使用率和CPU负载),保留一个就够了。这叫“多重共线性”,一定要注意。
3.3 时间序列特征构造:让模型理解“时间”
运维数据天生就是时间序列。CPU使用率、网络流量、磁盘空间,这些都是随时间变化的。模型需要理解“过去发生了什么”才能预测“未来会怎样”。
3.3.1 滞后特征
把过去时刻的值作为当前时刻的特征。比如预测下一小时的CPU使用率,可以把过去1小时、2小时、3小时的值都作为特征。
# 构造滞后特征示例
import pandas as pd
df['cpu_usage_lag1'] = df['cpu_usage'].shift(1)
df['cpu_usage_lag2'] = df['cpu_usage'].shift(2)
df['cpu_usage_lag3'] = df['cpu_usage'].shift(3)
3.3.2 滑动窗口统计
用过去一段时间内的统计量作为特征。比如过去5分钟的均值、最大值、最小值、标准差。我个人习惯用滑动窗口的均值作为平滑特征,用标准差作为波动特征。
3.3.3 时间编码
把时间本身变成特征。比如:
- 小时(0-23)
- 星期几(0-6)
- 是否工作日(0/1)
- 是否节假日(0/1)
嗯,这里要注意:小时、星期几这些是循环变量,直接用数值会丢失周期性。比如23点和0点其实很近,但数值上差23。我一般用正弦和余弦编码来处理。
经验之谈:做运维监控时,我发现“过去7天同一时刻的均值”这个特征特别有用。它能捕捉到业务的周期性规律,比如每天上午10点是访问高峰。
3.4 特征降维:化繁为简
特征太多怎么办?降维。降维不是简单地扔掉特征,而是把高维数据映射到低维空间,同时尽量保留原始信息。
3.4.1 PCA(主成分分析)
PCA是最常用的降维方法。它找到数据方差最大的方向,把数据投影上去。我习惯先做标准化,再做PCA,否则量纲大的特征会主导结果。
3.4.2 t-SNE
t-SNE主要用于可视化。它能保留数据的局部结构,把高维数据降到2维或3维,方便我们观察数据分布。但注意,t-SNE每次运行结果可能不同,不适合做特征工程。
3.4.3 自编码器
用神经网络做降维。输入层和输出层维度相同,中间层维度小,强迫网络学习到低维表示。这个方法效果好,但需要大量数据训练。
我的建议:如果特征数量在100以内,先用过滤法粗筛,再用嵌入法精筛。如果特征数量上千,直接上PCA或自编码器。别一上来就搞复杂的方法,先试试简单的。
好了,特征工程这块就聊到这儿。记住一句话:好的特征让模型事半功倍,烂的特征让模型生不如死。多花时间在特征上,绝对值得。