想象你是一家神秘酒店的中文前台接待员。今晚有五位客人同时涌入大堂:来自中国的王先生、日本的铃木小姐、美国的杰克、法国的露西,还有巴西的佩德罗。你那台“AI前台系统”什么都好,唯独有个怪脾气——它只认数字。你递过去一张写着“国籍:中国”的登记表,屏幕立刻弹出红色警告:无法识别文本。你总不能把客人赶走吧?于是你急中生智,设计了一套“数字登记卡”:把每种文字信息翻译成一串数字。这就是类别编码的起点。 但随着接触的客人越来越多,你发现“翻译”的策略五花八门,各有门道。给每种国籍单独开一列打勾(One-Hot),很快就把登记表撑爆了;用这类客人的平均消费来代表(目标编码),又怕被个别土豪带偏;用出现频率当编号(频率编码),简单却没什么内涵;让AI自己学会一套“数字画像”(嵌入编码),听着玄乎,却可能最懂客人。这篇笔记,就带你跟着前台小陈,把四种编码挨个试一遍,最后学会在真实项目里挑出最合适的那一个。

岗位关联

掌握类别编码是特征工程的基本功。理解 One-Hot、Target Encoding 等方法的原理与适用边界,能帮你在建模时避开维度爆炸和过拟合两大暗坑,做出更合理的算法选型与架构决策,是从“拍脑袋调参”走向“系统化建模”的关键一步。

目录
  1. 可视化演示
  2. 编码缘起——AI前台只认数字
  3. One-Hot独热——一人一格的登记表
  4. 目标编码——平均消费当替身
  5. 频率编码——按出现次数编号
  6. 嵌入编码——AI自学的数字画像
  7. 选型之道——什么场景选什么编码
  8. 实战要点——别在小阴沟里翻船
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。

本节配有交互动效(进入视口后自动加载,约 3KB)。

系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T

编码缘起——AI前台只认数字

晚上九点,五湖四海的客人同时涌进前台。小陈飞快地敲着键盘,把每位客人的国籍、偏好、会员等级一条条录进系统。可当她敲下“国籍:中国”这行字时,屏幕却弹出一行红字:无法识别文本。小陈愣了——这套AI前台系统什么都好,唯独是个“数字控”,只认数字,不认文字。

这其实是所有机器学习模型的通病。类别特征(比如国籍、职业、商品类目)的取值是一串离散的字符串,而模型内部的数学运算——求内积、算距离、做梯度下降——全部建立在数值空间之上。更要命的是,数字天然有“大小”:5 比 3 大,但“中国”和“日本”之间没有大小,也没有“距离”。如果把文字按字典序硬编成 1、2、3,模型就会误以为“日本”恰好居于“中国”和“美国”的正中间,得到完全错误的规律。

因此,类别编码的本质,就是设计一个映射函数,把类别集合翻译成模型能计算的数字向量。这个函数必须守住两条底线:一是不同的类别要翻译成不同的数字(保持区分度);二是不能凭空捏造虚假的“大小关系”(保持语义中立)。不同的编码方式,就是对同一个映射的不同设计方案。

小陈明白了一个道理:翻译不能瞎翻。她需要一张足够聪明的“登记卡”,让每种国籍都能被 AI 准确识别,又不让 AI 产生奇怪的联想。接下来的四个方案,就是她陆续尝试的四种编码套路。

f:C→Rdf: \mathcal{C} \rightarrow \mathbb{R}^d
一句话:类别编码就是给文字类别找一套“数字身份”,让模型能算、还算得准。
  1. C(类别集合)所有可能取值的集合,比如五种国籍组成的集合。
    C\mathcal{C}
  2. R^d(d 维实数空间)模型真正发生运算的空间,里面的数字向量可以做加法和乘法。
    Rd\mathbb{R}^d
  3. f(映射函数)编码规则本身,也就是小陈设计的“数字登记卡”,把每个文字类别变成数字向量。
    f:C→Rdf: \mathcal{C} \rightarrow \mathbb{R}^d

One-Hot独热——一人一格的登记表

小陈的第一个方案最简单直白:一人一格。她做了一张登记表,五种国籍就是五列:中国、日本、美国、法国、巴西。客人来自哪里,就在对应列打 1,其余列打 0。整张表干净、清晰,AI 前台一眼就认出了每一位客人。这就是 One-Hot 独热编码——“独热”的意思是:只有自己那个格子是“热”的(1),其他格子全是“冰”的(0)。

这种方案的好处是彻底:类别之间完全正交,谁也不挨着谁,不存在“谁离谁更近”的误导,实现也极其简单。但代价同样肉眼可见:5 种国籍要 5 列,要是碰上 300 个城市、一万个商品 ID,登记表会宽到离谱,而且每一行几乎全是 0,内存和训练时间双双爆炸。

小陈盯着那张越拉越宽的登记表叹了口气:酒店才开业半年,国籍就从 5 种涨到了 30 种,照这个速度,One-Hot 这张表迟早得贴在城墙上。她不得不另想办法。

xi(k)={1,if category=ck0,otherwisex_i^{(k)} = \begin{cases} 1, & \text{if category} = c_k \\ 0, & \text{otherwise} \end{cases}
一句话:第 i 个样本的类别如果恰好是第 k 类,就在第 k 个维度的格子上点亮 1,其余格子全部填 0。
  1. x_i^(k)第 i 个样本在第 k 个编码维度上的取值。这里“第 i 个样本”是眼前某位客人,“第 k 个维度”是某一种国籍对应的那一列。
    xi(k)x_i^{(k)}
  2. 条件判断如果该样本的真实类别恰好是第 k 类,那么这个维度就点亮为 1,相当于在登记表对应格子打了个勾。
    if category=ck\text{if category} = c_k
  3. 置 1 置 0条件成立写 1,不成立写 0。每一行只有一个 1,其余全是 0,所以叫“独热”。
    xi(k)=1或xi(k)=0x_i^{(k)} = 1 \quad \text{或} \quad x_i^{(k)} = 0

目标编码——平均消费当替身

小陈灵机一动:何必一个国籍占一列?不如用一个数代表这个国籍。她翻开 VIP 消费记录,算出每个国籍客人的平均消费额——日本客人平均每年消费 85 个单位,巴西客人只有 48。以后遇到日本客人,就在“国籍”这一栏填 85,遇到巴西客人填 48。AI 前台照样能干活,登记表却只有一列,再也不怕类别多了。这就是 Target Encoding(目标编码):用类别内部的目标变量均值来代表这个类别。

目标编码的威力在于,它把“类别”和“预测目标”直接挂钩,信息密度很高。在电商、风控这类场景里,商品类目、职业代码等类别特征往往和目标(是否点击、是否违约)存在强关联,用它替换 One-Hot 能把模型效果拉升一大截。但危险也随之而来:如果一个类别只有 1 个样本,它的“均值”就是那一个人的数值,极端又不可靠。

小陈把公式抄在本子上:小类别的统计不可信时,就向全体客人的平均消费“收缩”一点,像新手估价师拿不准小区房价时,会往城市均价靠一靠。她给这个方案打了个勾,记下“高基数专用”。

x^c=nc⋅yˉc+m⋅yˉnc+m\hat{x}_c = \frac{n_c \cdot \bar{y}_c + m \cdot \bar{y}}{n_c + m}
一句话:把某个类别自己的平均值和全体平均值做加权折中,样本越少越向全局均值靠拢,防止小样本过拟合。
  1. n_c类别 c 在样本中出现的次数,相当于“这类客人的数量”。
    ncn_c
  2. ȳ_c类别 c 内部目标变量的平均值,比如“日本客人的平均消费”。
    yˉc\bar{y}_c
  3. ȳ全体样本的目标均值,也就是“所有客人的平均消费”。
    yˉ\bar{y}
  4. m(平滑参数)代表“先验强度”。m 越大,结果越向全局均值靠拢,小样本的噪音被压得越狠。
    mm
  5. 加权折中分子是“自己类别的均值乘样本数”加上“全局均值乘平滑强度”,分母归一化。样本越多,越信自己;样本越少,越信全局。
    x^c=nc⋅yˉc+m⋅yˉnc+m\hat{x}_c = \frac{n_c \cdot \bar{y}_c + m \cdot \bar{y}}{n_c + m}

频率编码——按出现次数编号

又过了几天,小陈接到一个新需求:给客人按“出生省份”分类。全国三十多个省份,用目标编码要小心维护均值,她嫌麻烦,干脆用起了最原始的笨办法——数数。哪个省份来的客人最多,这个省份的编号就最大。她把每个类别的出现次数除以总人数,得到一个 0 到 1 之间的比例,直接填进登记表。这就是频率编码。

频率编码没有任何花哨之处,但恰恰因为简单,它有三个好处:计算快、稳定、不会泄漏目标信息。它完全不依赖标签,所以即使在训练集和测试集分布略有偏移时,也不会像目标编码那样“一激动就过拟合”。缺点是信息量确实有限——它只描述了“常见度”,而常见度和业务目标往往只是弱相关,通常只能当辅助特征。

小陈在笔记里写道:频率编码就像按姓氏常见度给客人编号,“王”的编号很大,但老王是不是大客户?真不一定。它可以做保底方案,却不能当主力。

xc=ncNx_c = \frac{n_c}{N}
一句话:类别 c 的编码值就是它出现的概率,出现越多数字越大。
  1. n_c类别 c 在全部样本中出现的次数。
    ncn_c
  2. N全部样本的总数。
    NN
  3. 比值类别出现的频率,落在 0 到 1 之间,这就是填进登记表的数字。
    xc=ncNx_c = \frac{n_c}{N}

嵌入编码——AI自学的数字画像

后来酒店装了一套深度学习系统,小陈发现 AI 有个惊人的本事:它不再需要人为设计编码规则了,而是自己“学”出一套数字画像。系统给每个类别随机发一个初始向量,然后在训练中不断调整,最终让消费习惯相近的类别,在向量空间里的距离也相近。换句话说,AI 自己悟出了“日本客人常常和法国客人一样爱买红酒”之类的规律。这就是嵌入编码(Embedding)。

嵌入的本质是查表:每个类别对应一个稠密向量,维度由我们指定(比如 64 维),远小于类别总数。它既能压缩维度、缓解 One-Hot 的稀疏问题,又能表达类别之间的语义相似性,在推荐系统、NLP、用户画像中大放异彩。缺点是训练需要大量数据和算力,而且学出来的向量很难向业务方解释“为什么这两个类别离得近”。

小陈看着系统输出的向量坐标,笑着摇摇头:这就像老员工凭直觉把烟民都安排在同一个楼层,新客人一来就安排到隔壁——他自己也说不清理由,但结果就是让人舒坦。嵌入编码也是这么个“直觉”,只不过它的直觉是从数据里泡出来的。

ec=W⋅1ce_c = \mathbf{W} \cdot \mathbf{1}_c
一句话:嵌入编码就是准备一张可学习的查找表,每个类别查出自己的低维稠密向量。
  1. 1_c(one-hot 临时向量)先把类别 c 表示成一个“只有第 c 位是 1”的临时向量,当作查表钥匙。
    1c\mathbf{1}_c
  2. W(嵌入矩阵)d 行 K 列的矩阵,每一列就是对应类别的待学习向量,AI 训练时不断调整它。
    W∈Rd×K\mathbf{W} \in \mathbb{R}^{d \times K}
  3. 矩阵乘法乘以 1_c 等价于从 W 中取出第 c 列,也就是这个类别对应的那 d 个数。
    W⋅1c\mathbf{W} \cdot \mathbf{1}_c
  4. e_c(编码结果)最终得到的稠密向量,相似类别的向量在空间里靠得近,像“数字双胞胎”。
    ec∈Rde_c \in \mathbb{R}^d

选型之道——什么场景选什么编码

四种编码摆在桌上,小陈该选哪一张登记卡?她给自己总结了四个问题,这也是在实际项目中做编码选型时需要回答的核心问题:

1. 类别基数有多大? 类别数很少(比如小于 10),优先 One-Hot,简单且可解释;类别数很大(几百上千),立刻放弃 One-Hot,转投目标编码或嵌入编码。

2. 模型是什么类型? 树模型对特征做了大量非线性切分,对数值的具体尺度不敏感,可以放心使用目标编码和频率编码;线性模型对特征尺度敏感,编码前通常还需要标准化。

3. 样本量够不够? 数据量小时,平滑的目标编码依然有风险,此时频率编码更抗造;数据量大且模型是深度网络时,嵌入编码的上限最高。

4. 业务方要不要解释? 银行审核、医疗诊断这类强解释场景,目标编码和嵌入都很难交代,频率编码或 One-Hot 更稳妥。

选型不是非此即彼。一个常见技巧是把多种编码叠加使用,比如“目标编码 + 频率编码”拼成两列,让模型从“语义均值”和“常见度”两个角度同时吸收类别信息。小陈在笔记里总结成一句话:低基数要解释就 One-Hot,高基数要效果就 Target,怕泄漏图省事就频率,有数据要语义就嵌入。

半年后,小陈的酒店登记系统再也没出过大岔子。她看着手里的四张编码卡和一份选型清单,心想:所谓特征工程,原来就是把这些“翻译”的小事做到极致。数据不会说话,编码就是替数据说出模型能听懂的话。

实战要点——别在小阴沟里翻船

编码选型尘埃落定,小陈却在后续运营中踩了几个大坑,这里把它们都写出来,当作前车之鉴。第一个坑是缺失值:某个客人没填国籍,登记表那一栏空着。小陈一开始填 0,结果发现 0 和其他真实类别的编码混在一起,预测全乱。正确做法是单独设一个“未知”类别,给它编一个独立的编码值,而不是硬填 0。

第二个坑是罕见类别。有个国家的客商一年只来两三次,目标编码给它的均值全是噪音。小陈设了一个阈值统计,出现次数少于某个数的类别,一律合并成“其他”,再一起编码。第三个坑也是最隐蔽的——时序泄漏。她最初做目标编码时,直接在全量训练数据上统计均值,结果模型在测试集上表现惨不忍睹。原来编码值偷看了样本自己的标签,就像考试时你先看了答案再做题,平时成绩漂亮,上考场就露馅。正确做法是在交叉验证的每一折内只使用其余折的数据做统计,时序场景则只用截止日期之前的数据。

第四个坑是编码统一。上线那天,线上系统遇到一个训练集里从没见过的“新国籍”,映射表查不到,程序直接崩溃。小陈在映射表里加了一个默认值兜底,把所有未知类别统一映射到“未知”编码上,系统这才安安稳稳。她还养成了一个习惯:把训练好的映射表存成文件,训练和预测共用同一份,确保两边口径永远一致。

小陈把四个坑的教训贴在了总台背后的墙上:缺失值设未知、罕见类别合并、防泄漏、编码统一。登记表终于安安稳稳地运转起来,而她的“数字登记卡”故事,也成了新员工入职培训的必备一课。

AI 应用场景

场景一:电商平台的类别特征编码(CTR 预估)

阶段:特征工程

解决的问题:用户点击率预估中,商品类目、品牌 ID 是高基数类别特征。直接用 One-Hot 会产生几十万维稀疏矩阵,训练慢且内存爆炸。Target Encoding 把每个类目的“历史点击率”编码成一个数值,维度骤降,且在平滑 + 交叉验证保护下不会过拟合。

具体案例:某跨境电商模型,商品类目约 5 万个。采用 K 折交叉验证内的目标编码(平滑参数 m=50),配合频率编码构造辅助特征,编码后训练特征维度从 5 万降到 120,模型 AUC 提升约 2 个百分点,训练速度提升 20 倍。

场景二:金融风控中的职业代码编码

阶段:特征工程

解决的问题:信贷审批中“客户职业”有数百个类别,且与违约率显著相关。目标编码能把这个强信号提炼成一个数,但直接全量统计会造成数据泄漏,必须用交叉验证内的统计值。

具体案例:某银行用平滑目标编码(m=20)对职业编码,违约率高的职业得到较高的编码值,模型 KS 值提升 0.03;同时把出现次数少于 50 的职业合并为“其他”,避免了小样本噪声。

场景三:推荐系统里的嵌入编码

阶段:表示学习

解决的问题:用户观看序列中的视频 ID 是超高频类别,One-Hot 完全不可行。嵌入编码让相近视频的向量靠近,模型习得“看了 A 的人也会看 B”的语义。

具体案例:某视频平台用 64 维嵌入表示 100 万视频 ID,作为深度排序模型的输入;同时把训练好的视频向量导出,作为 GBDT 的候选特征,离线 AUC 提升 3.5%。

Python 演示

python53 行
# -*- coding: utf-8 -*-"""类别编码示例:One-Hot / Target / 频率 三种策略的对比""" import numpy as np  class CategoryEncoder:    """把文字类别翻译成模型能用的数字(类比前台小陈的数字登记卡)"""     def __init__(self, method="onehot", smooth=10.0):        self.method = method        self.smooth = smooth        self.mapping_ = {}        self.columns_ = None     def fit(self, x, y=None):        x = np.asarray(x)        if self.method == "onehot":            self.columns_ = sorted(set(x.tolist()))        elif self.method == "target":            y = np.asarray(y, dtype=float)            global_mean = float(y.mean())            for cat in set(x.tolist()):                mask = (x == cat)                n_c = int(mask.sum())                mean_c = float(y[mask].mean()) if n_c > 0 else global_mean                self.mapping_[cat] = (n_c * mean_c + self.smooth * global_mean) / (n_c + self.smooth)        elif self.method == "freq":            n = len(x)            for cat in set(x.tolist()):                n_c = int((x == cat).sum())                self.mapping_[cat] = n_c / n        else:            raise ValueError("unknown method: " + str(self.method))        return self     def transform(self, x):        x = np.asarray(x)        if self.method == "onehot":            out = np.zeros((len(x), len(self.columns_)))            for i, cat in enumerate(x.tolist()):                out[i, self.columns_.index(cat)] = 1            return out        return np.array([self.mapping_.get(cat, 0.0) for cat in x.tolist()])  if __name__ == "__main__":    x = np.array(["cn", "jp", "us", "cn", "us", "cn", "fr", "jp"])    y = np.array([90.0, 60.0, 85.0, 95.0, 88.0, 80.0, 45.0, 58.0])    for method in ["onehot", "target", "freq"]:        enc = CategoryEncoder(method=method, smooth=10.0)        enc.fit(x, y)        print(method, enc.transform(x))
目的:用 70 行实现三种类别编码策略,并在同一个数据集上展示它们的编码结果差异,方便直观对比。
  1. class CategoryEncoder:定义一张“数字登记卡”的统一接口,三种编码共用这套逻辑。
  2. self.mapping_ = {}登记册:存储“类别 → 数字”的映射关系,fit 阶段填好,transform 阶段查表。
  3. global_mean = float(y.mean())全体目标均值,作为目标编码平滑时的基准量。
  4. self.mapping_[cat] = (n_c * mean_c + self.smooth * global_mean) / (n_c + self.smooth)目标编码的核心公式:小样本类别向全局均值收缩,防止过拟合。
  5. out[i, self.columns_.index(cat)] = 1One-Hot 点灯:在对应类别列上写 1,其余列保持 0。
  6. np.array([self.mapping_.get(cat, 0.0) for cat in x.tolist()])查表映射,遇到没见过的新类别时用 0.0 兜底,对应实战中的“新类别防崩”。

常见误区

误区类别特征不都能用 One-Hot 吗?类别多就多几列,模型训练慢就加机器调参,反正 One-Hot 最经典、最不容易出错。

正解One-Hot 只在低基数类别上划算。类别数很大时,One-Hot 会产生稀疏高维矩阵,存储爆炸、训练变慢,还会引入大量冗余维度。高基数场景应优先目标编码、频率编码或嵌入编码。经典不等于万能,选型要看基数。

为何常见:教程里第一个教的往往是 One-Hot,它直观又好写,容易让初学者把它当成默认方案,忽略了它背后的维度代价。

误区目标编码不就是把训练集里每个类别的平均标签算出来填进去吗?几行代码搞定,为什么要搞交叉验证那么麻烦?

正解全量统计会让编码值“偷看”样本自己的标签,训练时拟合得很漂亮,测试时一塌糊涂——这就是数据泄漏。正确做法是用 K 折交叉验证,每一折只用其余折的数据做统计,时序场景则只用历史数据。

为何常见:写起来实在是太简单了,而泄漏的影响要到线下测试才暴露,隐蔽性强,很多人踩了坑还以为是模型调参问题。

误区频率只反映“常见度”,跟预测目标基本没关系,信息量这么低,用了也白用。

正解频率编码不依赖目标标签,天然不会泄漏,稳定又鲁棒。它可以表达“稀有度”这类信号,在许多场景里是很好的辅助特征。工程上“稳定压倒一切”,简单方案常常是保底的最优解。

为何常见:因为它的值域单调、看起来“没内涵”,容易被追求复杂模型的人轻视,忽略了它在稳定性和计算成本上的优势。

误区嵌入是神经网络才能学出来的东西,我用的是 XGBoost,跟嵌入八竿子打不着。

正解嵌入编码的本质是可复用的低维向量,完全可以先让神经网络或矩阵分解模型预训练好,再把这组向量作为输入特征喂给 GBDT、线性模型等传统模型。深度学习不是嵌入的专利。

为何常见:看到“嵌入”两个字就联想到深度学习,忘了它只是一组从数据中学到的稠密表示,换谁都能用。

误区线上遇到训练集没见过的类别,映射表查不到,那就在那一列填 0 吧,反正模型也需要处理缺失。

正解直接填 0 会让“未知”和某些真实类别的编码值混淆,污染预测结果。正确做法是单独映射到“未知类”编码,或在代码里用默认值兜底,同时保证训练和预测共用同一套映射表。

为何常见:查表报错后的“偷懒”解法,没意识到 0 在数值型特征里也是一个有含义的数字,乱填会扭曲模型的判断。

面试题

Q1. 为什么要对类别特征做编码?

单选题 · easy

  • A.让类别特征变成模型可计算的数值← 正确答案
  • B.让数值特征变成类别特征
  • C.提升数据集的存储压缩率
  • D.消除特征之间的共线性

答案:A。机器学习模型的数学运算只认数字,类别编码的本质是把文字类别翻译成数值,而不是压缩存储或消除共线性。One-Hot 每一列高度相关反而会引入共线性,B、C、D 都不是编码的目的。

Q2. 标准 One-Hot 编码后新增的维度数量等于什么?

单选题 · easy

  • A.类别数减一
  • B.类别数的个数← 正确答案
  • C.等于样本数量
  • D.类别的对数

答案:B。标准 One-Hot 是每个类别单独占一列,所以维度数等于类别数。有的实现为了处理共线性会丢弃一列(类别数减一),但那是变体而非标准形式,不能混淆。

Q3. 面对一个有 1000 个取值的类别特征,应优先选择哪种编码?

单选题 · mid

  • A.One-Hot 独热编码
  • B.Target 目标编码← 正确答案
  • C.标签顺序编码
  • D.直接删除该特征

答案:B。1000 个类别用 One-Hot 会产生 1000 维稀疏矩阵,维度爆炸;标签顺序编码会强加虚假的大小关系。目标编码把类别压缩成一个均值数字,是高基数场景的首选方案。

Q4. One-Hot 编码有哪些明显缺点?

多选题 · mid

  • A.特征维度爆炸← 正确答案
  • B.编码结果稀疏← 正确答案
  • C.无法表达类别相似性← 正确答案
  • D.只能用于树模型

答案:ABC。One-Hot 每行只有一个 1,其余全是 0,类别多时维度爆炸且极度稀疏;同时每个类别都是独立的维度,无法表达“日本和法国都是发达国家”这类相似性。One-Hot 对线性模型、树模型都适用,D 是错的。

Q5. 目标编码中平滑参数 m 的作用是什么?

单选题 · mid

  • A.让编码值偏向该类均值
  • B.向全局均值收缩防止过拟合← 正确答案
  • C.把连续编码变成整数
  • D.加速模型训练收敛

答案:B。平滑参数 m 像“先验强度”:类别样本多时相信自己,样本少时向全局均值靠拢。它防止小样本类别的均值被极端值带飞,是目标编码防过拟合的关键手段,与整数化、加速收敛无关。

Q6. 以下哪些做法能降低 Target Encoding 的过拟合风险?

多选题 · hard

  • A.用全量训练集统计后直接编码
  • B.K 折交叉验证内分折统计编码← 正确答案
  • C.对小样本类别调大平滑参数← 正确答案
  • D.在编码值上加入随机噪声← 正确答案

答案:BCD。全量统计会让编码偷看当前样本的标签,属于泄漏;分折统计、调大平滑参数、加入噪声都是对目标编码的正则化手段,能有效降低过拟合。A 正是我们最该避免的做法。

Q7. 频率编码输出的数值范围是什么?

单选题 · easy

  • A.负数到正数
  • B.0 到 1 之间← 正确答案
  • C.0 到样本数 N 之间
  • D.1 到类别数 K 之间

答案:B。频率编码是“类别出现次数 ÷ 总样本数”,本质是一个概率,落在 0 到 1 之间。它不可能是负数,也不会超过 1,更不会等于类别数或样本数。

Q8. 训练集中从未出现过的新类别,在预测时应如何处理?

单选题 · mid

  • A.直接丢弃该样本
  • B.映射为未知类编码或默认值← 正确答案
  • C.用当前样本目标值现场统计
  • D.让模型自动忽略该维度

答案:B。直接丢弃样本会浪费预测机会;现场统计目标值等于作弊;模型无法自动忽略一维。正确做法是在代码里给未知类别一个独立编码值或默认兜底值,让预测流程不崩溃。

Q9. 关于嵌入编码,下列说法正确的是?

多选题 · hard

  • A.是一种分布式稠密向量表示← 正确答案
  • B.需要借助神经网络训练得到← 正确答案
  • C.相似类别向量距离更近← 正确答案
  • D.完全不需要任何训练数据

答案:ABC。嵌入把每个类别映射成低维稠密向量,通过神经网络训练学习,训练后语义相近的类别向量距离也近。它需要大量数据驱动,零训练数据是做不到的,D 说法错误。

Q10. 在按天预测销量的时序数据中做 Target Encoding,哪种做法是正确的?

单选题 · extreme

  • A.用包含测试期的全量数据统计编码
  • B.只用训练截止日之前的数据分折统计← 正确答案
  • C.用未来数据统计后编码过去
  • D.用随机洗牌的 KFold 统计编码

答案:B。时序数据有严格的时间先后,随机洗牌的交叉验证会把未来信息泄漏给过去。正确做法是只用截止日之前的数据做统计,并按时间顺序划分验证集。A 和 C 都用了未来数据,D 破坏了时间顺序,都属于典型泄漏。