数据预处理与特征工程

数据预处理

数据的无量纲化

数据无量纲化(Normalization/Standardization)是数据预处理中的重要步骤,目的是消除不同特征之间量纲差异对模型的影响。

为什么需要无量纲化?

  1. 量纲差异问题:不同特征可能有不同的量纲和数值范围

    • 年龄:20-80
    • 收入:20,000-200,000
    • 身高:150-200cm
  2. 算法敏感性:某些算法对特征的尺度敏感

    • KNN、SVM、神经网络
    • 基于梯度的优化算法

常用的无量纲化方法

1. 标准化(Z-score Standardization)

将数据转换为均值为0,标准差为1的分布:

$$X_{new} = \frac{X - \mu}{\sigma}$$

其中:

  • $\mu$ 是均值
  • $\sigma$ 是标准差

标准化公式的详细推导

目标:将原始数据 $X$ 转换为均值为0,标准差为1的新数据 $X_{new}$

第一步:推导均值为0的条件

设原始数据集为 ${x_1, x_2, …, x_n}$,转换公式为:

$$x_{new,i} = \frac{x_i - \mu}{\sigma}$$

计算转换后数据的均值:

$$E[X_{new}] = E\left[\frac{X - \mu}{\sigma}\right] = \frac{1}{\sigma}E[X - \mu] = \frac{1}{\sigma}(E[X] - \mu) = \frac{\mu - \mu}{\sigma} = 0$$
第二步:推导标准差为1的条件

计算转换后数据的方差:

$$Var[X_{new}] = Var\left[\frac{X - \mu}{\sigma}\right] = \frac{1}{\sigma^2}Var[X - \mu] = \frac{1}{\sigma^2}Var[X] = \frac{\sigma^2}{\sigma^2} = 1$$

因此标准差为:

$$\sigma_{new} = \sqrt{Var[X_{new}]} = \sqrt{1} = 1$$
第三步:具体计算步骤

对于数据集 ${x_1, x_2, …, x_n}$:

  1. 计算均值

    $$\mu = \frac{1}{n}\sum_{i=1}^{n} x_i$$
  2. 计算标准差

    $$\sigma = \sqrt{\frac{1}{n}\sum_{i=1}^{n} (x_i - \mu)^2}$$

    或样本标准差:

    $$s = \sqrt{\frac{1}{n-1}\sum_{i=1}^{n} (x_i - \bar{x})^2}$$
  3. 标准化转换

    $$x_{new,i} = \frac{x_i - \mu}{\sigma} \quad \text{或} \quad x_{new,i} = \frac{x_i - \bar{x}}{s}$$
第四步:数学验证示例

假设有数据集:$X = {2, 4, 6, 8}$

  1. 计算均值:$\mu = \frac{2+4+6+8}{4} = 5$
  2. 计算方差:$\sigma^2 = \frac{(2-5)^2+(4-5)^2+(6-5)^2+(8-5)^2}{4} = \frac{9+1+1+9}{4} = 5$
  3. 计算标准差:$\sigma = \sqrt{5} \approx 2.236$
  4. 标准化:
    • $x_{new,1} = \frac{2-5}{2.236} = -1.342$
    • $x_{new,2} = \frac{4-5}{2.236} = -0.447$
    • $x_{new,3} = \frac{6-5}{2.236} = 0.447$
    • $x_{new,4} = \frac{8-5}{2.236} = 1.342$

验证结果:

  • 新均值:$\frac{-1.342+(-0.447)+0.447+1.342}{4} = 0$
  • 新标准差:$\sqrt{\frac{(-1.342)^2+(-0.447)^2+0.447^2+1.342^2}{4}} = 1$
数学性质总结
  1. 线性变换:标准化是线性变换,保持数据间的相对关系
  2. 分布形状不变:只改变位置和尺度,不改变分布形状
  3. 可逆性:可以通过逆变换恢复原始数据:$X = X_{new} \cdot \sigma + \mu$
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from sklearn.preprocessing import StandardScaler

# 创建标准化器
scaler = StandardScaler()

# 拟合并转换数据
X_scaled = scaler.fit_transform(X)

# 或者分步进行
scaler.fit(X_train)
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)

适用场景

  • 数据近似正态分布
  • 需要保持数据分布形状
  • 大多数机器学习算法
2. 归一化(Min-Max Normalization)

将数据缩放到指定范围(通常是[0,1]):

$$X_{new} = \frac{X - X_{min}}{X_{max} - X_{min}}$$
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from sklearn.preprocessing import MinMaxScaler

# 创建归一化器
scaler = MinMaxScaler(feature_range=(0, 1))

# 拟合并转换数据
X_normalized = scaler.fit_transform(X)

# 自定义范围
scaler = MinMaxScaler(feature_range=(-1, 1))
X_custom = scaler.fit_transform(X)

适用场景

  • 需要将数据压缩到特定范围
  • 数据分布相对均匀
  • 神经网络的输入层
3. 鲁棒缩放(Robust Scaling)

使用中位数和四分位距进行缩放,对异常值不敏感:

$$X_{new} = \frac{X - median(X)}{IQR(X)}$$

其中IQR是四分位距(Q3 - Q1)

1
2
3
4
5
6
7
from sklearn.preprocessing import RobustScaler

# 创建鲁棒缩放器
scaler = RobustScaler()

# 拟合并转换数据
X_robust = scaler.fit_transform(X)

适用场景

  • 数据包含异常值
  • 数据分布不对称
  • 需要减少异常值影响
4. 单位向量缩放(Unit Vector Scaling)

将每个样本缩放为单位向量:

$$X_{new} = \frac{X}{||X||_2}$$
1
2
3
4
5
6
7
from sklearn.preprocessing import normalize

# L2范数归一化
X_unit = normalize(X, norm='l2')

# L1范数归一化
X_l1 = normalize(X, norm='l1')

适用场景

  • 文本分析(TF-IDF)
  • 需要保持方向性的场景
  • 稀疏数据

实际应用示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler, MinMaxScaler
import matplotlib.pyplot as plt

# 创建示例数据
np.random.seed(42)
data = pd.DataFrame({
    'age': np.random.normal(35, 10, 1000),
    'income': np.random.normal(50000, 15000, 1000),
    'score': np.random.uniform(0, 100, 1000)
})

print("原始数据统计:")
print(data.describe())

# 标准化
scaler_std = StandardScaler()
data_std = pd.DataFrame(
    scaler_std.fit_transform(data), 
    columns=data.columns
)

# 归一化
scaler_norm = MinMaxScaler()
data_norm = pd.DataFrame(
    scaler_norm.fit_transform(data), 
    columns=data.columns
)

print("\n标准化后数据统计:")
print(data_std.describe())

print("\n归一化后数据统计:")
print(data_norm.describe())

注意事项

  1. 训练测试集一致性:使用训练集的参数缩放测试集
  2. 特征选择顺序:通常在特征选择之前进行
  3. 算法选择:根据数据分布和算法特性选择合适的方法
  4. 异常值处理:在无量纲化前可能需要处理异常值

方法对比总结

方法 优点 缺点 适用场景
标准化 保持分布形状,适用性广 对异常值敏感 正态分布数据
归一化 结果在固定范围内 对异常值敏感 分布均匀的数据
鲁棒缩放 对异常值不敏感 可能不在固定范围内 包含异常值的数据
单位向量 保持方向性 丢失量级信息 稀疏数据,文本数据

数据降维

数据降维(Dimensionality Reduction)是将高维数据映射到低维空间的过程,目的是在尽量保留原始信息的前提下,减少特征数量。

为什么需要降维?

  1. 缓解维度灾难:高维空间中数据稀疏,距离计算失效,模型易过拟合。
  2. 提升计算效率:减少特征数量,降低存储和计算成本。
  3. 可视化:便于将高维数据投影到2D/3D空间进行可视化。
  4. 去除冗余特征:消除特征间的相关性,提高模型泛化能力。

常见降维方法

1. 主成分分析(PCA)

PCA是一种经典的线性降维方法,通过正交变换将原始特征映射到一组新的无关主成分上,按方差大小排序,保留主要信息。

PCA数学推导简要:

  1. 中心化数据: $$X_{centered} = X - \bar{X}$$
  2. 计算协方差矩阵: $$C = \frac{1}{n} X_{centered}^T X_{centered}$$
  3. 特征分解:对协方差矩阵$C$做特征值分解,得到特征值$\lambda_i$和特征向量$u_i$。
  4. 选取主成分:按特征值从大到小排序,选取前$k$个特征向量组成投影矩阵$U_k$。
  5. 数据投影: $$Z = X_{centered} U_k$$

PCA性质:

  • 主成分两两正交
  • 最大化投影后数据的方差
  • 可逆性:可近似重构原始数据

PCA Python示例:

1
2
3
4
5
6
7
8
from sklearn.decomposition import PCA
import numpy as np

X = np.random.rand(100, 5)  # 100个样本,5个特征
pca = PCA(n_components=2)
X_reduced = pca.fit_transform(X)
print("降维后形状:", X_reduced.shape)
print("主成分方差贡献率:", pca.explained_variance_ratio_)
2. 线性判别分析(LDA)

LDA是一种有监督降维方法,最大化类间距离、最小化类内距离,常用于分类前的特征压缩。

3. t-SNE/UMAP

t-SNE和UMAP是常用的非线性降维方法,适合高维数据的可视化。

  • t-SNE:保持局部结构,适合可视化聚类结构
  • UMAP:速度快,保持全局和局部结构

降维的应用场景

  • 数据可视化(如MNIST手写数字集)
  • 特征冗余、共线性严重的数据
  • 图像、文本、基因等高维数据分析

注意事项

  1. 降维前建议先做标准化/归一化处理
  2. PCA等线性方法不适合强非线性数据
  3. 降维后特征可解释性降低
  4. 选择合适的降维维数,避免信息损失
最后更新于 2025-06-19 14:46
使用 Hugo 构建
主题 StackJimmy 设计