第十章.主成分分析(PCA)
①.数据预处理:中心化𝑋−𝑋`。
②.求样本的协方差矩阵(1/m)𝑋𝑋𝑇
③.对协方差(1/m)𝑋𝑋𝑇矩阵做特征值分解。
④.选出最大的k个特征值对应的k个特征向量。
⑤.将原始数据投影到选取的特征向量上。
⑥.输出投影后的数据集。
方差是描述一个数据的离散程度:
协方差是描述两个数据的相关性,接近1就是正相关, 接近-1就是负相关,接近0就是不相关。
通过数据集的协方差矩阵及其特征值分析,我们可以得到协方差矩阵的特征向量和特征值。我们需要保留k个维度的特征就选取最大的k个特征值。
①.代码实现
import numpy as np
import matplotlib.pyplot as plt# 数据中心化
def zeroMean(data):mean = np.mean(data, axis=0) # 按列求平均,即各个特征的均值norm = data - meanreturn norm, meandef PCA(data, k):# 1.数据中心化norm, mean = zeroMean(data)# 2.样本的协方差矩阵covMat = np.cov(norm, rowvar=0) # rowvar=0:一行数据代表一个样本# 3.对协方差矩阵做特征值和特征向量分解eigVals, eigVects = np.linalg.eig(np.mat(covMat))# 4.选出最大的k个特征值对应的k个特征向量。eigVals_sort = np.argsort(eigVals)n_eigVals = eigVals_sort[-1:-(k + 1):-1] # 最大的k个特征值的下标n_eigVects = eigVects[:, n_eigVals] # 对应的k个特征向量# 5.将原始数据投影到选取的特征向量上。lowData = norm * n_eigVects # 低维特征空间的数据reconMat = (lowData * n_eigVects.T) + mean # 利用低维数据来重构数据return lowData, reconMat# 加载数据
data = np.genfromtxt('F:\\data.csv', delimiter=',')# 原始数据点
x_data = data[:, 0]
y_data = data[:, 1]
plt.scatter(x_data, y_data, c='b')# 重构后的数据点
k = 1 # 数据降到k维
lowData, reconMat = PCA(data, k)# 6.重构数据
x_dstdata = np.array(reconMat)[:, 0]
y_dstdata = np.array(reconMat)[:, 1]
plt.scatter(x_dstdata, y_dstdata, c='r')plt.show()
②.结果展示
①.代码实现
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split# 加载数据
digits = load_digits()# 数据
x_data = digits.data# 标签
t_data = digits.target# 数据分割:训练数据和测试数据
x_train, x_test, t_train, t_test = train_test_split(x_data, t_data)# 数据中心化
def zeroMean(data):mean = np.mean(data, axis=0) # 按列norm = data - meanreturn norm, mean# PCA
def PCA(data, k):# 1.数据中心化norm, mean = zeroMean(data)# 2.样本的协方差矩阵covMat = np.cov(norm, rowvar=0)# 3.对协方差矩阵做特征值和特征向量分解eig_vals, eig_vects = np.linalg.eig(np.mat(covMat))# 4.选出最大的k个特征值对应的k个特征向量eig_vals_sort = np.argsort(eig_vals)n_eig_vals = eig_vals_sort[-1:-(k + 1):-1]n_eig_vects = eig_vects[:, n_eig_vals]# 5.将原始数据投影到选取的特征向量上lowData = norm * n_eig_vectsreconMat = (lowData * n_eig_vects.T) + meanreturn lowData, reconMatfig = plt.figure(figsize=(6, 3))k = 2
# 降维数据
lowData, reconMat = PCA(x_data, k)
x_dstdata = np.array(lowData)[:, 0]
y_dstdata = np.array(lowData)[:, 1]
print(x_dstdata)
print(y_dstdata)
fig.add_subplot(121)
plt.scatter(x_dstdata, y_dstdata, c=t_data)
plt.title('2D')k = 3
# 降维数据
lowData, reconMat = PCA(x_data, k)
x_dstdata = np.array(lowData)[:, 0]
y_dstdata = np.array(lowData)[:, 1]
z_dstdata = np.array(lowData)[:, 2]
ax = fig.add_subplot(122, projection='3d')
ax.scatter(x_dstdata, y_dstdata, z_dstdata, c=t_data, s=10)
plt.title('3D')plt.show()
②.结果展示