机器学习实践(18):特征工程
第十八篇:特征工程到底在做什么——为什么很多时候数据比模型更重要
很多人刚开始学机器学习的时候,最容易把注意力全放在模型上。
比如:
- 这题该用逻辑回归还是随机森林?
- 要不要试试 XGBoost?
- SVM 会不会比 KNN 更准?
- 参数是不是还能再调一下?
这些问题当然都重要。
但如果你真的开始做一个完整项目,很快就会发现一件很现实的事:
模型能发挥到什么程度,很大程度上取决于你喂给它什么样的特征。
换句话说,模型不是凭空变聪明的。
它只能在你提供的信息上做判断。
如果你给它的特征本身就不够好、不够稳定、不够贴近问题本质,那模型再高级,也很难凭空补出真正有效的信息。
这就是为什么在机器学习里,总有人会说:
很多时候,数据和特征比模型更重要。
这句话听起来像鸡汤,但它其实非常现实。
这一篇我们就专门讲清楚:
特征工程到底是什么,它为什么重要,它通常在做什么,又容易踩什么坑。
1. 先说最核心的一句:特征工程是在帮模型更容易看到规律
如果你只记一句话,我建议你记这句:
特征工程的本质,是把原始数据变成更适合模型学习的表达。
这里面有两个关键词:
- 原始数据
- 更适合模型学习的表达
很多真实数据,并不是天然就长成“模型一看就明白”的样子。
你得先把它整理、转换、组合、提炼,让真正和任务有关的结构更容易被模型捕捉。
也就是说,特征工程并不是在“制造魔法”,而是在做一件很朴素但很关键的事:
把问题翻译成模型更容易理解的形式。
2. 原始数据,不一定等于好特征
这个点特别重要。
很多人一开始会下意识觉得:
我把手头所有字段全扔进去,不就信息最全了吗?
但现实里,原始字段和“好特征”之间,中间通常隔着很长一段距离。
举几个很常见的例子。
例子一:时间戳
假设你有一个字段是:
2026-04-09 18:37:42
你直接把这个时间戳原封不动扔给模型,通常意义不大。
但如果你把它拆成:
- 小时
- 星期几
- 是不是周末
- 是不是节假日
- 是白天还是晚上
那这些新特征很可能就更有用。
因为模型真正需要的,不是“这一串时间字符串”,而是这背后和行为模式有关的结构。
例子二:出生年份
假设你有用户出生年份:
- 1998
- 2001
- 1987
如果你直接用出生年份,模型当然也能学。
但很多时候你真正关心的是:
- 年龄
- 年龄段
因为“年龄”比“出生年份”更直接对应现实意义。
例子三:商品标题
假设你在做电商预测,手里有商品标题:
- 2026新款轻薄羽绒服男短款立领
- 春季休闲运动鞋女透气跑步鞋
原始文本当然有用,但如果你先提取出:
- 是否包含“新款”
- 品类
- 性别
- 季节属性
- 价格区间
- 标题长度
这些结构化特征,往往能帮传统机器学习模型更直接地学习。
这些例子都在说明一件事:
原始数据是素材,特征是你从素材里提取出来、真正让模型拿来判断的输入。
3. 特征工程并不神秘,它通常就在做这几类事
如果把特征工程拆开来看,其实它做的事情大致就几种。
第一类:清洗和修正
先把明显有问题的数据处理掉。
比如:
- 缺失值填补
- 异常值识别
- 重复值清理
- 单位统一
- 格式统一
严格说,这一部分你前面在数据预处理那篇已经讲过。
但它和特征工程是紧密连在一起的。
因为脏数据不处理,你后面做再多特征,也可能建立在不靠谱的基础上。
第二类:变换
把原始字段换一种更适合学习的表达方式。
比如:
- 时间戳拆成小时、星期几
- 对数变换
- 分箱
- 标准化
- 类别编码
这类操作的特点是:
信息未必变多了,但表达方式更合理了。
第三类:组合
把多个原始字段组合成一个新特征。
比如:
- 总消费额 / 购买次数 = 客单价
- 点击数 / 曝光数 = 点击率
- 收入 / 家庭人数 = 人均收入
- 房贷 / 月收入 = 负债压力比例
很多时候,模型自己并不总能轻松看出这些关系。
但你把它们提前做成特征,模型就更容易学到问题真正关心的模式。
第四类:筛选
不是所有特征都值得留下。
有些特征:
- 几乎没信息量
- 和目标关系很弱
- 噪声很大
- 和别的特征高度重复
- 甚至可能造成泄漏
这时候做特征工程,不是“再加更多”,而是“删掉没必要的”。
这一点特别重要。
因为很多人一开始总觉得特征工程就是不断加特征,但其实:
好的特征工程,很多时候也包括敢于减特征。
4. 为什么好特征经常比换模型更有效
这个结论在实践里非常常见,而且对初学者特别重要。
很多时候你会发现:
- 换一个更复杂的模型,只提升一点点
- 但改好几个关键特征,效果直接明显改善
为什么?
因为模型再强,它也得建立在输入信息之上。
如果输入本身就缺少关键结构,模型很难无中生有。
比如你要预测用户是否流失。
如果你只给模型:
- 用户 ID
- 注册日期
- 性别
那模型能学到的东西本来就有限。
但如果你进一步做出这些特征:
- 最近 7 天活跃次数
- 最近 30 天使用时长
- 最近一次登录距今天数
- 最近是否投诉
- 历史付费金额
- 是否连续多周下降活跃度
这时候你给模型的信息密度就完全不一样了。
所以在很多任务里,真正拉开差距的不是“你最后选了随机森林还是 XGBoost”,而是:
你到底有没有把业务里真正重要的信号变成特征。
5. 一个很典型的例子:模型不是不会学,而是你没把关键信息交给它
假设你在做外卖订单取消预测。
你如果只给模型这些字段:
- 用户 ID
- 商家 ID
- 下单时间
- 订单金额
当然也能学点东西。
但如果你进一步提取:
- 是否高峰期下单
- 用户过去 30 天下单取消率
- 商家过去 7 天平均出餐时长
- 用户和商家距离
- 天气是否恶劣
- 是否使用优惠券
- 同商家近期取消率
模型的判断能力通常会强很多。
为什么?
因为这些特征更接近这个问题真实发生的机制。
订单会不会取消,往往不只是“这笔订单本身长什么样”,还和:
- 时间场景
- 用户历史行为
- 商家履约能力
- 外部环境
这些因素有关。
所以你会发现,特征工程说到底,其实很像在回答一个问题:
这个任务真正由哪些因素驱动?
我能不能把这些因素,用数据特征表达出来?
一旦你这样想,特征工程就不再是“机械加工字段”,而更像是在做问题理解。
6. 类别特征为什么经常特别值得认真处理
在真实数据里,类别特征非常常见。
比如:
- 城市
- 行业
- 品类
- 用户等级
- 支付方式
- 设备类型
但类别特征并不是直接扔给模型就完事的。
你得考虑怎么编码,以及编码方式会不会影响模型学习。
最常见的是独热编码
这个你前面已经提过了。
比如支付方式:
- 微信
- 支付宝
- 银行卡
独热编码以后会变成几列 0/1。
它的好处是不会强行给类别引入大小关系。
适合很多线性模型和距离模型。
但有时候独热编码不够好
比如类别太多时:
- 用户 ID
- 商品 ID
- 城市编码
- 品牌编码
如果直接 one-hot,维度会爆炸。
这时候就要考虑别的方法,比如:
- 频数编码
- 目标编码
- embedding(后面深度学习里更常见)
所以类别特征处理不是“有个方法就行”,而是要看:
- 类别多少
- 模型类型
- 是否容易泄漏
- 是否会过拟合
7. 数值特征为什么有时候也不能直接用
类别特征需要处理,这大家比较容易意识到。
但很多人会忽略,数值特征有时候也需要加工。
比如:
长尾分布
很多业务数据天然长尾,比如:
- 用户消费金额
- 商品销量
- 停留时长
少数值特别大,大多数值比较小。
这种情况下,直接用原值,模型可能会被极端值影响很大。
常见做法是:
- 对数变换
- 截断
- 分箱
这些操作不一定每次都要做,但你至少要意识到:
数值是数值,不代表它就已经是最适合学习的形态。
8. 分箱为什么有时候会有用
分箱这个操作看起来有点“粗”,但有时真的很有效。
比如你有年龄这个特征。
原始值当然可以直接用,但有时候你也会做成:
- 18-24
- 25-34
- 35-44
- 45+
为什么?
因为在某些任务里,模型真正需要的不是“精确到 27 岁和 28 岁的差异”,而是:
不同年龄阶段对应的行为模式差异。
分箱有时能带来两个好处:
- 降低噪声敏感度
- 更贴近现实业务区间
当然,分箱也不是永远更好。
它有时会损失信息。
所以重点不在于“分箱一定有用”,而在于:
你要知道什么时候连续值其实更适合变成区间。
9. 特征组合,往往是最容易出效果的一类操作
很多有用的信号,不藏在单个字段里,而藏在字段之间的关系里。
比如:
- 访问次数很多,但下单数很少 → 转化低
- 收入不低,但负债很高 → 财务压力大
- 点击很多,但停留时间很短 → 可能是误点或低意愿
- 登录频繁,但支付金额连续下降 → 活跃但价值下降
这些信息,如果只看单个字段,模型未必很容易捕捉。
但如果你提前做出:
- 转化率
- 负债收入比
- 平均客单价
- 最近活跃变化率
模型就更容易学到有意义的模式。
所以很多特征工程最值钱的地方,并不是“会不会用库”,而是:
你能不能从业务逻辑里想到有意义的特征关系。
10. 特征工程为什么特别需要业务理解
这一点很关键。
很多人学机器学习,容易把特征工程想成一个纯技术动作。
但真正做项目时,它往往特别依赖业务理解。
因为好特征往往不是“代码里长出来的”,而是:
你先理解问题,再把理解翻译成数据。
比如做用户流失预测时,一个懂业务的人很可能第一时间想到:
- 最近活跃下降速度
- 最近使用频率变化
- 最近是否有负面反馈
- 最近功能使用范围是否收缩
这些特征,不是你随便调个模型就能自动想到的。
它们来自对问题机制的理解。
这也是为什么很多真实团队里,做得好的模型,不一定是算法最花哨的,而往往是:
- 最懂数据的人
- 最懂业务的人
- 最知道哪些信号真正关键的人
把特征做得更好。
11. 特征工程也很容易踩坑,尤其是数据泄漏
特征工程越重要,就越容易踩坑。
其中最大的一类坑就是:数据泄漏。
比如你要预测用户会不会流失,结果你做了一个特征:
- “未来 7 天是否登录”
这当然特别有预测力。
问题是,这个特征在真实预测时根本拿不到。
它等于把答案偷偷塞进来了。
再比如做贷款违约预测时,你用了:
- 放款后 30 天是否逾期
那这也不对。
因为你预测时并不知道“未来会不会逾期”。
所以特征工程有一个非常重要的原则:
所有特征都必须来自预测时刻之前、真实可获得的信息。
否则模型分数会很好看,但完全没法落地。
12. 特征太多,也不一定是好事
这是很多人很容易误判的一点。
一听说特征重要,就容易走到另一个极端:
那我把能想到的特征都加进去,不就更好吗?
不一定。
特征太多可能带来这些问题:
- 引入更多噪声
- 增加过拟合风险
- 增加训练成本
- 让模型更难解释
- 让真正重要的信号被淹没
所以特征工程不只是“做加法”,也常常要做减法。
你得不断问自己:
- 这个特征真的有信息吗?
- 它和已有特征高度重复吗?
- 它会不会引入泄漏?
- 它在训练集上看起来有用,是不是只是偶然?
很多时候,做完一轮特征扩展之后,接下来要做的不是继续堆,而是筛。
13. 一个简单的小例子:为什么“比例”特征经常比原始值更有用
这个例子很适合放进文章里,因为直观。
假设你要预测一个用户会不会购买。
原始字段有:
- 商品浏览次数
- 商品收藏次数
- 商品加入购物车次数
这些原始值当然都可以用。
但如果你进一步做几个特征:
- 收藏率 = 收藏次数 / 浏览次数
- 加购率 = 加购物车次数 / 浏览次数
这通常会比单独看原始次数更有意义。
为什么?
因为:
- 浏览 100 次收藏 10 次
- 浏览 10 次收藏 10 次
这两个用户收藏次数一样,但意愿强度显然不一样。
比例特征,往往更能反映行为质量,而不只是行为数量。
这就是特征工程常见的价值:
不是创造信息,而是把已有信息变成更贴近问题的表达。
14. 用一个简单代码例子演示一下特征构造
下面给一个非常基础的示例,读者能直接看懂。
import pandas as pd
# 构造简单数据
data = pd.DataFrame({
"browse_count": [100, 50, 20, 80],
"favorite_count": [10, 5, 2, 1],
"cart_count": [8, 3, 1, 0],
"buy": [1, 1, 0, 0]
})
print("原始数据:")
print(data)
# 构造新特征
data["favorite_rate"] = data["favorite_count"] / data["browse_count"]
data["cart_rate"] = data["cart_count"] / data["browse_count"]
print("\n加入新特征后:")
print(data)
15. 怎么判断一个特征值不值得做
这是很多人特别想知道、但很少有人认真讲的事。
说到底,特征值不值得做,通常可以从这几个角度去想:
第一,它有没有业务意义
如果一个特征你自己都说不清它为什么可能和目标有关,那就要小心。
第二,它是不是来自真实可用信息
如果预测时根本拿不到,那再强也没意义。
第三,它是不是和已有特征高度重复
如果只是换个名字重复表达,价值未必大。
第四,它是不是只在训练集里“看起来有用”
这就要靠验证集、交叉验证去判断。
第五,它会不会让模型更容易过拟合
尤其是一些很细碎、很局部、很容易记住训练集的特征。
所以判断特征,不只是看“加了以后训练集分数涨没涨”,更重要的是看:
它是不是稳定、有意义、能泛化。
16. 这一篇真正想传达的,不是“多做特征”,而是“做对特征”
特征工程很容易被误解成一件体力活:
- 多做几个字段
- 多组合几列
- 多跑几轮筛选
但真正重要的不是“做得多”,而是“做得对”。
你要让读者慢慢建立一个感觉:
好特征不是堆出来的,是理解出来的。
它来自:
- 对数据的理解
- 对任务的理解
- 对业务机制的理解
- 对模型局限的理解
所以特征工程真正厉害的地方,不是技术动作本身,而是:
你是否真的知道,模型缺的是什么信息。
17. 到这里,机器学习系列其实已经开始真正像“做项目”了
前面几篇更多是在讲模型和方法。
这一篇开始,你的系列已经明显从“认识算法”走向“开始做实战”。
因为现实里的机器学习,很少是:
- 干净数据
- 现成特征
- 模型一跑就结束
更常见的是:
- 数据脏
- 字段杂
- 特征不够用
- 要不断试、不断改、不断验证
而特征工程,恰恰就是连接“原始业务数据”和“模型输入”的那一步。
所以这一篇其实很关键。
它会让读者意识到:
模型当然重要,但模型看到什么,往往更重要。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)