数据采集与特征工程:数据源选择、数据清洗、特征提取、特征选择方法

做智能决策模型这么多年,我越来越觉得一句话特别对:「数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限」。说白了,你模型再花哨,喂进去的是垃圾,出来的还是垃圾。今天咱们就聊聊这个「喂食」的过程——数据采集与特征工程。

核心观点:特征工程不是锦上添花,而是模型成败的基石。我见过太多团队花80%的时间调参,却不愿意花20%的时间做特征,结果模型上线后一塌糊涂。

一、数据源选择:从哪里找「好米」?

数据源的选择,其实是个「找米下锅」的活。我个人习惯把数据源分成三类:

  • 内部数据:公司数据库、日志系统、业务系统。这是最靠谱的,但往往有权限壁垒。
  • 公开数据:政府开放数据、学术数据集、行业报告。质量参差不齐,需要仔细甄别。
  • 外部采购:第三方数据服务商。价格不菲,但有时能解决燃眉之急。

我在项目中遇到过一个问题:某次做用户画像模型,内部数据只有交易记录,缺少用户行为数据。后来我们接入了第三方埋点数据,才把模型效果提上去。嗯,这里要注意:数据源的「相关性」比「量」更重要。你想想看,100万条无关数据,不如1万条精准数据。

我的经验:选数据源时,先问自己三个问题:1)这个数据能直接或间接反映目标变量吗?2)数据采集成本是否可控?3)数据更新频率是否满足业务需求?

二、数据清洗:把「脏米」淘干净

数据清洗,说白了就是「去伪存真」。我刚开始做数据时,总觉得这步可有可无,直到有一次模型训练完,发现准确率奇高——后来一查,原来是数据里有大量重复样本,模型「作弊」了。从那以后,我再也不敢跳过数据清洗了。

常见的脏数据问题:

问题类型 表现 处理方法
缺失值 字段为空或NaN 删除、均值填充、插值、模型预测填充
异常值 明显偏离正常范围 3σ原则、IQR方法、业务规则过滤
重复值 完全相同的记录 去重(注意业务含义)
格式不一致 日期格式、单位不统一 标准化处理

举个例子,处理缺失值时,我一般这样写:

# 缺失值处理示例
import pandas as pd
import numpy as np

# 数值型特征:用中位数填充(比均值更鲁棒)
df['age'].fillna(df['age'].median(), inplace=True)

# 类别型特征:用众数填充
df['gender'].fillna(df['gender'].mode()[0], inplace=True)

# 时间序列:用前向填充
df['temperature'].fillna(method='ffill', inplace=True)

避坑指南:我曾经犯过一个错——把所有缺失值都填充为0。结果模型学到的规律全是错的。缺失值本身可能就包含信息,比如「用户未填写收入」可能暗示其收入不稳定。所以,先分析缺失原因,再决定处理方式

三、特征提取:从「米」到「饭」的转化

特征提取,就是把原始数据变成模型能理解的形式。说白了,就是「翻译」工作。机器只认数字,你得把文本、图片、时间、类别都翻译成数字。

常见的特征提取方法:

  • 数值型特征:直接使用,或做对数变换、标准化、分箱
  • 类别型特征:独热编码、标签编码、目标编码
  • 文本特征:TF-IDF、词嵌入、词袋模型
  • 时间特征:年、月、日、星期、是否为节假日、时间差
  • 组合特征:特征交叉、多项式特征

我记得有一次做电商推荐模型,原始数据只有「购买时间」和「商品ID」两个字段。后来我提取了「用户最近一次购买距今的天数」「用户购买同一类商品的频率」「用户购买时间段的偏好」等特征,模型AUC直接从0.72提升到了0.85。你想想看,这就是特征提取的魔力。

一个小技巧:做特征提取时,多问问自己「这个特征在业务上意味着什么?」。比如「用户凌晨3点下单」这个特征,可能暗示用户是夜猫子,或者有紧急需求。这种业务理解,往往是特征提取的灵感来源。

四、特征选择:去粗取精,留下「好米」

特征太多不是好事。我见过一个项目,工程师提取了500多个特征,结果模型训练慢得像蜗牛,还容易过拟合。特征选择,就是帮你「去粗取精」。

常用的特征选择方法:

  1. 过滤法:根据统计指标筛选(方差、相关系数、卡方检验)
  2. 包裹法:用模型效果来评估特征子集(递归特征消除RFE)
  3. 嵌入法:在模型训练过程中自动选择(L1正则化、树模型特征重要性)

我个人最常用的是嵌入法,尤其是基于树模型的特征重要性。为什么呢?因为它既考虑了特征与目标的关系,又考虑了特征之间的交互,而且计算效率高。

# 基于随机森林的特征重要性
from sklearn.ensemble import RandomForestClassifier

model = RandomForestClassifier(n_estimators=100)
model.fit(X_train, y_train)

# 获取特征重要性
importances = model.feature_importances_
indices = np.argsort(importances)[::-1]

# 打印前10个重要特征
for i in range(10):
    print(f"特征 {indices[i]}: 重要性 {importances[indices[i]]:.4f}")

避坑指南:我曾经用相关系数做特征选择,把相关性低的特征全删了。结果模型效果反而下降了。为什么?因为有些特征虽然与目标变量相关性不高,但与其他特征组合后能产生很强的预测能力。所以,特征选择不能只看单变量关系,还要考虑特征间的交互

五、知识体系总览

下面这张图,是我梳理的数据采集与特征工程的整体流程。你可以把它当作一个「路线图」,做项目时对照着来,基本不会跑偏。

数据采集与特征工程知识体系 数据源选择 数据清洗 特征提取 内部数据 公开数据 外部采购 缺失值处理 异常值检测 重复值去重 数值/类别特征 文本/时间特征 组合特征 特征选择 过滤法 包裹法 嵌入法

这张图把整个流程串起来了。从数据源选择开始,到数据清洗、特征提取,最后到特征选择。每一步都有对应的技术和方法。做项目时,你可以把它当作一个checklist,确保每个环节都做到位。

最后说一句:特征工程没有银弹。同样的方法,在这个数据集上效果好,换一个数据集可能就失效了。我的建议是:多尝试、多对比、多思考业务含义。做得多了,你自然会有感觉。

专注资料整理