PCA(主成分分析)简介与使用
1 PCA(Principal Component Analysis)简介
在平常的研究和应用中处理的数据都是多变量的(多维),能够提供丰富的信息,但是很难对多维的数据各维指标进行分析,因为往往孤立地分析每个指标不能完全利用数据中的信息,但盲目减少指标会损失很多有用的信息。
所以我们需要找到一种合理的方法,在减少需要分析的指标的同时尽量减少原指标包含信息的损失。
数据的各变量之间存在一定的相关关系,所以我们可以考虑将关系紧密的变量变成尽可能少的新变量,使得新得到的变量是两两不相关的。这样就可以用较少的综合指标分别代表存在于各个变量中的信息。
主成分分析(PCA)就是利用上述方法对多维数据进行降维,将拥有多个属性的数据转换为少数属性的数据,便于分析数据。PCA的主要思想是将n维特征映射到k维上(k维特征是从n维特征重新构造出来的正交特征,也称为主成分)
PCA的算法流程是利用数据的协方差矩阵计算其特征值和特征向量,然后选出少量(想要最后拥有多少属性就选择多少)的较大特征值的特征向量与原始数据点积得到降维后的数据。下面来看具体的内容。
降维:对高维度特征数据预处理,保留最重要的一些特征,去除噪声和不重要的特征(伴随着些许信息的损失)。
1.1 协方差矩阵
首先我们想知道什么是协方差矩阵,先来看协方差:协方差是用来衡量两个变量相关性的变量,当这两个变量是同一变量时协方差便是方差。
假设两个变量\(X\),\(Y\),那么\(X\),\(Y\)的协方差为: \[ Cov(X,Y)=\frac{\sum_{i=1}^n{(x_i-\overline x)(y_i-\overline y)}}{n-1} \]
其中,\(\overline x\)是\(X\)的均值。除以n-1
而不是n
是因为
- 当两个变量是正相关关系(同增同减)时,协方差>0;
- 当两个变量是负相关关系(一增一减)时,协方差<0;
- 当两个变量不相关时,协方差=0。
所以,协方差矩阵表示的是所有变量之间两两相关的关系。
从二维协方差矩阵矩阵开始,其实二维的协方差矩阵没有实际意义,为了方便后面多维协方差矩阵的推广,先从二维协方差矩阵开始看。
假设我们有样本Z如下: \[ Z=\begin{bmatrix} 1 & 2 \\ 3 & 6 \\ 4 & 2 \\ 5 & 2 \end{bmatrix} \]
利用两个变量空间\(X\),\(Y\)来表示上面的两列(即两个特征): \[ X=\begin{bmatrix} 1 \\ 3 \\ 4 \\ 5 \end{bmatrix}, \ \ \ Y=\begin{bmatrix} 2 \\ 6 \\ 2 \\ 2 \end{bmatrix} \]
那么协方差矩阵\(Cov(Z)\)为: \[ Cov(Z)=\begin{bmatrix} Cov(X,X) & Cov(X,Y) \\ Cov(Y,X) & Cov(Y,Y) \end{bmatrix} \]
由协方差的计算公式计算协方差矩阵中的各项:
首先需要出\(X\),\(Y\)两个特征空间的平均值:\(\overline x = 3.25\), \(\overline y = 3\)。
接下来计算矩阵中的各项: \[ Cov(X,X)=\frac{(1-3.25)^2+(3-3.25)^2+(4-3.25)^2+(5-3.25)^2}{4-1}=2.9167 \]
\[ Cov(X,Y)=\frac{(1-3.25)(2-3)+(3-3.25)(6-3)+(4-3.25)(2-3)+(5-3.25)(2-3)}{4-1}=-0.3333 = Cov(Y,X) \]
\[ Cov(Y,Y)=\frac{(2-3)^2+(6-3)^2+(2-3)^2+(2-3)^2}{4-1}=4 \]
所以最后得到的协方差矩阵为: \[ Cov(Z)=\begin{bmatrix} 2.9167 & -0.3333 \\ -0.3333 & 4.000 \end{bmatrix} \]
经过上面二维协方差矩阵的计算可以总结出协方差矩阵的计算方式(任意维):
首先对样本Z按列进行中心化,即Z中的每列数据减去这列的平均值。(将中心化后的Z重新赋值给Z)。
然后通过公式\(Cov(Z) = \frac{1}{n} ZZ^{T}\)即可得到协方差矩阵。
1.2 特征向量
对于线性代数而言,特征向量和特征值体现了矩阵的本质。借一个比喻来看,把矩阵看做运动,那么特征值是速度的大小,而特征向量是速度的方向。还可以说特征向量是在其矩阵的作用下进行伸缩,伸缩的幅度由特征向量对应的特征值确定。
特征值和特征向量的定义如下:
假设A是n阶矩阵,如果存在常数λ和n维非零向量X使得: \[ AX = \lambda X \]
通常来说,矩阵A会有一组特征向量,将它们进行正交化单位化,就能得到一组正交单位特征向量。
2 PCA的使用
2.1 数据
这里使用的数据是谷歌新闻的词向量数据集的一部分,也就是部分词的词向量。
数据文件在这里
导入数据,即获取词向量: 1
2
3
4
5
6
7
8import numpy as np
import pickle
import pandas as pd
import matplotlib.pyplot as plt
word_embeddings = pickle.load(open('./word_embeddings_subset.p','rb'))
print(len(word_embeddings))
print("dimension: {}".format(word_embeddings['Spain'].shape[0]))243
dimension: 300
所以数据是300维的。
2.2 PCA
利用PCA算法将上述300维的数据转换为2维数据。
1 | def compute_pca(X,n_components=2): |
3 利用PCA进行降维
首先来一个帮助函数来获取词向量矩阵: 1
2
3
4
5
6
7
8
9
10def get_vectors(embeddings, word):
m = len(words)
X = np.zeros((1, 300))
for word in words:
emb = embeddings[word]
X = np.row_stack((X, emb))
X = X[1:, :] ## 最开始的一行零去掉
return X1
2words = ['oil', 'gas', 'happy', 'sad', 'city', 'town','village', 'country', 'continent', 'petroleum', 'joyful']
X = get_vectors(word_embeddings, words)1
2
3
4
5
6result = compute_pca(X, 2)
plt.scatter(result[:, 0], result[:, 1])
for i, word in enumerate(words):
plt.annotate(word, xy=(result[i, 0] - 0.05, result[i, 1] + 0.1))
plt.show()
从图中可以分析得出, 'gas', 'oil' 和 'petroleum' 属于同一类,'sad', 'joyful' 和 'happy' 为一类,其他的聚集为一类。