趋近智
随着您生成更多特征,也许是通过交互项或多项式扩展,您可能会发现输入变量的数量非常大。虽然有时有益,但具有许多维度(特征)的数据集可能带来挑战。训练模型可能变得计算成本高昂,并且由于“维度灾难”而增加了过拟合 (overfitting)的风险,这是一种在高维空间 (high-dimensional space)中数据变得稀疏,使模型难以泛化的现象。此外,拥有数百或数千个特征时,解释模型或可视化数据变得困难。
降维技术旨在减少输入变量的数量,同时尽可能保留有意义的信息。主成分分析(PCA)是为此目的最广泛使用的无监督技术之一。它不仅仅选择原始特征的一个子集;相反,它构建了一个新的、更小的特征集,称为主成分,这些成分是原始特征的线性组合。
PCA的核心思想是找出数据中方差最大的方向。想象您的数据点绘制在多维空间中。PCA识别出数据点最分散的轴,这是第一个主成分(PC1)。然后它找到与第一个轴正交(垂直)的下一个轴,该轴捕获了剩余的最大方差。这是第二个主成分(PC2),以此类推。
每个主成分是原始特征的线性组合:
其中 是第 个主成分, 是第 个原始特征,而 是定义每个原始特征对主成分贡献的载荷得分或权重 (weight)。
这些成分有两个重要特性:
从数学角度看,PCA涉及计算数据协方差矩阵的特征向量 (vector)和特征值(或者对数据矩阵执行奇异值分解,SVD)。特征向量给出主成分的方向,相应的特征值表示沿这些方向的方差大小。
在应用PCA之前,几乎总是需要标准化您的数据,这意味着将每个特征缩放到具有零均值和单位方差。为什么?PCA查找最大方差的方向。如果特征具有非常不同的尺度(例如,一个特征范围从0到1,另一个从10,000到1,000,000),则尺度较大的特征将固有地具有更大的方差,并将主导主成分,无论其在捕获数据结构中的实际重要性如何。标准化确保所有特征对分析的贡献相同。
我们可以使用scikit-learn中的StandardScaler:
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
import numpy as np
# 假设 'X' 是您的 pandas DataFrame 或 NumPy 特征数组
# 示例数据(请替换为您的实际数据)
data = {'feature1': np.random.rand(100) * 10,
'feature2': np.random.rand(100) * 1000,
'feature3': np.random.rand(100) - 50}
X = pd.DataFrame(data)
print("原始数据样本:")
print(X.head())
# 1. 标准化数据
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
print("\n标准化数据样本(均值接近0,标准差接近1):")
print(pd.DataFrame(X_scaled, columns=X.columns).head())
数据缩放后,使用scikit-learn的PCA类应用PCA非常直接。您通常需要决定保留多少个主成分。
# 2. 应用PCA
# 让我们首先拟合PCA,不指定组件数量
# 以查看每个组件解释了多少方差。
pca_full = PCA()
pca_full.fit(X_scaled)
# 解释方差比例:每个组件解释的方差百分比
explained_variance = pca_full.explained_variance_ratio_
print("\n每个组件的解释方差比例:")
print(explained_variance)
# 累积解释方差
cumulative_variance = np.cumsum(explained_variance)
print("\n累积解释方差:")
print(cumulative_variance)
决定保留多少个组件()的常用方法是检查累积解释方差。您可以设置一个阈值,例如保留足够的组件来解释总方差的95%或99%。绘制累积解释方差有助于可视化这种权衡。
随着主成分数量的增加,显示累积解释方差的图。一种常见的方法是选择曲线开始趋于平稳或达到所需阈值(例如95%)时的组件数量。
根据图表或累积方差数组,您可以选择组件数量。例如,如果保留2个组件可以解释95%的方差,您可能会认为这已足够。
# 3. 选择组件数量(例如,目标是 >= 95% 方差)
n_components_chosen = 2 # 根据示例输出或图表
# 使用选定的组件数量再次拟合PCA
pca = PCA(n_components=n_components_chosen)
pca.fit(X_scaled)
# 4. 将数据转换到低维空间
X_pca = pca.transform(X_scaled)
print(f"\n原始数据形状:{X_scaled.shape}")
print(f"转换后数据形状(含 {n_components_chosen} 个组件):{X_pca.shape}")
print("\n转换后数据(前5行):")
print(X_pca[:5, :])
生成的 X_pca 数组现在包含由前两个主成分表示的数据。这些新特征捕获了原始数据集中最重要的方差,但处于较低维空间。您现在可以将 X_pca 用作机器学习 (machine learning)模型的输入。
PCA通常用于将数据降至2或3维以进行可视化。让我们想象将PCA应用于Iris数据集(有4个特征)并绘制前两个主成分。
# 使用Iris数据集的示例(假设已加载)
# from sklearn.datasets import load_iris
# iris = load_iris()
# X_iris = iris.data
# y_iris = iris.target
# target_names = iris.target_names
# scaler_iris = StandardScaler()
# X_iris_scaled = scaler_iris.fit_transform(X_iris)
# pca_iris = PCA(n_components=2)
# X_iris_pca = pca_iris.fit_transform(X_iris_scaled)
# 现在,想象绘制 X_iris_pca[:, 0] 与 X_iris_pca[:, 1]
# 按 y_iris 颜色区分。
# 用于图表说明的虚拟数据(请替换为实际PCA结果)
import plotly.graph_objects as go
dummy_pca_data = np.random.rand(150, 2) * np.array([[5, 2]]) + np.array([[-2, -1]])
dummy_labels = np.random.randint(0, 3, 150)
colors = ['#1f77b4', '#ff7f0e', '#2ca02c'] # 示例颜色
fig = go.Figure()
for i, color in enumerate(colors):
idx = dummy_labels == i
fig.add_trace(go.Scatter(
x=dummy_pca_data[idx, 0], y=dummy_pca_data[idx, 1],
mode='markers',
marker=dict(color=color, size=8, opacity=0.7),
name=f'类别 {i}' # 如果可用,请替换为实际的 target_names
))
fig.update_layout(
title="投影到前两个主成分的数据(示例)",
xaxis_title="主成分 1",
yaxis_title="主成分 2",
template="plotly_white",
legend_title_text='类别'
)
# 为了以兼容的格式显示图表:
# print(fig.to_json())
示例散点图,显示投影到前两个主成分的数据。通常,这些成分可以有效地分离不同的类别或显示数据中的聚类,使它们即使在为建模保留更多成分时,也对可视化很有用。
尽管功能强大,但PCA并非万能:
PCA是数据科学家工具箱中用于降维的一种基本方法。它有助于管理高维数据,可能减少噪声,降低计算成本,并辅助可视化,构成了为高效机器学习 (machine learning)建模准备特征的重要步骤。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造