目录
1. 学习内容
1. 了解PCA算法的思想及原理
2. 了解PCA算法的实现及应用
2. PCA算法介绍
PCA即主成分分析方法,是一种使用最广泛的数据降维算法(非监督的机器学习方法)。其最主要的用途在于“降维”,即通过析取主成分显出的最大的个别差异,发现更便于人类理解的特征。也可以用来削减回归分析和聚类分析中变量的数目[1]。
很多时候我们要用到的数据会具有非常多的特征。数据的特征越多意味着处理时间越长。因此有必要过滤掉一些不太重要的特征。同时,这些特征部分彼此之间存在关联。这既会增加分析问题的复杂性,又因为如果对每个特征进行单独分析,其分析结果往往是孤立的,不能完全利用数据中的信息。因此盲目减少指标会损失很多有用的信息,从而产生错误的结论。
总之,我们需要找到一种合理的方法,在减少需要分析的特征的同时,尽量减少原特征包含信息的损失,以达到对所收集数据进行尽可能全面分析的目的。由于各变量之间存在一定的相关关系,因此可以考虑将关系紧密的变量变成尽可能少的新变量,使这些新变量彼此是两两不相关的。那么就可以用较少的特征分别代表存在于各个变量中的各类信息。PCA就属于这类降维算法[1]。
3. PCA的思想
以一个二维空间的散点图为例,我们可以考虑取它们的横坐标或者纵坐标来代替他们。不过究竟取横坐标还是纵坐标更好呢?答案是:哪个区分度越高取哪个。如果每个点横坐标差别较大而纵坐标十分接近,那么取横坐标就要比取纵坐标好得多。不过,真实的情况往往要有比映射到坐标轴更好的映射方法,可以既保证数据彼此的区分度大同时又能尽可能地保留原数据的信息。
那么,我们要如何衡量映射后数据彼此的区分度呢?答案是:方差。映射后的数据方差越大,说明他们的区分度越高。
4. PCA的求解步骤
4.1 核心方法
1. 样本均值归0,也就是让每一个样本都减去均值。这么做的目的是为了简化方差的计算;
2. 找到一个单位方向向量,使得每个样本映射到其所在直线上的值方差最大。
对方差进行最优化时需要注意:这里求解的不是最小值而是最大值,因此要使用梯度上升法。
在对PCA的目标函数使用梯度上升法时还有几个需要注意的地方:首先,参数的初始值不能为0向量,而要是一个随机值构成的向量;其次,由于求解的是一个单位向量,因此整个过程中都要保证向量的模为1。
4.2 求解第n主成分
核心方法可以直接帮助我们求解一个数据的第一主成分(也就是最最重要的那个特征)。不过有时候我们不止需要一个主成分,那么要如何求解多个主成分呢?
答案很简单,那就是先将数据集在第一个主成分上的分量去掉,然后在没有第一个主成分的基础上再寻找第二个主成分。去掉的具体做法就是用上一次的输入样本减去由其得到的主成分就可以了。
5. PCA算法的应用
5.1 降维
实际上,在得到各个主成分之后将原数据分别与它们进行内积操作就可以了。例如,原数据为X(n个数据,m个特征),主成分构成的矩阵为W(一共有k个主成分,每个主成分维度也是m)。
此时,令,得到的结果就是降维后的数据[3]。
我们可以在sklearn中使用相应的模块来利用PCA进行降维。下面我们就用手写数字数据来看看降维对KNN分类算法的影响。
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.decomposition import PCA
digits = datasets.load_digits()
X = digits.data
y = digits.target
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 666)
knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train, y_train)
print(knn_clf.score(X_test, y_test))
pca = PCA(n_components = 2)
pca.fit(X_train)
X_train_reduction = pca.transform(X_train) # 训练数据集降维结果
X_test_reduction = pca.transform(X_test) # 测试数据集降维结果
knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train_reduction, y_train)
print(knn_clf.score(X_test_reduction, y_test))
结果如下:
0.9866666666666667
0.6066666666666667
可以发现,降维的确会损失一些信息从而影响算法的精确度。
那么,我么要如何控制降维后的精度呢?此时就需要使用一个特殊的指标:解释方差比例。这个指标可以令数据在降维后可以保持在期望的精度上。在sklearn中,解释方差比例是一个numpy数组,其中从前往后的值代表着第几个主成分保留了原数据方差的比例。同时,该数组从前往后是保持单调递减的。
因此,我们可以考虑先将原数据转化为一个较高维度的数据,然后画出它的累计分布函数图像。再根据我们希望保持的精确度从图中选择合适的维度。
实际上,再sklearn中还有更加简单的方法。那就是在初始化PCA模型的时候传入一个表示保留原方差比例的浮点数而非一个表示保留主成分个数的整数。
5.2 降噪
在使用PCA进行降维处理后,如果对得到的数据进行逆过程,则原来的噪音就会被削弱,从而实现了降噪的目的。不过需要注意的是:这个过程得到的数据已经不是原始数据了,而且原数据的一些信息也会在这个过程中丢失。
import numpy as np
import matplotlib.pyplot as plt
X = np.empty((100, 2))
X[:,0] = np.random.uniform(0., 100., size=100)
X[:,1] = 0.75 * X[:,0] + 3. + np.random.normal(0, 5, size=100)
plt.scatter(X[:,0], X[:,1])
plt.show()

import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
pca = PCA(n_components = 1)
pca.fit(X)
X_reduction = pca.transform(X)
X_restore = pca.inverse_transform(X_reduction)
plt.scatter(X_restore[:,0], X_restore[:,1])
plt.show()

5.3 可视化
这是显而易见的,因为如果可以把高维度的数据降维到二维或者三维,那么就可以直接作图进行可视化了。而且,呈现的结果都是最具有代表性的特征。
6. 参考文献
1. https://mp.weixin.qq.com/s/eNYpH3i4JQIxl-ni3lTrsA
2. https://mp.weixin.qq.com/s/RSx5M9oOmdmekq0htTz0qQ