Sklearn 降维与流形学习
sklearn.decomposition 和 sklearn.manifold 提供 PCA、SVD、NMF、t-SNE 等降维工具。
🎯 矩阵分解
1. PCA --- 主成分分析 ⭐
python
from sklearn.decomposition import PCA
model = PCA(
n_components=None, # 保留的成分数
# int: 成分数
# float (0~1): 保留的方差比例
# 'mle': 自动选择(Minka's MLE)
# None: 保留所有 min(n_samples, n_features)
copy=True,
whiten=False, # 白化处理
svd_solver='auto', # 'auto','full','arpack','randomized'
tol=0.0, # arpack 的容差
iterated_power='auto', # randomized 的幂迭代次数
n_oversamples=10, # randomized 的过采样数
random_state=None,
)
model.fit(X)
# 核心属性
print(model.components_) # 主成分(特征向量)(n_components, n_features)
print(model.explained_variance_) # 各成分的方差 ⭐
print(model.explained_variance_ratio_) # 各成分的方差比例 ⭐
print(model.singular_values_) # 奇异值
print(model.mean_) # 训练数据的均值
print(model.n_components_) # 实际成分数
print(model.n_features_) # 特征数
print(model.n_samples_) # 样本数
print(model.noise_variance_) # 噪声方差
# 变换
X_pca = model.transform(X)
X_pca = model.fit_transform(X)
# 逆变换(近似重建)
X_reconstructed = model.inverse_transform(X_pca)
# 增量 PCA(大数据集)
pca.partial_fit(X_batch) # 不适用于普通 PCA
2. IncrementalPCA --- 增量 PCA
python
from sklearn.decomposition import IncrementalPCA
model = IncrementalPCA(
n_components=None,
whiten=False,
copy=True,
batch_size=None # 每批样本数
)
# 分批拟合
for batch in np.array_split(X, 10):
model.partial_fit(batch)
X_pca = model.transform(X)
3. KernelPCA --- 核 PCA
python
from sklearn.decomposition import KernelPCA
model = KernelPCA(
n_components=None,
kernel='linear', # 'linear','poly','rbf','sigmoid','cosine','precomputed'
gamma=None, # rbf/poly/sigmoid 的参数
degree=3, # poly 次数
coef0=1, # poly/sigmoid 的独立项
kernel_params=None,
alpha=1.0, # 学习到的逆变换正则化参数
fit_inverse_transform=False,
eigen_solver='auto', # 'auto','dense','arpack','randomized'
tol=0,
max_iter=None,
iterated_power='auto',
remove_zero_eig=False,
random_state=None,
copy_X=True,
n_jobs=None
)
model.fit(X)
X_kpca = model.transform(X)
# 逆变换(需 fit_inverse_transform=True)
X_reconstructed = model.inverse_transform(X_kpca)
4. SparsePCA / MiniBatchSparsePCA --- 稀疏 PCA
python
from sklearn.decomposition import SparsePCA, MiniBatchSparsePCA
model = SparsePCA(
n_components=None,
alpha=1, # 稀疏控制参数
ridge_alpha=0.01, # 岭惩罚
max_iter=1000,
tol=1e-8,
method='lars', # 'lars' 或 'cd'(坐标下降)
n_jobs=None,
random_state=None
)
model.fit(X)
print(model.components_)
# MiniBatch 版本(大数据)
model = MiniBatchSparsePCA(
n_components=None, alpha=1,
batch_size=100, random_state=42
)
model.fit(X)
5. TruncatedSVD --- 截断 SVD ⭐
不中心化数据,直接进行 SVD 分解(适合稀疏矩阵,如 TF-IDF)。
python
from sklearn.decomposition import TruncatedSVD
model = TruncatedSVD(
n_components=2,
algorithm='randomized', # 'arpack' 或 'randomized'
n_iter=5, # 幂迭代次数(randomized)
n_oversamples=10,
random_state=None,
tol=0.0
)
model.fit(X)
print(model.components_)
print(model.explained_variance_)
print(model.explained_variance_ratio_)
print(model.singular_values_)
X_svd = model.transform(X)
X_approx = model.inverse_transform(X_svd)
6. NMF --- 非负矩阵分解
python
from sklearn.decomposition import NMF
model = NMF(
n_components=None,
init=None, # 'random','nndsvd','nndsvda','nndsvdar','custom'
solver='cd', # 'cd'(坐标下降)或 'mu'(乘法更新)
beta_loss='frobenius', # 'frobenius' 或 'kullback-leibler' 或 float
tol=1e-4,
max_iter=200,
random_state=None,
alpha_W=0.0, # W 正则化
alpha_H='same', # H 正则化('same' 或 float)
l1_ratio=0.0, # L1/L2 比率(0=仅L2, 1=仅L1)
shuffle=False, # 按样本划分时的打乱顺序
verbose=0
)
model.fit(X)
print(model.components_) # H 矩阵 (n_components, n_features)
print(model.n_components_)
print(model.reconstruction_err_)
print(model.n_iter_)
# W 矩阵(样本在成分上的表示)
W = model.transform(X)
X_approx = model.inverse_transform(W)
7. DictionaryLearning --- 字典学习
python
from sklearn.decomposition import DictionaryLearning
model = DictionaryLearning(
n_components=None,
alpha=1, # 稀疏控制
max_iter=1000,
tol=1e-8,
fit_algorithm='lars', # 'lars' 或 'cd'
transform_algorithm='omp', # 'lars','lasso_lars','lasso_cd','omp','threshold'
transform_n_nonzero_coefs=None,
transform_alpha=None,
n_jobs=None,
code_init=None,
dict_init=None,
callback=None,
verbose=False,
random_state=None
)
model.fit(X)
print(model.components_) # 字典
8. FactorAnalysis --- 因子分析
python
from sklearn.decomposition import FactorAnalysis
model = FactorAnalysis(
n_components=None,
tol=1e-2,
copy=True,
max_iter=1000,
noise_variance_init=None, # 噪声方差初始值
svd_method='randomized',
iterated_power=3,
rotation='varimax', # None 或 'varimax'(正交旋转)
random_state=0
)
model.fit(X)
X_transformed = model.transform(X)
print(model.components_)
print(model.noise_variance_)
print(model.loglike_)
9. FastICA --- 独立成分分析(ICA)
python
from sklearn.decomposition import FastICA
model = FastICA(
n_components=None,
algorithm='parallel', # 'parallel' 或 'deflation'
whiten='unit-variance', # 'unit-variance' 或 True/False
fun='logcosh', # 'logcosh','exp','cube'
fun_args=None, # 函数参数
max_iter=200,
tol=1e-4,
w_init=None,
whiten_solver='svd',
random_state=None
)
model.fit(X)
print(model.components_) # 独立成分
print(model.mixing_) # 混合矩阵
print(model.mean_) # 各特征的均值
print(model.n_iter_) # 迭代次数
X_ica = model.transform(X)
X_reconstructed = model.inverse_transform(X_ica)
10. LatentDirichletAllocation --- LDA 主题模型
python
from sklearn.decomposition import LatentDirichletAllocation
model = LatentDirichletAllocation(
n_components=10, # 主题数
doc_topic_prior=None, # Dirichlet 先验 α
topic_word_prior=None, # Dirichlet 先验 β
learning_method='batch', # 'batch' 或 'online'
learning_decay=0.7, # online 学习率衰减
learning_offset=10.0,
max_iter=10,
batch_size=128,
evaluate_every=-1, # 每多少次迭代评估困惑度
total_samples=1e6,
perp_tol=1e-1,
mean_change_tol=1e-3,
max_doc_update_iter=100,
n_jobs=None,
verbose=0,
random_state=None
)
model.fit(X)
print(model.components_) # 主题-词矩阵 (n_topics, n_words)
print(model.n_batch_iter_) # batch 方法的迭代次数
print(model.bound_) # 变分下界
# 文档-主题分布
doc_topics = model.transform(X) # (n_docs, n_topics)
🌀 流形学习(Manifold Learning)
1. TSNE --- t-SNE ⭐
python
from sklearn.manifold import TSNE
model = TSNE(
n_components=2, # 嵌入维度(通常 2 或 3)
perplexity=30.0, # 有效邻居数 (5-50)
early_exaggeration=12.0, # 早期放大因子
learning_rate='auto', # 学习率 (10-1000),'auto'=max(N/12, 200)
n_iter=1000, # 迭代优化次数
n_iter_without_progress=300, # 无改善则提前停止
min_grad_norm=1e-7,
metric='euclidean', # 距离度量
metric_params=None,
init='pca', # 'random','pca' 或 ndarray
verbose=0,
random_state=None,
method='barnes_hut', # 'barnes_hut' 或 'exact'
angle=0.5, # barnes_hut 的角度-速度权衡
n_jobs=None,
perplexity_max_iter=100 # 1.3+: perplexity 校准最大迭代
)
X_embedded = model.fit_transform(X)
# 关键属性
print(model.n_iter_) # 实际迭代数
print(model.kl_divergence_) # 最终的 KL 散度
print(model.embedding_) # 嵌入坐标
print(model.learning_rate_) # 实际使用的学习率
调参指导:
python
# perplexity: 5-50,数据集越大值越大
# learning_rate: 10-1000
# n_iter: 至少 250,通常 1000-5000
# 建议多次运行取最佳结果
# 大规模数据集(>5000 样本)先 PCA 降维再 t-SNE
from sklearn.pipeline import make_pipeline
from sklearn.decomposition import PCA
pipeline = make_pipeline(
PCA(n_components=50, random_state=42),
TSNE(n_components=2, random_state=42)
)
X_embedded = pipeline.fit_transform(X)
2. MDS --- 多维缩放
python
from sklearn.manifold import MDS
model = MDS(
n_components=2,
metric=True, # True=度量 MDS, False=非度量 MDS
n_init=4, # SMACOF 运行次数
max_iter=300,
eps=1e-3, # 收敛容差
n_jobs=None,
random_state=None,
dissimilarity='euclidean', # 'euclidean' 或 'precomputed'
normalized_stress='auto' # 是否返回标准化应力
)
X_embedded = model.fit_transform(X)
print(model.stress_) # 应力值(越低越好)
print(model.n_iter_)
print(model.embedding_)
3. Isomap --- 等度量映射
python
from sklearn.manifold import Isomap
model = Isomap(
n_neighbors=5, # 邻居数
n_components=2,
eigen_solver='auto', # 'auto','arpack','dense'
tol=0,
max_iter=None,
path_method='auto', # 'auto','FW'(Floyd-Warshall),'D'(Dijkstra)
neighbors_algorithm='auto', # 'auto','brute','kd_tree','ball_tree'
n_jobs=None,
metric='minkowski',
p=2,
metric_params=None
)
X_embedded = model.fit_transform(X)
print(model.embedding_)
print(model.dist_matrix_) # 训练数据的全对最短路径距离
print(model.nbrs_) # NearestNeighbors 实例
print(model.kernel_pca_) # KernelPCA 实例
print(model.n_features_in_)
4. LocallyLinearEmbedding --- 局部线性嵌入(LLE)
python
from sklearn.manifold import LocallyLinearEmbedding
model = LocallyLinearEmbedding(
n_neighbors=5,
n_components=2,
reg=0.001, # 正则化常数
eigen_solver='auto',
tol=1e-6,
max_iter=100,
method='standard', # 'standard','hessian','modified','ltsa'
hessian_tol=0.0001, # Hessian LLE 的容差
modified_tol=1e-12, # Modified LLE 的容差
neighbors_algorithm='auto',
random_state=None,
n_jobs=None
)
X_embedded = model.fit_transform(X)
print(model.embedding_)
print(model.reconstruction_error_) # 与 reconstruction error_ 相关联
print(model.nbrs_)
5. SpectralEmbedding --- 谱嵌入
python
from sklearn.manifold import SpectralEmbedding
model = SpectralEmbedding(
n_components=2,
affinity='nearest_neighbors', # 'nearest_neighbors','rbf','precomputed',callable
gamma=None, # RBF 核参数
random_state=None,
eigen_solver=None, # None,'arpack','lobpcg','amg'
eigen_tol='auto',
n_neighbors=None, # nearest_neighbors 的邻居数
n_jobs=None
)
X_embedded = model.fit_transform(X)
print(model.embedding_)
print(model.affinity_matrix_)
📊 PCA 实用技巧
确定保留的方差
python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
pca = PCA().fit(X)
# 累积方差比例
cumsum = np.cumsum(pca.explained_variance_ratio_)
# 找到 95% 方差所需的成分数
n_95 = np.argmax(cumsum >= 0.95) + 1
print(f"Components for 95% variance: {n_95}")
# 可视化
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
# 碎石图
ax1.bar(range(1, len(pca.explained_variance_ratio_) + 1),
pca.explained_variance_ratio_)
ax1.set_xlabel('Principal Component')
ax1.set_ylabel('Explained Variance Ratio')
# 累积方差
ax2.plot(range(1, len(cumsum) + 1), cumsum, 'bo-')
ax2.axhline(y=0.95, color='r', linestyle='--', label='95%')
ax2.axvline(x=n_95, color='r', linestyle='--')
ax2.set_xlabel('Number of Components')
ax2.set_ylabel('Cumulative Explained Variance')
ax2.legend()
plt.tight_layout()
plt.show()
PCA 逆变换(重建)
python
pca = PCA(n_components=0.95) # 只保留 95% 方差的成分
X_reduced = pca.fit_transform(X)
X_reconstructed = pca.inverse_transform(X_reduced)
# 计算重建误差
reconstruction_error = np.mean((X - X_reconstructed) ** 2)
📝 算法选择指南
| 场景 | 推荐 |
|---|---|
| 线性降维、去噪 | PCA |
| 稀疏数据(如 TF-IDF) | TruncatedSVD |
| 非负数据 | NMF |
| 非线性可视化(2D/3D) | TSNE |
| 保留全局结构 | MDS / Isomap |
| 保留局部结构 | LocallyLinearEmbedding |
| 独立源信号 | FastICA |
| 概率建模 | FactorAnalysis |
| 文本主题 | LatentDirichletAllocation |
| 大数据增量 | IncrementalPCA |
| 非线性 + 核方法 | KernelPCA |
| 稀疏表示 | SparsePCA / DictionaryLearning |
\[sklearn-总览\|← 返回总览\]