PCA与SVD降维的结果比较(以Iris数据集为例)(附Python代码)

比较结果

左上:原始数据的前两维特征。

右上:利用Sklearn库函数decomposition.PCA()对原数据进行PCA后,取前两个维度的特征。

左下:按照PCA的步骤对数据进行处理得到结果,并前两个维度特征。这里已经对结果取负,具体步骤参考利用PCA对Iris数据集降维

右下:直接对去均值化后的原始数据进行SVD分解,即dataremovemean=UΣVTdata_{remove-mean} = U * \Sigma * V^T,然后直接利用VV右乘去均值化的数据得到结果即KaTeX parse error: Expected group after '^' at position 32: …emove-mean} * V^̲。然后取前两个维度的特征。
PCA与SVD降维的结果比较(以Iris数据集为例)(附Python代码)
比对发现,PCA与SVD降维可以达到同样的效果,只是有维度相差一个负号,因为降维后的数据本身的物理意义难以确认,所以笔者认为不影响后续的处理。

Show me the code

导包

# 数据集
from sklearn import datasets
# 包含PCA的模块
from sklearn import decomposition

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

获取数据

# 载入鸢尾花数据
iris = datasets.load_iris()
x_true = iris.data
y_true = iris.target
feature_names = iris.feature_names
target_names = iris.target_names

#将样本命名为origin翻边方便后面使用
origin = x_true

分别利用三种方式降维

# 利用sklearn库函数进行PCA
pca_library_result = decomposition.PCA().fit(origin)
pca_library_result = pca_library_result.transform(origin)

# 利用正规PCA来处理origin
# 去均值化
origin_after_sub_mean = origin - np.mean(origin, axis= 0)
# 求协方差矩阵
cov = np.dot(origin_after_sub_mean.T, 
			 origin_after_sub_mean) / origin.shape[0]
# 对协方差矩阵进行svd分解
pca_u, pca_s, pca_v = np.linalg.svd(cov)
# 结果,注意这里对结果取负,使保持与库函数结果一致
origin_rot = -np.dot(origin_after_sub_mean, pca_u)


# 利用svd的s矩阵右乘来处理
U, S, VT = np.linalg.svd(origin_after_sub_mean)
result = np.dot(origin_after_sub_mean, VT.T)


# 利用前两列进行绘图
plt.figure(figsize= (12, 12))

plt.subplot(221)
plt.scatter(origin[:, 0], origin[:, 1], c= y_true, lw= 5)
plt.title("Origin data and it's first two features")

plt.subplot(222)
plt.scatter(pca_library_result[:, 0], pca_library_result[:, 1], 
			c= y_true, lw= 5)
plt.title("After using library function to PCA and it's first two features")

plt.subplot(223)
plt.scatter(origin_rot[:, 0], origin_rot[:, 1], c= y_true, lw= 5)
plt.title("After using PCA and it's first two features (take -result)")

plt.subplot(224)
plt.scatter(result[:, 0], result[:, 1], c= y_true, lw= 5)
plt.title("After using SVD's matrix V directly and it's first two features")
plt.savefig("PCA与直接运用SVD的V矩阵降维比较.png", quplity= 100)
plt.show()