机器学习7:特征工程
在传统的软件工程中,核心是代码,然而,在机器学习项目中,重点则是特征——也就是说,开发人员优化模型的方法之一是增加和改进其输入特征。很多时候,优化特征比优化模型带来的增益要大得多。
笔者曾经参与过一个“商品推荐”的项目,在项目中,笔者发现商品的类目(划分类别的标记,如纸品家清、米面粮油、数码产品等)虽然有 100 多个,但是运营人员经验不足,将超过 70% 的商品采用了默认的类目(精品好货)标记。如此一来,原本可以用来标记商品类型的关键特征(类目)的实际作用大打折扣。于是,我们重新整理了这个特征,将所有商品重新标记,在未改变算法模型的前提下,推荐效果(uvctr)提升了8%+。
目录
1.将原始数据映射到特征
1.1 映射数值
1.2 映射分类值
1.3 稀疏表示
2.寻找优秀的特征
2.1 避免很少使用的离散特征值
2.2 喜欢清晰、明显的含义
2.3 不要将“魔法”值与实际数据混合在一起
2.4 考虑上游不稳定因素
3.数据清洗
3.1 缩放特征值
3.2 处理极端异常值
3.3 分档
3.4 清洗
3.5 了解数据
4.参考文献
1.将原始数据映射到特征
图 1 左侧展示了来自输入数据源的原始数据;右侧展示了一个特征向量,它是包含数据集中示例的浮点值集。 特征工程意味着将原始数据转换为特征向量。在实践中,会花费大量时间实施特征工程。许多机器学习模型必须将特征表示为实数向量,因为特征值必须乘以模型权重。
图 1 特征工程将原始数据映射到 ML 特征
1.1 映射数值
整数和浮点数据不需要特殊编码,因为它们可以乘以数字权重。如图 2 所示,将原始整数值 6 转换为特征值 6.0 很简单:
图 2 将整数值映射到浮点值
1.2 映射分类值
分类特征具有一组离散的可能值。例如,可能有一个名为 street_name(
街道名称)的特征
包含以下选项:
{'Charleston Road', 'North Shoreline Boulevard', 'Shorebird Way', 'Rengstorff Avenue'}
由于模型无法将字符串乘以学习到的权重,因此我们使用特征工程将字符串转换为数值。我们可以通过定义从特征值(我们将其称为可能值的词汇表)到整数的映射来实现此目的。由于并非世界上的每条街道都会出现在我们的数据集中,因此我们可以将所有其他街道分组为一个包罗万象的 “其他”类别,称为OOV(词汇外)桶。
使用这种方法,我们可以将街道名称映射到数字:
- 将 “Charleston Road” 映射到 0
- 将 “North Shoreline Boulevard” 映射到 1
- 将 “Shorebird Way” 映射到 2
- 将 “Rengstorff Avenue” 映射到 3
- 将其他所有内容 (OOV) 映射到 4
但是,如果我们将这些索引号直接合并到我们的模型中,则会出现问题:
-
我们将学习适用于所有街道的单一权重。例如,如果我们学习的权重为 6,那么对于 Charleston Road,我们将其乘以 0,对于 North Shoreline Boulevard,我们将其乘以 1,对于 Shorebird Way,我们将其乘以 2,依此类推。
street_name
考虑一个使用特征来预测房价的模型。价格不太可能根据街道名称进行线性调整,而且这会假设您根据街道的平均房价对街道进行排序。我们的模型需要灵活地学习每条街道的不同权重,并将其添加到使用其他功能估计的价格中。 -
我们没有考虑
street_name
可能采用多个值的情况。例如,许多房屋位于两条街道的拐角处,如果值包含单个索引,则无法在值中编码该信息。
为了消除上述问题,我们可以为模型中的每个分类特征创建一个二元向量来表示值,如下所示:
- 对于适用于该示例的值,将相应的向量元素设置为
1
。 - 将所有其他元素设置为
0
。
该向量的长度等于词汇表中元素的数量。当单个值为 1 时,这种表示称为 one-hot 编码;当多个值为 1 时,这种表示称为 multi-hot 编码。
图 3 说明了特定街道的 one-hot 编码:Shorebird Way。Shorebird Way 的二元向量中的元素值为 1
,而所有其他街道的元素值为 0
。
图 3 通过 one-hot 编码映射街道地址
上述方法有效地为每个特征值(例如,街道名称)创建一个布尔变量。此处,如果房屋位于 Shorebird Way,则仅对于 Shorebird Way,二进制值为 1。因此,该模型仅使用 Shorebird Way 的权重。同样,如果房屋位于两条街道的拐角处,则两个二进制值设置为 1,并且模型使用它们各自的权重。
One-hot 编码还可以扩展到其他场景,比如不能直接乘以权重的数字数据,例如邮政编码。
1.3 稀疏表示
假设数据集中有 1,000,000 个不同的街道名称。在处理这些向量时,显式创建一个包含 1,000,000 个元素的二进制向量,其中只有 1 或 2 个元素为真,在存储和计算时间方面都是非常低效的表示形式。在这种情况下,常见的方法是使用 稀疏表示,其中仅存储非零值。在稀疏表示中,仍然为每个特征值学习独立的模型权重,如上所述。
2.寻找优秀的特征
在上面,我们已经探索了将原始数据映射到合适的特征向量的方法,但这只是工作的一部分。我们还必须探索哪些类型的值可以在这些特征向量中产生良好的表现。
2.1 避免很少使用的离散特征值
好的特征值应该在数据集中出现超过 5 次左右。这样做可以使模型了解该特征值与标签的关系。也就是说,拥有相同离散值的许多示例使模型有机会在不同设置中查看该特征,进而确定何时它是标签的良好预测变量。例如,名为 house_type(房屋类型)
的特征可能在很多示例中出现。
相反,如果某个特征的值仅出现一次或很少出现,则模型无法根据该特征进行预测。例如,unique_house_id(房屋唯一编码)
是一个不好的特征,因为每个值只能使用一次,因此模型无法从中学习任何内容。
2.2 喜欢清晰、明显的含义
每个特征对于项目中的任何人都应该具有清晰且明显的含义。例如,名称明确的特征,并且值相对于名称有意义:
house_age_years: 27
相反,不好的特征,除了创建它的工程师之外,任何人都无法理解以下特征值的含义:
house_age: 851472000
在某些情况下,噪声数据(而不是糟糕的工程选择)会导致值不明确。例如,以下 user_age_years ,如果不做前置过滤,这样的 “不恰当的特征数值” 将会混入。
user_age_years: 277
2.3 不要将“魔法”值与实际数据混合在一起
良好的浮点数特征不应包含特殊的超出范围的“魔法”值。例如,假设某个特征包含 0 到 1 之间的浮点值。因此,如下所示的值就可以了:
quality_rating: 0.82
quality_rating: 0.37
但是,如果用户没有输入 quality_rating
,则数据集可能会用如下所示的 “魔法” 值来表示其不存在:
quality_rating: -1
要显式标记 “魔法值”,请创建一个布尔功能来指示是否提供了 quality_rating 这一特征,并
为这个布尔特征命名,例如 is_quality_rating_defined
。
在原来的特征中,将 “魔法值” 替换如下:
- 对于采用有限值集(离散变量)的变量,向该集中添加一个新值并用它来表示特征值缺失。
- 对于连续变量,通过使用特征数据的平均值来确保缺失值不会影响模型。
2.4 考虑上游不稳定因素
特征的定义不应随时间而改变。例如,城市名称一般不会更改。(需要说明的是,在实际应用中,我们需要将 “br/sao_paulo” 这样的字符串转换为 one-hot 向量。)
city_id: "br/sao_paulo"
3.数据清洗
苹果树结出美味的果实和虫害的混合物。然而,高端杂货店里的苹果却是 100% 完美的水果。在果园和杂货店之间,有人花费大量时间去除坏苹果或在可回收的苹果上撒一点蜡。作为一名 ML 工程师,您将花费大量时间排出不好的示例并清理可挽救的示例。即使是几个“坏苹果”也会破坏一个大的数据集。
3.1 缩放特征值
缩放意味着将浮点特征值从其自然范围(例如 100 到 900)转换为标准范围(例如 0 到 1 或 -1 到 +1)。如果一个特征集仅包含一个特征,那么缩放几乎不会带来任何实际好处。然而,如果一个特征集由多个特征组成,那么特征缩放会带来以下好处:
- 帮助梯度下降更快地收敛。
- 有助于避免“NaN 陷阱”,即模型中的一个数字变成 NaN (例如,当训练期间某个值超过浮点精度限制时),并且由于数学运算,模型中的所有其他数字最终也会变成 NaN。
- 帮助模型学习每个特征的适当权重。如果没有特征缩放,模型将过多关注范围更广的特征。
我们不必为每个浮点特征提供完全相同的比例。如果特征 A 从 -1 缩放到 +1,而特征 B 从 -3 缩放到 +3,则不会发生什么可怕的事情。但是,如果特征 B 从 5000 缩放到 100000,模型反应会很差。
3.2 处理极端异常值
下图表示 roomsPerPerson
从加州住房数据集调用的一个特征。的值 roomsPerPerson
是通过将某个区域的房间总数除以该区域的人口来计算的。该图显示,加利福尼亚州的绝大多数地区每人拥有一到两个房间。但沿着 x 轴看一下。
图 4 一条非常长的尾巴
我们如何才能最大限度地减少这些极端异常值的影响?好吧,一种方法是取每个值的对数:
图 5 对数缩放仍然留下尾巴
对数缩放的效果稍好一些,但仍然存在明显的异常值尾部。让我们选择另一种方法。如果我们简单地将 的最大值“限制”或“限制”roomsPerPerson
为任意值(例如 4.0)会怎么样?
图 6 在 4.0 处剪切特征值
将特征值裁剪为 4.0 并不意味着我们忽略所有大于 4.0 的值。相反,它意味着所有大于 4.0 的值现在都变为 4.0。这解释了 4.0 处的有趣山丘。尽管有这座山,但缩放后的特征集现在比原始数据更有用。
3.3 分档
下图显示了加利福尼亚州不同纬度房屋的相对流行率。请注意聚类情况 - 洛杉矶大约位于纬度 34 处,旧金山大约位于纬度 38 处。
图 7 每个纬度的房屋
数据集中,latitude
是一个浮点值。然而,在我们的模型中表示 latitude
为浮点特征是没有意义的。这是因为纬度和住房价值之间不存在线性关系。例如,北纬 35 度的房子就不是 3534 比纬度 34 的房屋更贵(或更便宜)。然而,各个纬度可能是房屋价值的一个很好的预测指标。
为了使纬度成为有用的预测器,我们将纬度划分为“区间”,如下图所示:
图 8 分箱值
我们现在拥有 11 个不同的布尔特征(LatitudeBin1
, LatitudeBin2
, ..., LatitudeBin11
),而不是只有一个浮点特征。拥有 11 个独立的特征并不好,因此让我们将它们合并成一个 11 元素向量。这样做将使我们能够将纬度 37.4 表示如下:
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
基于分箱,我们的模型现在可以学习每个纬度完全不同的权重。
3.4 清洗
到目前为止,我们假设用于训练和测试的所有数据都是值得信赖的。在现实生活中,由于以下一个或多个原因,数据集中的许多示例都是不可靠的:
- 省略的值。例如,某人忘记输入房屋的年龄值。
- 重复的例子。 例如,服务器错误地将相同的日志上传了两次。
- 不好的标签。 例如,有人将橡树的图片错误地标记为枫树。
- 不良特征值。例如,有人输入了额外的数字。
一旦检测到,通常需要通过从数据集中删除它们来 “修复” 不良示例。要检测遗漏的值或重复的示例,您可以编写一个简单的程序。在实践中,检测不良特征值或标签可能要棘手得多。
除了检测不良的个别示例之外,还必须检测聚合中的不良数据。直方图是可视化聚合数据的绝佳机制。此外,获取如下统计数据也会有所帮助:
- 最大值和最小值
- 平均值和中位数
- 标准差
考虑生成离散特征最常见值的列表。例如,示例的数量是否与 country:uk
您期望的数量相匹配。language:jp
是数据集中最常用的语言吗?
3.5 了解数据
请遵循以下规则:
- 请记住数据应该是什么样子。
- 验证数据是否满足这些期望(或者你可以解释为什么不满足)。
- 仔细检查训练数据是否与其他来源一致。
像对待任何关键任务代码一样小心地对待你的数据。好的机器学习依赖于好的数据。
4.参考文献
本文部分内容翻译自:英文资料(链接-https://developers.google.cn/machine-learning/crash-course/representation/feature-engineering)
相关文章:

机器学习7:特征工程
在传统的软件工程中,核心是代码,然而,在机器学习项目中,重点则是特征——也就是说,开发人员优化模型的方法之一是增加和改进其输入特征。很多时候,优化特征比优化模型带来的增益要大得多。 笔者曾经参与过一…...

coverage代码覆盖率测试介绍
coverage代码覆盖率测试介绍 背景知识补充 1、什么是覆盖率 测试过程中提到的覆盖率,指的是已测试的内容,占待测内容的百分比,在一定程度上反应测试的完整程度。 覆盖率有可以根据要衡量的对象细分很多种,比如接口覆盖率、分支…...

使用 Debian、Docker 和 Nginx 部署 Web 应用
前言 本文将介绍基于 Debian 的系统上使用 Docker 和 Nginx 进行 Web 应用部署的过程。着重介绍了 Debian、Docker 和 Nginx 的安装和配置。 第 1 步:更新和升级 Debian 系统 通过 SSH 连接到服务器。更新软件包列表:sudo apt update升级已安装的软件…...

Redis原理 - 内存策略
原文首更地址,阅读效果更佳! Redis原理 - 内存策略 | CoderMast编程桅杆https://www.codermast.com/database/redis/redis-memery-strategy.html Redis 本身是一个典型的 key-value 内存存储数据库,因此所有的 key、value 都保存在之前学习…...

【计算机网络】IP 地址处理函数
目录 1.struct sockaddr_in的结构 2.一般我们写的结构 3.常见的“点分十进制” 到 ” uint32_t 的转化接口 3.1. inet_aton 和 inet_ntoa (ipv4) 3.2. inet_pton 和 inet_ntop (ipv4 和 ipv6) 3.3. inet_addr 和 inet_network 3…...

9i物联网浏览器(cef_114.2.110114.2.100支持H264视频)WinForm-CefSharp114(5735)视频版本体验
更新:2023.6.25 版本:Cef_114.2.110和114.2.100+chromium-114.0.5735.134的32位和64位 说明:支持图片,mp3,mp4(H264)多媒体 测试环境:windows server 2019 测试网址:www.html5test.com 1.包下载地址 1.1 https://www.nuget.org/packages/CefSharp.Common/ 1.2 https…...

如何在本地运行一个已关服但具有客户端的游戏
虽然游戏服务器关闭后,我们通常无法再进行在线游戏,但对于一些已经关服但仍保留客户端的游戏来说,我们仍然可以尝试在本地进行游玩。本文将介绍如何在本地运行一个已关服但具有客户端的游戏的方法。 一、获取游戏客户端 要在本地运行一个已关…...

C语言编程—预处理器
预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤。简言之,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理。我们将把 C 预处理器(C Preprocessor)简写为 CP…...

使用 Maya Mari 设计 3D 波斯风格道具(p1)
今天瑞云渲染小编给大家带来了Simin Farrokh Ahmadi 分享的Persian Afternoon 项目过程,解释了 Maya 和 Mari 中的建模、纹理和照明过程。 介绍 我的名字是西敏-法罗赫-艾哈迈迪,人们都叫我辛巴 在我十几岁的时候,我就意识到我喜欢艺术和创造…...

Redis分布式问题
Redis实现分布式锁 Redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对Redis的连接并不存在竞争关系Redis中可以使用SETNX命令实现分布式锁。当且仅当 key 不存在,将 key 的值设为 value。 若给定的 key 已经存在&…...

synchronized原理
目录 一、基本特点 二、加锁过程 2.1、偏向锁 2.2、轻量级锁 2.3、重量级锁 三、其它的优化操作 3.1、锁消除 3.2、锁粗化 一、基本特点 synchronized有以下特性: 开始是乐观锁,如果锁冲突频繁,就转换为悲观锁。开始是轻量级锁,…...

10G光模块能兼容千兆光口吗
当涉及到光网络设备和光模块的兼容性时,确保正确的匹配是至关重要的。本期文章内容,我们将探讨10G光模块与千兆光口之间的兼容性。 一、10G光模块和千兆光口的基本概念 首先,我们需要了解10G光模块和千兆光口的基本概念。10G光模块是一种用…...

css 显示省略号 和 动态显示省略号
省略是非常常见的功能。 简单的实现省略号 下面的代码就可以实现省略号,超过宽度的时候就会出现省略号 .text-name{//宽高是一定要设置的不然是会无效延伸的width: 200rpx;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}稍微复杂点的情况&#…...

LeetCode 1253. 重构 2 行二进制矩阵
【LetMeFly】1253.重构 2 行二进制矩阵 力扣题目链接:https://leetcode.cn/problems/reconstruct-a-2-row-binary-matrix/ 给你一个 2 行 n 列的二进制数组: 矩阵是一个二进制矩阵,这意味着矩阵中的每个元素不是 0 就是 1。第 0 行的元素之…...

【八股】【C++】内存
这里写目录标题 内存空间分配new和delete原理C有几种newmalloc / free 与 new / delete区别malloc和free原理?delete和delete[]区别?C内存泄漏malloc申请的存储空间能用delete释放吗?malloc、calloc函数、realloc函数C中浅拷贝与深拷贝栈和队列的区别C里…...

数据库G等待
> db^Cgbasedbtpc:~$ dbaccess db10 -Database selected.> call insert_t();Routine executed.Elapsed time: 811.630 sec 磁盘逻辑日志,无BUF库> ^Cgbasedbtpc:~$ gbasedbtpc:~$ dbaccess db10 -Database selected.> call insert_t();Routine executed.Elapse…...

PCB封装设计指导(一)基础知识
PCB封装设计指导(一)基础知识 PCB封装是PCB设计的基础,也是PCB最关键的部件之一,尺寸需要非常准确且精确,关系到设计,生产加工,贴片等后续一系列的流程。 下面以Allegro为例介绍封装创建前的一些基础知识 1.各个psm文件代表什么 mechanical symbol 是.bsm Package sy…...

Flask框架之Restful--介绍--下载--基本使用
目录 Restful 概念 架构的主要原则 适用场景 协议 数据传输格式 url链接规则 HTTP请求方式 状态码 Restful的基本使用 介绍 优势 缺点 安装 基本使用 注意 Restful 概念 RESTful(Representational State Transfer)是一种用于设计网络应用…...

2023年上海市浦东新区网络安全管理员决赛理论题样题
目录 一、判断题 二、单选题 三、多选题 一、判断题 1.等保1.0至等保2.0从信息系统拓展为网络和信息系统。 正确 (1)保护对象改变 等保1.0保护的对象是信息系统,等保2.0增加为网络和信息系统,增加了云计算、大数据、工业控制系统、物联网、移动物联技术、网络基础…...

SQL语言的四大组成部分——DCL(数据控制语言)
1️⃣前言 SQL语言中的DCL(Data Control Language)是一组用于控制数据库用户访问权限的语言,主要包括GRANT、REVOKE、DENY等关键字。 文章目录 1️⃣前言2️⃣DCL语言3️⃣GRANT关键字4️⃣REVOKE关键字5️⃣DENY关键字6️⃣总结附࿱…...

ChatGPT新功能曝光:可记住用户信息、上传文件和工作区
🦉 AI新闻 🚀 ChatGPT新功能曝光:可记住用户信息、上传文件和工作区 摘要:一张神秘截图曝光了ChatGPT新功能,包括可记住用户信息的"My profile"、上传和管理文件的"My files"以及可以让AI使用不…...

【Unity编辑器扩展】(三)PSD转UGUI Prefab, 一键拼UI解放美术/程序(完结)
工具效果: 第一步,把psd图层转换为可编辑的节点树,并自动解析UI类型、自动绑定UI子元素: 第二步, 点击“生成UIForm"按钮生成UI预制体 (若有UI类型遗漏可在下拉菜单手动点选UI类型): 验证一键生成UI效果: 书接上…...

SpringBoot开发Restful风格的接口实现CRUD功能
基于SpringBoot开发一个Restful接口 前言一、什么是SpringBoot?二、实战---基于SpringBoot开发一个Restful接口1.开发前的准备工作1.1 添加相关依赖 (pom文件) 1.2 创建相关数据库和表1.3 数据库配置文件 2.实战开发---代码逻辑2.1 实体类2.2…...

【Servlet学习三】实现一个内存版本的简易计算器~
目录 一、方式1:使用form表单的形式(不推荐) 🌈1、前端代码:HTML文件 🌈2、后端代码:Calculator_form.java文件 🌈3、最终效果 二、方式2:使用ajax形式(…...

Linux c语言获取本机网关 ip 地址
文章目录 前言一、获取本机网关 ip 地址1.1 代码示例1.2 代码详解介绍 二、使用Netlink套接字实时监控网络事件2.1 简介2.2 示例代码 前言 这篇文章写了获取本机的ip地址和子网掩码:Linux c语言获取本机 ip、子网掩码 一、获取本机网关 ip 地址 使用Netlink套接字…...

nginx部署本地项目如何让异地公网访问?服务器端口映射配置!
接触过IIS或apache的小伙伴们,对nginx是比较容易理解的,nginx有点类似,又有所差异,在选择使用时根据自己本地应用场景来部署使用即可。通过一些对比可能会更加清楚了解: 1.nginx是轻量级,比apache占用更少…...

云时代已至,新一代数据分析平台是如何实现的?
2023 年 5 月,由 Stackoverflow 发起的 2023 年度开发者调查数据显示,PostgreSQL 已经超越 MySQL 位居第一,成为开发人员首选。PostgreSQL 在国内的热度也越来越高。6 月 17 日,PostgreSQL 数据库技术峰会在成都顺利召开。本次大会…...

【C#】简单聊下Framework框架下的事务
框架用的多了,之前版本的事务都忘记了。本次简单聊下.net framework 4.8框架下本身的事务 目录 1、SqlClient2、TransactionScope3、引用 1、SqlClient 在 C# 中,使用 using 块可以方便地实现对资源的自动释放,但它不适用于实现事务处理。为…...

asyncPool并发执行请求函数
asyncPool应用场景 一个不太常见的极端场景,当我们为了某个操作需要发生异步请求的时候,等待所有异步请求都完成时进行某些操作。这个时候我们不在简简单单的发送 1 - 2 个请求而是 5 - 10个(其实极端场景式 很多很多个请求,这个…...

Ubuntu 22.04上安装NFS服务
1、使用如下命令安装NFS服务端软件: # 在主机上运行以下命令 orangepiorangepi5:~$ sudo apt install nfs-server 2、在配置NFS时需要使用用户uid和组gid,可以使用id命令查看 # 在主机上运行id命令 orangepiorangepi5:~$ id uid1000(orangepi) gid100…...