机器学习数据预处理:数据转换
机器学习数据预处理:数据转换(超通俗完整版)
数据转换是把原始数据“改造”成模型能轻松学习的格式,是建模前必做的核心步骤,几乎所有数据分析、机器学习项目都会用到。
一、什么是数据转换?
一句话理解:
把不规整、难处理的数据,变成规整、好计算、符合模型要求的数据。
比如:
- 数值差距太大(收入 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′=xmax−xminxi−xmin
适用场景:
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 主成分分析(降维转换)
作用:把高维特征线性投影,保留主要信息,降低维度。
步骤:
- 计算协方差矩阵
- 求特征值与特征向量
- 保留前 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()
五、数据转换的优缺点
优点
- 让模型更容易学习,大幅提升精度
- 加速收敛,梯度下降更快更稳
- 削弱异常值,提高鲁棒性
- 文字转数字,让分类特征可用
- 降维减噪,节省计算资源
缺点
- 可能丢失原始语义(尤其 PCA)
- 转换不当会破坏数据规律
- 增加预处理代码与调试成本
- 对树模型(决策树、XGBoost)收益不大
六、什么时候必须做数据转换?
- 用线性模型、SVM、神经网络、KNN → 必须标准化/归一化
- 数据严重偏态、有极端大值 → 对数转换
- 特征是文字类别 → One-Hot / 目标编码
- 特征维度太高、冗余多 → PCA
- 想把数字变成业务等级 → 分箱
七、总结(面试/笔记万能版)
- 数据转换 = 把原始数据改成模型友好格式
- 7 大核心方法:标准化、归一化、对数、Box-Cox、分箱、One-Hot、PCA
- 距离/线性模型必做缩放,树模型可不做
- 偏态数据用对数,分类数据用One-Hot,高维数据用PCA
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)