使用pytorch和sklearn的PCA分别对mnist做降维

1. pytorch,使用   torch.pca_lowrank 函数

A,要处理的数据, q要保留的维度,返回(S,V,D)元组,中间的V为降维后的维度

代码

import torch
import torchvision.datasets as data
from torch.utils.data import DataLoader
import torchvision.transforms as T
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# 颜色设置
color = ['yellow','black','aqua','green','teal','orange','navy','pink','purple','red']
# 绘图
def show(v2,y):
    for i in range(len(v2)):
        plt.scatter(v2[i][0],v2[i][1],color=color[y[i]])
    plt.show()
def show3d(v3,y):
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    for i in range(len(v3)):
        ax.scatter(v3[i][0],v3[i][1],v3[i][2],color=color[y[i]])
    plt.show()

trans = T.Compose([
    T.ToTensor(),
    T.Normalize(mean=0, std=1)
])
mnist = data.MNIST('../mnist',train=True,download=False, transform=trans)
loader_train = DataLoader(mnist, batch_size=200, shuffle=True) # 可视化200个点

for (x,y) in loader_train:
    x = torch.squeeze(x) # 去掉维度为1的, 也就是以28x28来分,结果不太好
    # x = x.flatten(start_dim=2,end_dim=-1) #方法2: 压平,以1x784来分

    print(x.shape)
    # pca
    v3 = []
    for i in range(len(x)):
        v3.append(torch.pca_lowrank(x[i],q=3)[1].numpy()) # 3维
    v2 = []
    for i in range(len(x)):
        v2.append(torch.pca_lowrank(x[i],q=2)[1].numpy()) # 2维
    print(v2)
    # 画图
    show(v2,y)
    show3d(v3,y)
    break

结果:效果特别差,找不到原因。后来使用sklearn的要好很多

 

2. sklearn,使用 from sklearn import decomposition

代码

import torch
import torchvision.datasets as data
from torch.utils.data import DataLoader
import torchvision.transforms as T
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn import decomposition
# 颜色设置
color = ['yellow','black','aqua','green','teal','orange','navy','pink','purple','red']
# 绘图
def show(v2,y):
    for i in range(len(v2)):
        plt.scatter(v2[i][0],v2[i][1],color=color[y[i]])
    plt.show()
def show3d(v3,y):
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    for i in range(len(v3)):
        ax.scatter(v3[i][0],v3[i][1],v3[i][2],color=color[y[i]])
    plt.show()

trans = T.Compose([
    T.ToTensor(),
    T.Normalize(mean=0, std=1)
])
mnist = data.MNIST('../mnist',train=True,download=False, transform=trans)
loader_train = DataLoader(mnist, batch_size=200, shuffle=True) # 可视化1000个点

for (x,y) in loader_train:
    # x = torch.squeeze(x) # 方法一:去掉维度为1的, 也就是以28x28来分,结果不太好
    x = x.flatten(start_dim=2,end_dim=-1) #方法2: 压平,以1x784来分
    x = torch.squeeze(x) # 去掉维度为1的
    print(x.shape)
    # pca
    pca2 = decomposition.PCA(2)
    pca3 = decomposition.PCA(3)
    # 3维
    v3 = []
    pca3.fit(x)  # sklearn的pca要求输入是(m,n)m为样本数,n为维数
    temp = pca3.fit_transform(x)
    v3.append(temp) # 3维
    print(len(v3[0]))
    # 2维
    v2 = []
    pca2.fit(x)
    print('ssss',pca2.explained_variance_ratio_) #看每个特征可以百分之多少表达整个数据集
    v2.append(pca2.fit_transform(x)) # 2维
    print(v2)
    # 画图
    show(v2[0],y)
    show3d(v3[0],y)
    break
pca = decomposition.PCA()
pca.fit(x)

结果

### 如何在 PyTorch 中实现或使用 PCA PCA 是一种统计方法,主要用于数据压缩,在多种应用场景中表现出色[^1]。尽管 PyTorch 主要专注于深度学习任务,但仍然可以通过一些技巧来利用 PyTorch 实现 PCA。 #### 使用 NumPy Scikit-Learn 进行预处理 虽然 PyTorch 自身并不直接提供 PCA 的功能模块,但在实践中可以先借助 `scikit-learn` 库完成 PCA 变换,再将转换后的数据导入到 PyTorch 模型中继续后续操作: ```python from sklearn.decomposition import PCA import numpy as np # 假设 X 是输入的数据矩阵 (n_samples, n_features) pca = PCA(n_components=2) # 设置目标度数量 X_reduced = pca.fit_transform(X) print(f"原始形状: {X.shape}") print(f"变换后形状: {X_reduced.shape}") # 将结果转化为张量供 PyTorch 使用 tensor_X_reduced = torch.tensor(X_reduced).float() ``` #### 利用 PyTorch 手动计算协方差矩阵并求解特征向量 如果希望完全基于 PyTorch 来执行 PCA,则需要手动编写代码来进行如下几个步骤的操作: 1. **中心化**: 计算每列均值并将所有元素减去对应列的平均数; 2. **构建协方差矩阵**; 3. **SVD分解**, 获取前 k 大奇异值对应的右奇异向量作为新的基底; 4. **投影至新空间**. 以下是具体实现方式: ```python def pca_torch(data_tensor, num_components): """ :param data_tensor: 输入数据 Tensor 形状为(batch_size, feature_dim) :param num_components: 需保留的主要成分数目 """ mean_vector = torch.mean(data_tensor, dim=0) centered_data = data_tensor - mean_vector cov_matrix = torch.matmul(centered_data.T, centered_data)/(data_tensor.size(0)-1) _, eigenvalues, eigenvectors = torch.svd(cov_matrix) top_k_eigenvector = eigenvectors[:, :num_components] transformed_data = torch.mm(centered_data, top_k_eigenvector) return transformed_data # 测试函数 if __name__ == "__main__": from torchvision.datasets import MNIST from torchvision.transforms import ToTensor dataset = MNIST(root='./mnist', train=True, transform=ToTensor(), download=True) images = next(iter(dataset))[0].view(-1) # 提取单个样本展平成一向量 batch_images = images.unsqueeze(0).repeat((8, 1)) # 创建一个小批量重复该样本 reduced_batch = pca_torch(batch_images, 2) print(reduced_batch.shape) ``` 此段代码展示了如何仅依赖于 PyTorch 完整地实现了 PCA 算法的核心逻辑。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值