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

数据转换是把原始数据“改造”成模型能轻松学习的格式,是建模前必做的核心步骤,几乎所有数据分析、机器学习项目都会用到。


一、什么是数据转换?

一句话理解:
把不规整、难处理的数据,变成规整、好计算、符合模型要求的数据。

比如:

  • 数值差距太大(收入 1000~1000 万)
  • 是文字而不是数字(男/女、好/中/差)
  • 分布歪歪扭扭(严重右偏)
  • 连续值不想用具体数字,只想分等级

都要靠数据转换来解决。


二、7 种最常用的数据转换方法(超详细)

1. 标准化(Z-Score)

作用:把数据变成 均值=0,标准差=1 的标准分布。
公式
zi=xi−μσz_i = \frac{x_i - \mu}{\sigma}zi=σxiμ

  • μ:均值
  • σ:标准差

适用场景
线性回归、逻辑回归、SVM、PCA、神经网络等对尺度敏感的模型。

优点

  • 对异常值相对稳定
  • 让特征权重公平,不被大数带偏

2. 归一化(Min-Max Scaling)

作用:把数据缩到 [0,1][-1,1] 区间。
公式
xi′=xi−xminxmax−xminx_i' = \frac{x_i - x_{min}}{x_{max} - x_{min}}xi=xmaxxminxixmin

适用场景
KNN、K-Means、神经网络、图像像素(0-255 → 0-1)。

优点

  • 范围固定,直观
  • 提升距离计算的稳定性

3. 对数转换(Log Transform)

作用:压缩大数差距,把右偏分布变对称。
公式
x′=log⁡(1+x)x' = \log(1+x)x=log(1+x)

适用场景
房价、收入、销量、金额等跨度极大的数据。

优点

  • 削弱极端值影响
  • 让线性模型更容易拟合

4. Box-Cox 变换

作用:比对数更通用,把任意分布转成近似正态分布
公式
x′={xλ−1λλ≠0log⁡(x)λ=0 x'= \begin{cases} \frac{x^\lambda -1}{\lambda} & \lambda \neq 0 \\ \log(x) & \lambda = 0 \end{cases} x={λxλ1log(x)λ=0λ=0

适用场景
统计建模、需要严格正态分布的任务。


5. 分箱(Binning)

作用:把连续数字 → 离散类别
两种常用方式:

  • 等宽分箱:按区间宽度均分
  • 等频分箱:按样本数量均分

例子
年龄 22、35、58 → 青年、中年、老年

适用场景
决策树、业务规则建模、提升鲁棒性。


6. One-Hot 编码(独热编码)

作用:把分类文字 → 数字向量,让模型能看懂。
例子
颜色:红、蓝、绿
→ 红(1,0,0)、蓝(0,1,0)、绿(0,0,1)

优点

  • 不引入虚假大小关系(如 红=1,蓝=2 这种错误)

缺点
类别多的时候会维度爆炸


7. PCA 主成分分析(降维转换)

作用:把高维特征线性投影,保留主要信息,降低维度。
步骤

  1. 计算协方差矩阵
  2. 求特征值与特征向量
  3. 保留前 k 个主成分

适用场景
特征冗余高、维度太高、需要加速训练时。


三、7 种方法一张表速查

方法 核心作用 适用场景
标准化 均值0,标准差1 线性模型、神经网络、SVM
归一化 缩到 [0,1] KNN、聚类、图像
对数转换 修正偏态、压缩大数 房价、收入、金额
Box-Cox 转为近似正态 统计建模
分箱 连续→离散 决策树、业务解释
One-Hot 分类→数值向量 所有不支持类别输入的模型
PCA 降维、去冗余 高维特征、加速训练

四、完整实战代码(房价预测数据集)

包含:对数转换、标准化、分箱、One-Hot、PCA、建模评估,直接复制可运行

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

from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Ridge
from sklearn.metrics import mean_squared_error
from scipy.stats import skew

# ======================
# 1. 加载数据
# ======================
data = pd.read_csv('./train.csv')  # 从Kaggle下载House Prices数据
print(data.shape)

# ======================
# 2. 查看偏态数据(需要对数转换)
# ======================
numeric_feats = data.select_dtypes(include=[np.number]).columns
skewed_feats = data[numeric_feats].apply(lambda x: skew(x.dropna()))
skewed_feats = skewed_feats[skewed_feats > 1].sort_values(ascending=False)
print("高偏度特征:")
print(skewed_feats[:10])

# ======================
# 3. 对数转换
# ======================
data_log = data.copy()
for feat in skewed_feats.index:
    data_log[feat] = np.log1p(data_log[feat])

# ======================
# 4. 标准化
# ======================
data_log[numeric_feats] = data_log[numeric_feats].fillna(data_log[numeric_feats].median())
scaler = StandardScaler()
scaled_vals = scaler.fit_transform(data_log[numeric_feats])
scaled_df = pd.DataFrame(scaled_vals, columns=numeric_feats)

# ======================
# 5. 分箱(房龄分箱)
# ======================
data_log['YearBuiltBin'] = pd.cut(
    data_log['YearBuilt'],
    bins=[1870,1900,1950,2000,2010],
    labels=['VeryOld','Old','Modern','New']
)

# ======================
# 6. One-Hot 编码
# ======================
cat_cols = ['YearBuiltBin','Neighborhood','HouseStyle']
for c in cat_cols:
    data_log[c] = data_log[c].fillna(data_log[c].mode()[0])

onehot_df = pd.get_dummies(data_log[cat_cols], drop_first=True)

# 合并数值 + 编码特征
final_df = pd.concat([scaled_df, onehot_df], axis=1)

# ======================
# 7. PCA 降维
# ======================
pca = PCA(n_components=0.95)
X_pca = pca.fit_transform(final_df)
print("原维度:", final_df.shape[1])
print("PCA后维度:", X_pca.shape[1])

# ======================
# 8. 建模预测(房价回归)
# ======================
y = np.log1p(data_log['SalePrice'])
X_train, X_test, y_train, y_test = train_test_split(
    X_pca, y, test_size=0.2, random_state=42
)

model = Ridge(alpha=1.0)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

rmse = np.sqrt(mean_squared_error(y_test, y_pred))
print("RMSE(对数空间):", round(rmse,4))

# ======================
# 9. 预测结果可视化
# ======================
plt.figure(figsize=(8,6))
plt.scatter(np.expm1(y_test), np.expm1(y_pred), alpha=0.7, color='#ff6666')
plt.plot([0,800000],[0,800000],'k--')
plt.title('真实房价 vs 预测房价')
plt.xlabel('真实价格')
plt.ylabel('预测价格')
plt.grid()
plt.show()

五、数据转换的优缺点

优点

  1. 让模型更容易学习,大幅提升精度
  2. 加速收敛,梯度下降更快更稳
  3. 削弱异常值,提高鲁棒性
  4. 文字转数字,让分类特征可用
  5. 降维减噪,节省计算资源

缺点

  1. 可能丢失原始语义(尤其 PCA)
  2. 转换不当会破坏数据规律
  3. 增加预处理代码与调试成本
  4. 对树模型(决策树、XGBoost)收益不大

六、什么时候必须做数据转换?

  • 线性模型、SVM、神经网络、KNN → 必须标准化/归一化
  • 数据严重偏态、有极端大值 → 对数转换
  • 特征是文字类别 → One-Hot / 目标编码
  • 特征维度太高、冗余多 → PCA
  • 想把数字变成业务等级 → 分箱

七、总结(面试/笔记万能版)

  1. 数据转换 = 把原始数据改成模型友好格式
  2. 7 大核心方法:标准化、归一化、对数、Box-Cox、分箱、One-Hot、PCA
  3. 距离/线性模型必做缩放,树模型可不做
  4. 偏态数据用对数,分类数据用One-Hot,高维数据用PCA
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐