标签编码 vs One-Hot 编码:“城市“为什么不能直接喂给模型?
很多机器学习数据里都会有类别字段比如城市、性别、职业、会员等级、商品类型。这些字段对预测很有用但模型不能直接读取北京“黄金会员”电子产品这些文字必须先把类别转换成数字。这一步叫类别编码。编码本身不难难的是选错方式后数字会向模型传递错误的大小或距离关系。两种编码方式两种世界观第一种是 Label Encoding标签编码给每个类别分配一个数字普通会员 - 0 白银会员 - 1 黄金会员 - 2第二种是 One-Hot Encoding独热编码把一个类别字段拆成多列每列用 0/1 表示是/否样本 city_北京 city_上海 city_广州 city_纽约 北京 1 0 0 0 上海 0 1 0 0 广州 0 0 1 0 纽约 0 0 0 1两种方法都把文字变成了数字但传递给模型的含义完全不同。用 Label Encoding 把北京0、上海1、广州2、纽约3喂给一个线性模型模型会按数字大小理解它们之间的关系纽约(3) 广州(2) 上海(1) 北京(0)而且数字相差越大差别越大。城市之间并不存在这种大小关系这就是错误信息。One-Hot 让每个类别独占一列任意两个类别之间的距离都相同不引入虚假的顺序或距离。代价是维度膨胀1000 个城市就会多出 1000 列。Label Encoding 适合什么情况Label Encoding 适合有明确顺序的类别比如低/中/高或差/一般/好/优秀。这些类别本身有大小关系用数字表达是合理的。fromsklearn.preprocessingimportOrdinalEncoder encoderOrdinalEncoder(categories[[普通会员,白银会员,黄金会员]])df[member_level_code]encoder.fit_transform(df[[member_level]])类别顺序最好由你自己指定不要完全交给工具按字母或出现顺序自动决定否则黄金会员可能被编在白银会员前面。One-Hot Encoding 适合什么情况One-Hot 更适合没有大小顺序的类别比如城市。北京、上海、深圳之间没有谁天然比谁更大。importpandasaspd dfpd.get_dummies(df,columns[city],drop_firstFalse)这样每个城市都变成一列只表示这个样本是否属于该城市。一个简单选择表编码方式何时用何时不用Label / Ordinal Encoding类别有天然顺序小学中学大学青铜白银黄金无序类别城市、颜色、职业、商品类目One-Hot Encoding类别之间互相独立、没有大小或远近关系类别数量极多1000 个或使用树模型有顺序的类别 - Ordinal / Label Encoding 无顺序且类别不多 - One-Hot Encoding 类别特别多 - 先合并低频或考虑目标编码 / Embedding 预测时可能有新类别 - 编码器要支持 unknown这不是绝对规则但足够帮你完成第一个版本。一个重要例外决策树和随机森林树模型判断分支的方式是这个特征 ≤ 某个值吗所以即便把城市编码成 0、1、2、3树模型也能通过多层分裂把不同城市分开。这种情况下 Label Encoding 也能工作。但树模型对编码不敏感不代表 One-Hot 没用。为了代码可读性和调试友好新手阶段统一用 One-Hot 是更安全的选择。训练和预测必须用同一套编码规则类别编码最容易出问题的地方是训练和预测不一致。比如训练时城市只有北京、上海、深圳上线后来了一个新城市杭州。如果编码器没有处理未知类别预测接口可能直接报错。fromsklearn.preprocessingimportOneHotEncoder encoderOneHotEncoder(handle_unknownignore,sparse_outputFalse)encodedencoder.fit_transform(train_df[[city]])new_encodedencoder.transform(new_df[[city]])注意训练集用fit_transform新数据只用transform。不能在预测数据上重新fit否则列的含义会变。One-Hot 的进阶操作避开三个雷oheOneHotEncoder(sparse_outputFalse,# 默认输出稀疏矩阵转 dense 后续操作更省心handle_unknownignore,# 测试集出现训练集没见过的类别时安全处理dropfirst# n 个类别只用 n-1 列避免多重共线性)为什么需要dropfirst如果 n 个类别建了 n 列任意 n-1 列就能推出第 n 列每行恰好有一个 1。这在逻辑回归和线性回归中会引起多重共线性模型参数变得不稳定、不可靠。删掉第一列问题就解决了。小结类别编码的核心不是怎么把文字变成数字而是这个数字会不会传递错误含义。类别特征必须先转成数字无序类别不要随便用 Label EncodingOne-Hot 更安全独热编码会增加特征列数高基数类别考虑合并低频或用目标编码、Embedding编码规则要和模型一起保存训练和预测使用同一套规则。下一课继续讲数值特征标准化和归一化有什么区别什么时候需要做。在线阅读点击这里阅读博客原文原文地址https://bestsdz.xyz/posts/label-encoding-vs-one-hot/