产品战略专家梁宁确认出席AICon北京站,分享AI时代下的商业逻辑与产品需求 了解详情
写点什么

特征工程最佳实践解析

  • 2017-08-02
  • 本文字数:3423 字

    阅读完需:约 11 分钟

作为面向机器学习建立新输入特征的实现过程,特征工程已经成为改进预测模型的最具实效的方法之一。

获取特征难度极高、相当耗时且要求具备专业知识。“应用机器学习”在本质上其实就是在实现特征工程。-Andrew Ng

通过特征工程方法,你将能够提取关键信息、突出数据模式并引入你的领域专长。

由于特征工程具备突出的开放性,因此极易令实施者陷入困境。

在今天的教程当中,我们将探讨 20 项特征工程的最佳实践与启发性结论,希望能够帮助大家顺利踏上特征工程之旅。

特征工程是什么?

作为一个非正式话题,特征工程可能拥有多种潜在定义。事实上,由于机器学习流程的流动性与迭代性,我们很难为特征工程找到概念层面的惟一“正确答案”。

根据自身理解,我们将特征工程定义为“基于现有的特征创建新特征,以提升模型性能的过程”。

典型的数据科学流程可能如下所示:

  1. 项目范围设定 / 数据收集
  2. 探索性分析
  3. 数据清理
  4. 特征工程
  5. 模型训练(包括交叉验证以调整超参数)
  6. 项目交付 / 获得见解

哪些不属于特征工程?

上述流程意味着我们将一些步骤明确排除在特征工程范畴之外:

  • 我们认为初始数据收集并不属于特征工程。
  • 同样的,我们认为创建目标变量不属于特征工程。
  • 我们认为删除重复项、处理丢失值或者修复错误标记类并不属于特征工程。我们将这些纳入数据清理范畴。
  • 我们认为特征缩放或者归一化不属于特征工程,因为此类步骤归属于交叉验证循环(即在你已经建立起分析基表之后)。
  • 最后,我们认为特征选择或者主成分分析(PCA)并不属于特征工程。这些步骤同样归属于交叉验证循环。

再次强调,这些只是我们给出的分类意见。我们接受其他数据科学家对此提出的质疑,毕竟特征工程本身就属于一个开放性概念。

免责声明到此结束,下面让我们进一步探讨与之相关的最佳实践与启发性结论。

指标变量

特征工程的第一种类型是利用指标变量提取关键信息。

现在,有些朋友可能会问,“好的算法不是应该自行学习关键信息吗?”

这个嘛,情况并非始终如此,具体取决于你所拥有的数据量以及竞争信号的强度。你可以通过预先突出重要内容帮助算法对其给予“关注”。

  • 来自阈值的指标变量: 我们假设你正在研究美国消费者对于酒精饮料的偏好,而当前数据集包含年龄特征 age。您可以创建一个指标变量 age>=21 以区分达到合法饮酒年龄的受试者。
  • 来自多种特征的指标变量:假设你正在预测房地产价格,并且已经掌握了 n_bedrooms 与 n_bathrooms 两项特征。如果拥有两卧两卫的房产在出租时拥有溢价性,则你可以创建一项指标变量对其进行标记。
  • 针对特殊事件的指标变量: 假设你正在为电子商务网站的每周销售情况建模。你可以为黑色星期五与圣诞节那两周分别创建两项指标变量。
  • 类组指标变量: 假设你正在分析网站转换率,而当前数据集包含 traffic_source 这一分类特征。你可以通过标记“Facebook 广告”或者“谷歌广告”为 paid_traffic 创建指标变量。

交互特征

第二种特征工程类型主要是突出两项或者多项特征之间的交互。

你是否听说过“一加一大于二”这种说法?事实上,一部分特征组合起来确实能够较单一特征带来更多信息。

具体来讲,我们可以对多项特征进行加和、减差、乘积或者除商后再寻找其中的模式。

备注:我们并不建议大家利用自动化循环为全部特征创建交互。这有可能造成“特征爆炸”问题。

  • 两项特征加和: 我们假设你希望根据初步销售数据预测收入情况。你已经拥有 sales_blue_pens 与 sales_black_pens 两项特征。如果你只关注总体 sales_pens,那就可以将二者相加。
  • 两项特征之差: 假设你已经拥有 house_built_date 以及 house_purchase_date 两项特征,可以求二者之差以创建 house_age_at_purchase 特征。
  • 两项特征乘积: 假设你正在进行价格测试,而且分别拥有特征 price 与指标变量 conversion。您可以将二者相乘以建立特征 earnings。
  • 两项特征除商: 假设你拥有一套市场营销活动数据集,其中包含 n_clicks 与 n_impressions 两项特征。你可以将点击次数除以展示次数以求得 click_through_rate,并借此了解不同规模的宣传活动间的转化率对比情况。

特征表达

接下来要谈到的特征工程类型虽然简单却影响巨大。我们将其称为特征表达。

你的数据并不一定总是理想格式。你需要考虑是否有必要通过另一种形式进行特征表达以获取有用信息。

  • 日期与时间特征: 我们假设你拥有 purchase_datetime 特征。从中提取 purchase_day_of_week 与 purchase_hour_of_day 两项特征可能会更有用。你还可以进行观察聚类以创建诸如 purchases_over_last_30_days 这类特征。
  • 数字到分类的映射: 假设你拥有 years_in_school 特征。你可以基于它创建新的 grade 特征,并分类为“小学”、“初中”和“高中”。
  • 稀疏类分组:假设你拥有一个包含多个类别的特征,但样本量较小。你可以尝试对相似类进行分组,将相似的类别分到一组,然后将剩下的类划分至单一的“其他”类中。
  • 创建虚拟变量 根据你所选取的机器学习实现方法,你可能需要手动地将各分类特征转化为虚拟变量。请务必在稀疏类分组之后再创建虚拟变量。

外部数据

特征工程中一个未被充分利用的类型正是外部数据的引入,实际上它能够为性能带来一些巨大突破。

举例来说,定量对冲基金的一种研究方式就是对不同财务数据流进行分层。

亦有多种机器学习难题能够通过引入外部数据得到改善。以下为相关示例:

  • 时间序列数据: 时间序列数据的最大优势在于,你只需要一项特征——即某种形式的日期,即可将其纳入来自其他数据集的特征。
  • 外部 API: 如今我们可以利用大量 API 来协助创建特征。例如,微软计算机视觉 API 能够返回某一图像当中包含的人脸数量。
  • 地理编码: 如果你已经拥有街道地址、城市乃至州等信息,则可以利用地理编码将其转换为纬度与经度。如此一来,你就能够借助其他数据集计算出本地人口属性(例如 median_income_within_2_miles)等特征。
  • 同一数据的其它来源: 我们可以通过几种方式追踪 Facebook 广告宣传活动?答案可能包括 Facebook 自身的追踪系统、Google Analytics 以及其他第三方软件。每一种来源都可能带来其他方案所无法追踪的信息。另外,这些数据集之间的任何差别都可能包含重要信息(例如不同信息来源可能对机器人流量选择忽略或者保留)。

错误分析(建模后)

特征工程的最后一种类型,我们将其称为错误分析。错误分析应该在第一套模型训练完成之后进行。

错误分析是一项广义术语,是指对模型当中的错误分类或者高错误率观察结果加以分析,同时决定如何在下一步当中作出改进。

潜在的后续步骤包括收集更多数据、对问题进行拆分或者设计出能够解决错误的新特征。要在特征工程当中使用错误分析,我们需要搞清楚自己的模型为何未能得出正确结果。

具体方式包括:

  • 由较大错误入手:错误分析通常手动执行。很明显,大家没有时间对每一项观察结果进行逐一检查。我们建议从那些错误评分较高的问题处入手,并寻找那些能够转换为新特征的模式。
  • 按类别分段: 另一项技术在于拆分观察结果,并针对各个分段对平均误差进行比较。你可以尝试为误差值最高的分段创建指标变量。
  • 无监督聚类: 如果你在发现模式时遇到问题,则可对被错误分类的观察结果执行无监督聚类算法。我们并不建议你盲目将这些聚类视为新特征,但这确实能够有效简化模式的发现过程。请记住,我们的目标是理解为何观察结果中会出现错误分类。
  • 询问同事或者领域内专家:这种做法可以作为以上任一项技术的补充。如果你确定效果不佳(例如通过分段方式检验),但还不清楚具体原因,那么向领域内专家求助或许能帮上大忙。

结论

如大家所见,特征工程领域存在着诸多可能性。我们在本文中提到了 20 项最佳实践与启发性结论,但这明显还不是全部。

当你开始进行自己的实验时,请牢记以下一般性准则:

良好的特征工程应当……

  • 可面向未来观察结果进行计算。
  • 通常能给出直观的解释。
  • 通过领域内专业知识或者探索性分析得出。
  • 必须拥有预测能力。不要为了创建特征而创建特征。
  • 切勿触及目标变量。这一点对于初学者们来说是一种经常会误入的陷阱。无论你是在创建指标变量抑或是交互特征,都千万不要使用自己的目标变量。这就像是一种“欺骗”,会给大家带来极具误导性的结果。

最后,如果感觉上述内容太难,请不必担心!通过不断实践和积累经验,你将在特征工程当中自然而然地熟悉一切并得到更理想的结果。

原文链接: Best Practices for Feature Engineering


感谢蔡芳芳对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-08-02 19:004819
用户头像

发布了 24 篇内容, 共 96047 次阅读, 收获喜欢 7 次。

关注

评论

发布
暂无评论
发现更多内容

【网络编程知识】什么是Socket?概念及原理分析

呆呆敲代码的小Y

大家的 Hexo 博客都还好吗?

jrwng

Hexo

在线JADE转HTML工具

入门小站

工具

数据库每日一题---第4天:从不订购的客户

知心宝贝

数据库 程序员 前端 后端 6月月更

【100个 Unity踩坑小知识点】| Unity中的 Development build 详细解析

呆呆敲代码的小Y

运维服务体系构建

阿泽🧸

运维体系 6月月更

NFT赛道或进入聚合时代,OKALEIDO成BNB Chain上的首个NFT聚合平台

股市老人

this和super的用法与区别

写代码两年半

继承 super javase this 6月月更

【100个 Unity实用技能】| 游戏中获取鼠标点击的坐标,并将游戏对象移动到鼠标的点击位置

呆呆敲代码的小Y

如何使用物联网低代码平台进行模型管理?

AIRIOT

物联网 低代码开发

PHP开发者福音,支持CRUD代码生成且前后分离的tp6+Vue3后台管理系统开源啦!

妙码生花

php typescript Vue3 thinkphp Pinia

在线文本右边批量删除字符工具

入门小站

工具

Fabric.js 精简输出的JSON🎫

德育处主任

FabricJS 6月月更

Junit 测试中如何对异常进行断言

HoneyMoose

spring4.1.8初始化源码学习三部曲之一:AbstractApplicationContext构造方法

程序员欣宸

Java spring 6月月更

【100个 Unity踩坑小知识点】| 在编辑器中绘制正方体虚线、球体虚线(Gizmos 辅助线框)

呆呆敲代码的小Y

【100个 Unity踩坑小知识点】| Unity 使用Quaternion.AngleAxis随机一个方向

呆呆敲代码的小Y

【100个 Unity踩坑小知识点】| Unity调用API ,动态获取Android权限,附带所有Android权限表格

呆呆敲代码的小Y

AssertJ 的异常(Exception )断言

HoneyMoose

如何写好技术博客

卢卡多多

技术 博客 6月月更

见自身,见天地:华为,将ICT技术变成绿色未来的支点

脑极体

Django API 开发:博客系统的权限管理

宇宙之一粟

django 6月月更

vue指令-2

小恺

6月月更

【100个 Unity实用技能】| 游戏中使技能或装备跟随角色环绕,持续旋转

呆呆敲代码的小Y

【100个 Unity踩坑小知识点】| Unity中的 碰撞盒检测 Physics.OverlapBox、OverlapCapsule、OverlapSphere

呆呆敲代码的小Y

【愚公系列】2022年06月 面向对象设计原则(一)-单一职责原则

愚公搬代码

6月月更

软件设计本质

GalaxyCreater

架构 设计模式 架构师 系统 软件设计

InfoQ 极客传媒 15 周年庆征文|聊聊 Kafka:Kafka 如何保证一致性

老周聊架构

kafka 架构 云原生 6月月更 InfoQ极客传媒15周年庆

理解 Java 中的 NumberFormatException 异常

HoneyMoose

数据类型

Jason199

js 数据类型 6月月更

【100个 Unity踩坑小知识点】| Unity控制物体持续指向某个方向

呆呆敲代码的小Y

特征工程最佳实践解析_语言 & 开发_EliteDataScience_InfoQ精选文章