0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

机器学习特征工程:分类变量的数值化处理方法

颖脉Imgtec 2026-02-10 15:58 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

编码是机器学习流程里最容易被低估的环节之一,模型没办法直接处理文本形式的分类数据,尺寸(Small/Medium/Large)、颜色(Red/Blue/Green)、城市、支付方式等都是典型的分类特征,必须转成数值才能输入到模型中。

50603b9c-0656-11f1-96ea-92fbcf53809c.jpg那么问题来了:为什么不直接把 Red 编成 1,Blue 编成 2?这个做法看起来简单粗暴,但其实藏着大坑。下面用一个小数据集来说明。


数据集概述

Feature | Description
-------------------|----------------------------------------------------------
customer_id | Unique customer identifier
gender | Male or Female
education_level | High School → Associate → Bachelor's → Master's → PhD
employment_status | Full-time, Part-time, Self-employed, Unemployed
city | Customer's city (50+ US cities)
product_category | Electronics, Clothing, Books, Sports, Home & Garden, Beauty, Food & Beverage
payment_method | Credit Card, Debit Card, PayPal, Cash
customer_tier | Bronze → Silver → Gold → Platinum
satisfaction_level | Dissatisfied → Neutral → Satisfied → Very Satisfied
credit_score_range | Poor → Fair → Good → Very Good → Excellent
purchase_amount | Purchase amount in USD
will_return | Yes or No (target variable)


Ordinal Encoding

Ordinal Encoding 思路很简单:给每个类别分配一个数字,但是模型会把这些数字当作有序的。

假设对payment_method做编码:Cash = 1,PayPal = 2。模型会认为 Cash < PayPal,仿佛 PayPal 比 Cash "更好" 或 "更大"。但支付方式之间根本没有这种大小关系因为它们只是不同的选项而已。

什么时候 Ordinal Encoding 才合适?当数据本身就存在真实的顺序关系时。比如education_level:High School < Associate < Bachelor's < Master's < PhD。这是客观存在的递进关系,用数字表示完全没问题,模型的理解也是对的。

所以 Ordinal Encoding 的使用场景很明确:只用于那些排名确实有意义的特征。

from sklearn.preprocessing import OrdinalEncoder
ordEnc = OrdinalEncoder()
print(ordEnc.fit_transform(data[["education_level"]])[:5])

# Output
"""
[[1.]
[2.]
[3.]
[4.]
[2.]]
"""


One-Hot Encoding

One-Hot Encoding 换了个思路:不用数字而是给每个类别创建一列。payment_method有 4 个值,就变成 4 列,每行只有一个位置是 1,其余全是 0。

| payment_cash | payment_credit_card | payment_debit_card | payment_paypal |
|--------------|---------------------|--------------------|----------------|
| 1 | 0 | 0 | 0 |
| 0 | 1 | 0 | 0 |
| 0 | 0 | 1 | 0 |
| 0 | 0 | 0 | 1 |

这样做的好处是消除了虚假的顺序关系,所有类别被平等对待和线性模型配合得也很好。

那么代价是什么?维度会膨胀。customer_tier和payment_method各 4 个值,合起来就是 8 列。如果遇到城市这种特征,50 多个类别直接炸成 50 多列,维度灾难就来了。

from sklearn.preprocessing import OneHotEncoder
oneEnc = OneHotEncoder()
print(oneEnc.fit_transform(data[["customer_tier", "payment_method"]]).toarray()[:5])

#output
"""
[[0. 1. 0. 0. 0. 1. 0. 0.]
[0. 0. 0. 1. 0. 0. 1. 0.]
[0. 0. 1. 0. 0. 0. 0. 1.]
[0. 1. 0. 0. 0. 1. 0. 0.]
[1. 0. 0. 0. 1. 0. 0. 0.]]
"""


Target Encoding

面对高基数特征(比如 City 有 50 多个值)One-Hot Encoding 会把特征空间撑得太大,Target Encoding 的做法是:用每个类别对应的目标变量均值来替换。也叫 Mean Encoding。

举个例子,目标变量是will_return(Yes = 1,No = 0):

| City | will_return |
|-----------|-------------|
| Austin | 1 |
| Austin | 1 |
| New York | 1 |
| New York | 0 |
| New York | 0 |
| New York | 0 |
| New York | 1 |

计算每个城市的目标均值:Austin → (1 + 1) / 2 = 1.0,New York → (1 + 0 + 0 + 0 + 1) / 5 = 0.4,这样得到的编码结果就是:

| City | Encoded Value |
|----------|----------------|
| Austin | 1.0 |
| New York | 0.4 |

这里有一个坑,Austin 只出现了 2 次而且刚好都是正例,编码值直接变成 1.0。模型可能会 "学到" 一个规律:看到 Austin 就预测 will_return = Yes。

但这个 "规律" 完全是数据量不足造成的假象。样本太少均值就很不可靠。

Smoothing 的思路是把类别均值往全局均值方向 "拉" 一拉。公式:

Encoded Value = (w * Category Mean) + ((1 - w) * Global Mean)

其中 Category Mean 是该类别的目标均值Global Mean 是整个数据集的目标均值,w 是一个和样本量相关的权重。样本越少w 越小,编码值就越接近全局均值;样本越多类别自己的均值就越占主导。这能有效抑制小样本带来的过拟合。

另一个问题就是 Data Leakage。如果用全量数据计算编码值再把这个编码喂给模型,模型等于直接 "看到了" 答案的统计信息。比如模型发现 City = 0.34 对应的样本大概率是 will_return = Yes,那它干脆走捷径,不从其他特征里学东西了。

所以就要引入交叉验证,以 5 折为例:把数据分成 5 份,对第 1 份的数据,用第 2 到第 5 份来计算编码;对第 2 份的数据,用第 1、3、4、5 份来计算编码;以此类推。每个样本的编码值都来自于它 "没见过" 的数据,泄露就切断了。

但是副作用是同一个城市在不同折里的编码值会略有差异:New York 在 Fold 1 里可能是 0.50,在 Fold 2 里是 0.45。但这反而是好事,这样可以让模型被迫学习更一般化的模式而不是死记某个精确数值。

Target Encoding 的优点:避免维度爆炸,适合高基数特征,还能把目标变量的统计信息编进去。

但用的时候得小心:必须加 Smoothing 防止小样本过拟合,必须用交叉验证防止数据泄露。

from sklearn.preprocessing import TargetEncoder

data["will_return_int"] = data["will_return"].map({"Yes": 1, "No": 0})
tarEnc = TargetEncoder(smooth="auto", cv=5) # Those are the default value
print(data[["city"]][:5])
print(tarEnc.fit_transform(data[["city"]], data["will_return_int"])[:5])

"""
city
0 Houston
1 Phoenix
2 Chicago
3 Phoenix
4 Phoenix

[[0.85364466]
[0.69074308]
[0.65024828]
[0.74928653]
[0.81359495]]
"""


总结

三种编码方法各有适用场景,选择取决于特征本身的性质。

实际操作中可以这样判断:特征有天然顺序就用 Ordinal Encoding;没有顺序、类别数量也不多就用 One-Hot Encoding;类别太多就上 Target Encoding,记得配合 Smoothing 和交叉验证。

真实项目里,一个数据集往往会同时用到这三种方法。

本文转自:DeepHub IMBA

作者: adham ayman

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编码
    +关注

    关注

    6

    文章

    1041

    浏览量

    57194
  • 机器学习
    +关注

    关注

    67

    文章

    8570

    浏览量

    137381
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    机器学习算法的特征工程与意义详解

    1、特征工程与意义 特征就是从数据中抽取出来的对结果预测有用的信息。 特征工程是使用专业知识背景知识和技巧
    发表于 10-08 15:24 3486次阅读
    <b class='flag-5'>机器</b><b class='flag-5'>学习</b>算法的<b class='flag-5'>特征</b><b class='flag-5'>工程</b>与意义详解

    【下载】《机器学习》+《机器学习实战》

    ]目录:第一部分 分类第1章 机器学习基础  2第2章 k-近邻算法   15第3章 决策树   32第4章 基于概率论的分类方法:朴素贝叶
    发表于 06-01 15:49

    如何选择机器学习的各种方法

    每当提到机器学习,大家总是被其中的各种各样的算法和方法搞晕,觉得无从下手。确实,机器学习的各种套路确实不少,但是如果掌握了正确的路径和
    发表于 03-07 20:18

    图像分类方法之深度学习与传统机器学习

    实际情况非常复杂,传统的分类方法不堪重负。现在,我们不再试图用代码来描述每一个图像类别,决定转而使用机器学习方法
    发表于 09-28 19:43 0次下载

    机器学习应用中的常见问题分类问题你了解多少

    分类问题是机器学习应用中的常见问题,而二分类问题是其中的典型,例如垃圾邮件的识别。本文基于UCI机器学习
    的头像 发表于 03-29 16:40 1.6w次阅读
    <b class='flag-5'>机器</b><b class='flag-5'>学习</b>应用中的常见问题<b class='flag-5'>分类</b>问题你了解多少

    想掌握机器学习技术?从了解特征工程开始

    问题。解决这些问题的方法与数据预处理方法机器学习中被统称为特征
    的头像 发表于 12-05 09:36 2701次阅读

    机器学习特征工程是将原始的输入数据转换成特征

    对于类别数量很多的分类变量可以采用特征哈希(Hashing Trick),特征哈希的目标就是将一个数据点转换成一个向量。利用的是哈希函数将原始数据转换成指定范围内的散列值,相比较独热模
    的头像 发表于 04-19 16:42 5372次阅读
    <b class='flag-5'>机器</b><b class='flag-5'>学习</b>的<b class='flag-5'>特征</b><b class='flag-5'>工程</b>是将原始的输入数据转换成<b class='flag-5'>特征</b>

    机器学习特征工程的五个方面优点

    特征工程是用数学转换的方法将原始输入数据转换为用于机器学习模型的新特征
    的头像 发表于 03-15 16:57 4762次阅读

    常见的11个分类变量编码方法

    机器学习算法只接受数值输入,所以如果我们遇到分类特征的时候都会对分类
    的头像 发表于 11-28 15:45 5143次阅读

    机器学习算法学习特征工程1

    特征工程机器学习过程中的关键步骤,涉及将原始数据转换为机器学习算法可以有效使用的格式。在本篇博
    的头像 发表于 04-19 11:38 1799次阅读
    <b class='flag-5'>机器</b><b class='flag-5'>学习</b>算法<b class='flag-5'>学习</b>之<b class='flag-5'>特征</b><b class='flag-5'>工程</b>1

    机器学习算法学习特征工程2

    特征工程机器学习过程中的关键步骤,涉及将原始数据转换为机器学习算法可以有效使用的格式。在本篇博
    的头像 发表于 04-19 11:38 1715次阅读
    <b class='flag-5'>机器</b><b class='flag-5'>学习</b>算法<b class='flag-5'>学习</b>之<b class='flag-5'>特征</b><b class='flag-5'>工程</b>2

    机器学习算法学习特征工程3

    特征工程机器学习过程中的关键步骤,涉及将原始数据转换为机器学习算法可以有效使用的格式。在本篇博
    的头像 发表于 04-19 11:38 1827次阅读
    <b class='flag-5'>机器</b><b class='flag-5'>学习</b>算法<b class='flag-5'>学习</b>之<b class='flag-5'>特征</b><b class='flag-5'>工程</b>3

    什么是特征工程机器学习特征工程详解解读

    One-hot 编码对于用机器学习模型能够理解的简单数字数据替换分类数据很有用。
    发表于 12-28 17:14 822次阅读
    什么是<b class='flag-5'>特征</b><b class='flag-5'>工程</b>?<b class='flag-5'>机器</b><b class='flag-5'>学习</b>的<b class='flag-5'>特征</b><b class='flag-5'>工程</b>详解解读

    深度学习中的时间序列分类方法

    的发展,基于深度学习的TSC方法逐渐展现出其强大的自动特征提取和分类能力。本文将从多个角度对深度学习在时间序列
    的头像 发表于 07-09 15:54 3341次阅读

    机器学习中的数据预处理特征工程

    机器学习的整个流程中,数据预处理特征工程是两个至关重要的步骤。它们直接决定了模型的输入质量,进而影响模型的训练效果和泛化能力。本文将从数
    的头像 发表于 07-09 15:57 2706次阅读