当前位置: 首页 > news >正文

吴恩达机器学习课程(PyTorch 适配)学习笔记:3.2 降维技术详解(PCA)

特征降维概述

什么是降维?

降维是指将高维数据转换为低维表示的过程,同时尽可能保留原始数据的关键信息。在机器学习中,当特征数量过多时,会出现"维度灾难"问题,降维技术能有效解决这一问题。

为什么需要降维?

  1. 缓解维度灾难:高维空间中数据稀疏,模型难以学习有效模式
  2. 减少计算成本:降低特征数量能显著减少训练时间和存储需求
  3. 数据可视化:将高维数据降至2D或3D便于可视化分析
  4. 去除噪声和冗余:识别并保留重要特征,提高模型泛化能力

降维方法分类

  • 线性降维:PCA、LDA、因子分析
  • 非线性降维:t-SNE、UMAP、自编码器
  • 基于特征选择:过滤法、包裹法、嵌入法

PCA 算法详解

基本思想

主成分分析(PCA)通过正交变换将可能存在相关性的变量转换为一组线性不相关的变量,这组变量称为主成分。第一个主成分具有最大方差,后续每个主成分都与前一个正交且方差递减。

数学原理

1. 数据标准化

首先对原始数据进行标准化处理:

import torch
import numpy as npdef standardize_data(X):"""标准化数据"""mean = torch.mean(X, dim=0)std = torch.std(X, dim=0)return (X - mean) / std
2. 协方差矩阵计算

对于标准化后的数据矩阵 XXX,计算协方差矩阵:
Σ=1n−1XTX \Sigma = \frac{1}{n-1} X^T X Σ=n11XTX

3. 特征分解

对协方差矩阵进行特征分解:
Σ=QΛQT \Sigma = Q \Lambda Q^T Σ=QΛQT
其中 QQQ 是特征向量矩阵,Λ\LambdaΛ 是对角特征值矩阵。

4. 选择主成分

按特征值从大到小排序,选择前 kkk 个特征向量组成投影矩阵。

PCA 算法流程

原始高维数据
数据标准化
计算协方差矩阵
特征值分解
选择主成分数量k
构建投影矩阵
数据投影到低维空间
降维后的数据

PCA 的 PyTorch 实现

import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
import numpy as npclass PCA:"""PCA 实现类"""def __init__(self, n_components):self.n_components = n_componentsself.components = Noneself.mean = Noneself.explained_variance_ratio = Nonedef fit(self, X):"""训练PCA模型"""# 计算均值self.mean = torch.mean(X, dim=0)# 中心化数据X_centered = X - self.mean# 计算协方差矩阵covariance_matrix = torch.mm(X_centered.T, X_centered) / (X.shape[0] - 1)# 特征值分解eigenvalues, eigenvectors = torch.linalg.eigh(covariance_matrix)# 按特征值降序排序sorted_indices = torch.argsort(eigenvalues, descending=True)eigenvalues = eigenvalues[sorted_indices]eigenvectors = eigenvectors[:, sorted_indices]# 选择前n_components个主成分self.components = eigenvectors[:, :self.n_components]# 计算解释方差比total_variance = torch.sum(eigenvalues)self.explained_variance_ratio = eigenvalues[:self.n_components] / total_variancereturn selfdef transform(self, X):"""将数据投影到主成分空间"""X_centered = X - self.meanreturn torch.mm(X_centered, self.components)def fit_transform(self, X):"""训练并转换数据"""self.fit(X)return self.transform(X)# 示例:在Iris数据集上应用PCA
def pca_demo():# 加载数据iris = load_iris()X = torch.tensor(iris.data, dtype=torch.float32)y = iris.target# 应用PCApca = PCA(n_components=2)X_pca = pca.fit_transform(X)print(f"原始数据形状: {X.shape}")print(f"降维后数据形状: {X_pca.shape}")print(f"解释方差比: {pca.explained_variance_ratio}")print(f"累计解释方差: {torch.sum(pca.explained_variance_ratio):.4f}")# 可视化结果plt.figure(figsize=(12, 5))plt.subplot(1, 2, 1)for i, target_name in enumerate(iris.target_names):plt.scatter(X_pca[y == i, 0], X_pca[y == i, 1], label=target_name, alpha=0.7)plt.xlabel('Principal Component 1')plt.ylabel('Principal Component 2')plt.title('PCA: Iris Dataset')plt.legend()plt.grid(True, alpha=0.3)plt.subplot(1, 2, 2)# 绘制解释方差比pca_full = PCA(n_components=4)pca_full.fit(X)explained_variance = pca_full.explained_variance_ratiocumulative_variance = torch.cumsum(explained_variance, dim=0)plt.bar(range(1, 5), explained_variance, alpha=0.6, label='Individual explained variance')plt.step(range(1, 5), cumulative_variance, where='mid',label='Cumulative explained variance')plt.ylabel('Explained variance ratio')plt.xlabel('Principal components')plt.title('Explained Variance by Components')plt.legend()plt.tight_layout()plt.show()# 运行示例
pca_demo()

基于PyTorch的神经网络PCA实现

class NeuralPCA(nn.Module):"""使用自编码器实现PCA的神经网络版本"""def __init__(self, input_dim, encoding_dim):super(NeuralPCA, self).__init__()self.encoder = nn.Sequential(nn.Linear(input_dim, encoding_dim, bias=False),)self.decoder = nn.Sequential(nn.Linear(encoding_dim, input_dim, bias=False),)def forward(self, x):encoded = self.encoder(x)decoded = self.decoder(encoded)return decoded, encodeddef train_neural_pca(X, encoding_dim=2, epochs=1000, lr=0.01):"""训练神经PCA"""model = NeuralPCA(X.shape[1], encoding_dim)criterion = nn.MSELoss()optimizer = torch.optim.Adam(model.parameters(), lr=lr)losses = []for epoch in range(epochs):optimizer.zero_grad()reconstructed, encoded = model(X)loss = criterion(reconstructed, X)loss.backward()optimizer.step()losses.append(loss.item())if epoch % 200 == 0:print(f'Epoch [{epoch}/{epochs}], Loss: {loss.item():.6f}')return model, encoded, losses# 使用神经PCA
def neural_pca_demo():iris = load_iris()X = torch.tensor(iris.data, dtype=torch.float32)y = iris.target# 标准化数据X_normalized = (X - torch.mean(X, dim=0)) / torch.std(X, dim=0)# 训练神经PCAmodel, encoded, losses = train_neural_pca(X_normalized)# 可视化训练过程和结果plt.figure(figsize=(15, 5))plt.subplot(1, 3, 1)plt.plot(losses)plt.title('Training Loss')plt.xlabel('Epoch')plt.ylabel('MSE Loss')plt.grid(True, alpha=0.3)plt.subplot(1, 3, 2)for i, target_name in enumerate(iris.target_names):plt.scatter(encoded.detach().numpy()[y == i, 0], encoded.detach().numpy()[y == i, 1], label=target_name, alpha=0.7)plt.xlabel('Encoded Dimension 1')plt.ylabel('Encoded Dimension 2')plt.title('Neural PCA: Iris Dataset')plt.legend()plt.grid(True, alpha=0.3)plt.subplot(1, 3, 3)# 比较传统PCA和神经PCAtraditional_pca = PCA(n_components=2)X_traditional = traditional_pca.fit_transform(X_normalized)plt.scatter(X_traditional[:, 0].numpy(), X_traditional[:, 1].numpy(), c='red', alpha=0.5, label='Traditional PCA')plt.scatter(encoded.detach().numpy()[:, 0], encoded.detach().numpy()[:, 1],c='blue', alpha=0.5, label='Neural PCA')plt.xlabel('Component 1')plt.ylabel('Component 2')plt.title('Comparison: Traditional vs Neural PCA')plt.legend()plt.grid(True, alpha=0.3)plt.tight_layout()plt.show()neural_pca_demo()

注意事项和易错点

1. 数据预处理

# 错误做法:未标准化数据
# pca.fit(raw_data)  # 可能导致某些特征主导PCA# 正确做法:标准化数据
def proper_preprocessing(X):# 方法1: 标准化 (推荐)X_standardized = (X - torch.mean(X, dim=0)) / torch.std(X, dim=0)# 方法2: 归一化X_normalized = (X - torch.min(X, dim=0)[0]) / (torch.max(X, dim=0)[0] - torch.min(X, dim=0)[0])return X_standardized

2. 主成分数量选择

def select_optimal_components(X, variance_threshold=0.95):"""自动选择主成分数量"""pca_full = PCA(n_components=X.shape[1])pca_full.fit(X)cumulative_variance = torch.cumsum(pca_full.explained_variance_ratio, dim=0)# 找到达到方差阈值的第一个成分n_components = torch.argmax(cumulative_variance >= variance_threshold) + 1print(f"推荐的主成分数量: {n_components}")print(f"累计解释方差: {cumulative_variance[n_components-1]:.4f}")return n_components# 使用示例
iris = load_iris()
X = torch.tensor(iris.data, dtype=torch.float32)
X_standardized = (X - torch.mean(X, dim=0)) / torch.std(X, dim=0)optimal_k = select_optimal_components(X_standardized)

3. PCA的局限性

  • 线性假设:PCA只能捕捉线性关系
  • 方差不代表重要性:高方差特征不一定是最重要的
  • 类别信息丢失:无监督方法,可能丢失与类别相关的信息

高级应用:增量PCA

class IncrementalPCA:"""增量PCA,适用于大数据集"""def __init__(self, n_components, batch_size=50):self.n_components = n_componentsself.batch_size = batch_sizeself.components = Noneself.mean = Noneself.var = Noneself.n_samples_seen = 0def partial_fit(self, X):"""增量学习"""if self.mean is None:# 初始化self.mean = torch.zeros(X.shape[1])self.var = torch.zeros(X.shape[1])self.components = torch.randn(X.shape[1], self.n_components)# 更新统计量batch_mean = torch.mean(X, dim=0)batch_var = torch.var(X, dim=0)# 更新均值和方差n_total = self.n_samples_seen + X.shape[0]self.mean = (self.n_samples_seen * self.mean + X.shape[0] * batch_mean) / n_totalself.var = (self.n_samples_seen * self.var + X.shape[0] * batch_var) / n_totalself.n_samples_seen += X.shape[0]return selfdef transform(self, X):"""转换数据"""X_centered = X - self.meanreturn torch.mm(X_centered, self.components)# 使用增量PCA处理大数据
def incremental_pca_demo():# 生成示例大数据torch.manual_seed(42)n_samples, n_features = 1000, 20large_data = torch.randn(n_samples, n_features)ipca = IncrementalPCA(n_components=5, batch_size=100)# 分批处理数据for i in range(0, n_samples, 100):batch = large_data[i:i+100]ipca.partial_fit(batch)transformed = ipca.transform(large_data)print(f"增量PCA结果形状: {transformed.shape}")incremental_pca_demo()

总结

PCA是降维技术中最基础且重要的方法,应该掌握:

  1. PCA的数学原理和算法流程
  2. 使用PyTorch实现PCA的多种方法
  3. 主成分数量选择的策略
  4. PCA的注意事项和局限性
  5. 高级PCA变体的实现

在实际应用中,要根据数据特性和任务需求选择合适的降维方法,并注意数据预处理和参数调优。PCA作为线性降维的基准方法,为理解更复杂的降维技术奠定了重要基础。

http://www.dtcms.com/a/458608.html

相关文章:

  • 一元购网站建设多少钱手机网站生成代码
  • 天津免费做网站公司网站建设30元
  • 天津智能网站建设制作做电商要关注哪些网站
  • 商店网站源码淮安做网站
  • Effective STL 第4条:调用empty()而不是检查size()是否为0
  • 家具网站开发环境与工具铜陵市网站建设
  • Mysql初阶第三讲:Mysql数据类型
  • 网络营销价格北京seo公司工作
  • 徐州cms模板建站建设购物网站多少钱
  • 视频网站点击链接怎么做的工业设计出来做什么
  • 怎样把网站做的漂亮个人网站用主机做服务器
  • 备案掉了网站会怎样开发一套小区多少钱
  • Java基础 10.8
  • 长湖南营销型网站简单网站建设公司
  • 计算机基础——浏览器、算法、计算机原理和编译原理等
  • 网站制作企业有哪些下页
  • 企业做外贸网站常用术语通江移动网站建设
  • vultr做网站广东软件公司排名
  • [1]python爬虫入门,爬取豆瓣电影top250实践
  • 学习网站开发体会与感想wordpress多语言插件:qtranslate
  • 辽源市网站建设html怎么制作网页
  • 旅游网站建设的目标蓝天下品牌运营业务展示
  • 网站死循环青岛网红打卡景点
  • 域名过期做的网站怎么办门户网站建设与推广方案
  • 文档做网站闵行营销型网站制作
  • 网页设计报告模板免费wordpress安装后优化
  • 重庆制作网站公司简介网上商城运营推广方案
  • 网站代码怎么打开青岛制作公司网站
  • 适合女生做的网站主题做网站销售一个星期的计划
  • 郑州一凡网站建设简易手机站