Scikit-learn 中文教程

第二部分:Scikit-learn 核心基础
第 3 章 Scikit-learn 核心设计与 API 体系
第 4 章 数据集模块与数据划分
第三部分:数据预处理与特征工程
第 5 章 数据预处理核心模块(sklearn.preprocessing)
第 6 章 特征工程:提取、选择与构建
第四部分:模型评估与验证
第 7 章 模型评估指标(按任务类型划分)
第 8 章 模型验证与超参数调优
第五部分:Scikit-learn 核心算法模块
第 9 章 有监督学习:分类算法
第 10 章 有监督学习:回归算法
第 11 章 无监督学习:聚类与密度算法
第 12 章 半监督学习与其他常用算法
第八部分:性能优化与问题解决
第 18 章 Scikit-learn 性能优化
第 19 章 Scikit-learn 常见问题与解决方案

6.4 特征降维(sklearn.decomposition)

Scikit-learn 特征降维教程:PCA, LDA, NMF, t-SNE 详解与实战

Scikit-learn 中文教程

本教程详细讲解 Scikit-learn 中的特征降维方法,包括主成分分析(PCA)、线性判别分析(LDA)、非负矩阵分解(NMF)和 t-SNE,提供简单代码示例和维度选择评估技巧,适合初学者入门。

推荐工具
PyCharm专业版开发必备

功能强大的Python IDE,提供智能代码补全、代码分析、调试和测试工具,提高Python开发效率。特别适合处理列表等数据结构的开发工作。

了解更多

特征降维: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 开始,逐步尝试其他方法,并在实际项目中应用这些技巧。

开发工具推荐
Python开发者工具包

包含虚拟环境管理、代码格式化、依赖管理、测试框架等Python开发全流程工具,提高开发效率。特别适合处理复杂数据结构和算法。

获取工具包