本章数学公式太难了,作为初学者还是了解概念调包即可
主成分分析(PCA)
思想
- 主要是利用 正交变换,把 线性相关变量的数据转化为 线性无关的数据。线性无关的数据称为 主成分,该算法因此得名。变换后的数据不仅是 线性无关的,而且是 相互独立(协方差Cov(X,Y)=0)
- 新变量是正交变换中 方差和最大的,最大的称为 第一主成分,次大的是 第二主成分等等。
数学推导(todo)
- 先占个坑,有空回来看数学推导,这里的结论是
实现
import numpy as np
import matplotlib.pyplot as plt
data = np.loadtxt('PCA_dataset.csv', delimiter=',')
print(type(data))
_,(ax1,ax2) = plt.subplots(1,2)
print(type(ax1))
ax1.scatter(data[:,0],data[:,1],color='red',s=10)
def pca(x,k):
d,m = x.shape
if d < k:
print("k应该小于特征数")
return x,None
# 中心化
x = x - np.mean(x,axis=0)
# 计算协方差矩阵
cov = x.T @ x
# 计算特征值与特征向量
eig_val, eig_vec = np.linalg.eig(cov)
# 取最大的k个,因为加了负数,所以原本排序的规则颠倒过来
idx = np.argsort(-eig_val)[:k]
w = eig_vec[:,idx]
x = x @ w
return x,w
x,w = pca(data,2)
ax2.scatter(x[:,0],x[:,1],color='blue',s=10)
x_min, x_max = min(data[:, 0].min(), x[:, 0].min()), max(data[:, 0].max(), x[:, 0].max())
y_min, y_max = min(data[:, 1].min(), x[:, 1].min()), max(data[:, 1].max(), x[:, 1].max())
# 设置两个子图的坐标轴范围一致
ax1.set_xlim(x_min, x_max)
ax1.set_ylim(y_min, y_max)
ax2.set_xlim(x_min, x_max)
ax2.set_ylim(y_min, y_max)
# (可选)设置相同的刻度
ax1.set_xticks(np.linspace(x_min, x_max, 10)) # 例如,在x轴范围内均匀设置5个刻度
ax1.set_yticks(np.linspace(y_min, y_max, 10)) # 在y轴范围内均匀设置5个刻度
ax2.set_xticks(np.linspace(x_min, x_max, 10)) # 与 ax1 设置相同的刻度
ax2.set_yticks(np.linspace(y_min, y_max, 10)) # 与 ax1 设置相同的刻度
plt.show()
实现之调包
from sklearn.decomposition import PCA
# sklearn中调包使用
x = data - np.mean(data,axis=0)
data = np.loadtxt('PCA_dataset.csv', delimiter=',')
pca = PCA(n_components=2).fit(x)
w = pca.components_.T
print('变换矩阵是: {}\n'.format(w))
x_pca = x @ w
ax = plt.subplot()
ax.set_xticks(np.linspace(x_min, x_max, 5)) # 与 ax1 设置相同的刻度
ax.set_yticks(np.linspace(y_min, y_max, 5)) # 与 ax1 设置相同的刻度
ax.set_xlim(x_min, x_max)
ax.set_ylim(y_min, y_max)
ax.scatter(x_pca[:,0],x_pca[:,1])