6.4 特征降维(sklearn.decomposition)
Scikit-learn 特征降维教程:PCA, LDA, NMF, t-SNE 详解与实战
本教程详细讲解 Scikit-learn 中的特征降维方法,包括主成分分析(PCA)、线性判别分析(LDA)、非负矩阵分解(NMF)和 t-SNE,提供简单代码示例和维度选择评估技巧,适合初学者入门。
特征降维:Scikit-learn 中的高效工具
引言
特征降维是机器学习中一个重要的预处理步骤,它可以帮助我们减少数据的维度,从而降低计算复杂度、去除噪声或进行数据可视化。Scikit-learn 提供了多种降维算法,本教程将详细介绍最常用的方法,包括主成分分析(PCA)、线性判别分析(LDA)、非负矩阵分解(NMF)和 t-SNE,并讲解如何选择维度和评估效果。
主成分分析(PCA)
PCA 是一种无监督降维方法,其目标是最大化数据方差。通过找到数据中的主要方向(主成分),PCA 可以有效地压缩数据,适用于线性数据降维。
工作原理
PCA 通过线性变换将高维数据投影到低维子空间,使得投影后的数据方差最大化。它计算数据的协方差矩阵,然后进行特征值分解来选择最重要的成分。
代码示例
from sklearn.decomposition import PCA
import numpy as np
# 生成示例数据
X = np.random.rand(100, 10) # 100个样本,10个特征
# 初始化 PCA,降维到 2 维
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
print("降维后的数据形状:", X_pca.shape)
print("解释方差比例:", pca.explained_variance_ratio_)
优点和缺点
- 优点:简单、高效,适用于线性数据,能最大化数据方差。
- 缺点:可能丢失非线性信息,假设数据是线性相关的。
线性判别分析(LDA)
LDA 是一种有监督降维方法,主要用于分类问题。它最大化类间的分离,同时最小化类内的方差,利用标签信息指导降维。
与 PCA 的区别
PCA 是无监督的,关注整体方差;LDA 是有监督的,关注类别分离。LDA 通常在分类任务中表现更好,因为它利用了标签信息。
代码示例
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.datasets import load_iris
# 加载数据
data = load_iris()
X, y = data.data, data.target
# 初始化 LDA,降维到 2 维
lda = LinearDiscriminantAnalysis(n_components=2)
X_lda = lda.fit_transform(X, y)
print("降维后的数据形状:", X_lda.shape)
非负矩阵分解(NMF)
NMF 适用于所有特征为非负的数据,例如文本词频或图像像素值。它将数据分解为两个非负矩阵的乘积,常用于主题建模或特征提取。
应用场景
常用于文本分析(如主题发现)或图像处理(如面部识别),因为它能产生可解释的成分。
代码示例
from sklearn.decomposition import NMF
import numpy as np
# 示例数据,确保为非负
X_nmf = np.random.rand(100, 50) # 100个样本,50个非负特征
# 初始化 NMF,分解为 5 个成分
nmf = NMF(n_components=5, init='random', random_state=42)
W = nmf.fit_transform(X_nmf) # 基矩阵
H = nmf.components_ # 系数矩阵
print("分解后的基矩阵形状:", W.shape)
print("系数矩阵形状:", H.shape)
t-SNE(t-分布随机邻域嵌入)
t-SNE 是一种非线性降维方法,特别适合高维数据的可视化。它通过保持数据点之间的相似性来映射到低维空间,常用于探索性数据分析。
注意:t-SNE 在 sklearn.manifold 中
from sklearn.manifold import TSNE
import numpy as np
# 示例数据
X_tsne = np.random.rand(100, 30) # 100个样本,30个特征的高维数据
# 初始化 t-SNE,降维到 2 维用于可视化
tsne = TSNE(n_components=2, random_state=42)
X_tsne_reduced = tsne.fit_transform(X_tsne)
print("降维后的数据形状:", X_tsne_reduced.shape)
降维维度选择与效果评估
选择适当的降维维度至关重要,过度降维可能丢失信息,而降维不足则效果不佳。
如何选择维度
- 对于 PCA,使用
explained_variance_ratio_来确定保留多少方差。通常选择累积方差达到阈值(如 95%)的维度。pca = PCA() pca.fit(X) explained_variance = pca.explained_variance_ratio_ cumulative_variance = np.cumsum(explained_variance) n_components = np.argmax(cumulative_variance >= 0.95) + 1 print("推荐维度:", n_components) - 对于有监督方法如 LDA,维度通常受类别数限制,最多为类别数减一。
效果评估
- 对于分类任务:在降维后训练分类模型(如逻辑回归),比较降维前后的准确率或 AUC 分数。
- 对于可视化任务:观察降维后的散点图是否清晰分离类别或簇。
- 使用交叉验证或指标如重构误差(对于 NMF)来评估降维效果。
代码示例总结:完整实战
下面是一个完整示例,展示如何使用不同方法降维,并可视化效果。
# 导入必要库
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA, NMF
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
import numpy as np
# 加载数据
data = load_iris()
X, y = data.data, data.target
# PCA
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
# LDA
lda = LinearDiscriminantAnalysis(n_components=2)
X_lda = lda.fit_transform(X, y)
# NMF(确保数据非负)
X_nmf = X - X.min() # 简单处理为非负
nmf = NMF(n_components=2, init='random', random_state=42)
X_nmf_reduced = nmf.fit_transform(X_nmf)
# t-SNE
tsne = TSNE(n_components=2, random_state=42)
X_tsne = tsne.fit_transform(X)
# 可视化
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
axes[0, 0].scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap='viridis')
axes[0, 0].set_title('PCA')
axes[0, 0].set_xlabel('Component 1')
axes[0, 0].set_ylabel('Component 2')
axes[0, 1].scatter(X_lda[:, 0], X_lda[:, 1], c=y, cmap='viridis')
axes[0, 1].set_title('LDA')
axes[0, 1].set_xlabel('Component 1')
axes[0, 1].set_ylabel('Component 2')
axes[1, 0].scatter(X_nmf_reduced[:, 0], X_nmf_reduced[:, 1], c=y, cmap='viridis')
axes[1, 0].set_title('NMF')
axes[1, 0].set_xlabel('Component 1')
axes[1, 0].set_ylabel('Component 2')
axes[1, 1].scatter(X_tsne[:, 0], X_tsne[:, 1], c=y, cmap='viridis')
axes[1, 1].set_title('t-SNE')
axes[1, 1].set_xlabel('Component 1')
axes[1, 1].set_ylabel('Component 2')
plt.tight_layout()
plt.show()
结论
特征降维是机器学习中的关键步骤,Scikit-learn 提供了丰富的工具来实现。PCA 适合无监督线性降维,LDA 用于有监督分类任务,NMF 处理非负数据,t-SNE 则专注于高维数据可视化。选择方法时,需考虑数据特性、任务需求和评估指标。通过合理选择维度和评估效果,可以提升模型性能和可解释性。作为初学者,建议从 PCA 开始,逐步尝试其他方法,并在实际项目中应用这些技巧。