机器学习数据预处理:数据编码

机器学习数据预处理:数据编码(超通俗完整版)

数据编码就是把文字、类别、标签,转换成计算机能看懂的数字,是处理分类特征必做步骤,不管是本科作业、研究生论文、工业项目都高频使用。


一、什么是数据编码?为什么必须做?

1. 一句话理解

机器只认识数字,不认识文字
“男/女、红/绿/蓝、北京/上海、低/中/高”这类特征,必须转成数字才能建模,这个过程就是数据编码

2. 不编码会怎样?

  • 模型直接报错,无法训练
  • 文字类别无法参与计算
  • 无法做距离计算、梯度下降、树分裂

二、4 种最常用编码方法(通俗易懂版)

1. 标签编码 Label Encoding

把每个类别直接映射成一个整数。

  • 男→0,女→1
  • 红→0,绿→1,蓝→2

优点:简单、不升维度
缺点:会引入虚假顺序
模型可能误以为:蓝(2) > 绿(1) > 红(0)

适合:有序类别(低<中<高、小<中<大)


2. 独热编码 One-Hot Encoding(最常用)

每个类别单独一列,用 0/1 表示是否属于该类。

  • 红 → [1,0,0]
  • 绿 → [0,1,0]
  • 蓝 → [0,0,1]

优点:无顺序误解,最安全
缺点:类别多会维度爆炸

适合:无序、类别少的特征(性别、颜色、品种)


3. 目标编码 Target Encoding(高级上分技巧)

用该类别对应的目标均值来编码。
例如:颜色→购买率

  • 红色类别购买率 0.7 → 红色=0.7
  • 蓝色类别购买率 0.3 → 蓝色=0.3

优点:不降信息、不升维度
缺点:容易信息泄露/过拟合

适合:树模型(XGBoost、LightGBM、RF)


4. 二进制编码 Binary Encoding

先标签编码 → 再转二进制 → 按位展开
既保留信息,又不会维度爆炸。

适合:类别非常多的特征(城市、商品ID)


三、一张表看懂怎么选编码

编码方法无序类别有序类别类别很多优点缺点
标签编码❌不适合✅适合简单、快引入顺序
独热编码✅最适合❌不适合❌爆炸安全、通用维度爆炸
目标编码✅适合✅适合✅适合强表达力易过拟合
二进制编码✅适合✅适合✅极适合低维、高效可解释性差

四、最简单选择口诀

  • 有序类别(低中高)→ 标签编码
  • 无序、类别少 → 独热编码
  • 树模型、类别多 → 目标编码
  • 超多类别(ID类)→ 二进制/Embedding

五、完整可运行代码(含3种编码+对比+可视化)

直接复制运行,包含:数据集、标签编码、独热编码、目标编码、模型对比、PCA可视化。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

# ======================
# 1. 构造数据集
# ======================
np.random.seed(42)
n = 500

df = pd.DataFrame({
    "Color": np.random.choice(["Red","Green","Blue","Yellow"], n),
    "City": np.random.choice(["Beijing","Shanghai","Guangzhou","Shenzhen"], n),
    "Rating": np.random.choice(["Low","Medium","High"], n),
    "Age": np.random.randint(18,60,n),
    "Income": np.random.randint(3000,15000,n),
})

# 构造标签
df["Purchased"] = (
    ((df["Color"]=="Red") & (df["Rating"]=="High")) |
    ((df["City"].isin(["Beijing","Shanghai"])) & (df["Age"]<30))
).astype(int)

print("原始数据:")
print(df.head())

# ======================
# 2. 标签编码
# ======================
df["Color_LE"] = LabelEncoder().fit_transform(df["Color"])
df["City_LE"] = LabelEncoder().fit_transform(df["City"])
df["Rating_LE"] = df["Rating"].map({"Low":0,"Medium":1,"High":2})

# ======================
# 3. 独热编码
# ======================
df_onehot = pd.get_dummies(df[["Color","City","Rating"]])

# ======================
# 4. 目标编码
# ======================
color_mean = df.groupby("Color")["Purchased"].mean()
df["Color_TE"] = df["Color"].map(color_mean)

# ======================
# 5. 编码分布可视化
# ======================
plt.figure(figsize=(16,10))
plt.subplot(331)
sns.countplot(x=df["Color"])
plt.title("原始颜色分布")

plt.subplot(332)
sns.histplot(x=df["Color_LE"])
plt.title("标签编码")

plt.subplot(333)
sns.histplot(x=df["Color_TE"])
plt.title("目标编码")
plt.show()

# ======================
# 6. 模型效果对比
# ======================
X1 = df[["Color_LE","City_LE","Rating_LE","Age","Income"]]
X2 = pd.concat([df_onehot, df[["Age","Income"]]], axis=1)
X3 = df[["Color_TE","City_LE","Rating_LE","Age","Income"]]
y = df["Purchased"]

def test_acc(X):
    X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=42)
    m = RandomForestClassifier(random_state=42)
    m.fit(X_train,y_train)
    return accuracy_score(y_test,m.predict(X_test))

print("标签编码准确率:", test_acc(X1))
print("独热编码准确率:", test_acc(X2))
print("目标编码准确率:", test_acc(X3))

# ======================
# 7. PCA 空间分布对比
# ======================
def pca_plot(X, title):
    pca = PCA(2)
    x_pca = pca.fit_transform(X)
    plt.scatter(x_pca[:,0],x_pca[:,1],c=y,cmap="coolwarm")
    plt.title(title)
    plt.show()

pca_plot(X1, "Label Encoding")
pca_plot(X2, "One-Hot Encoding")
pca_plot(X3, "Target Encoding")

六、编码常见误区(面试/作业必看)

  1. 对无序特征用标签编码 → 模型学错规律
  2. 类别太多还用独热 → 维度爆炸、训练变慢
  3. 目标编码不做平滑 → 严重过拟合
  4. 先编码再划分数据集 → 信息泄露
  5. 树模型用独热 → 效果不如目标编码

七、总结(背诵版)

  1. 数据编码 = 文字类别 → 数字
  2. 有序 → 标签编码
  3. 无序少类 → 独热编码
  4. 树模型多类 → 目标编码
  5. 编码选对,模型效果直接起飞
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeepModel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值