1. sklearn的PCA类
在sklearn中,与PCA相关的类都在sklearn.decomposition包中,主要有:
- sklearn.decomposition.PCA
最常用的PCA类,接下来会在2中详细讲解。
- KernelPCA类,主要用于非线性数据的降维,需要用到核技巧。因此在使用的时候需要选择合适的核函数并对核函数的参数进行调参。
- IncrementalPCA类,主要解决单机内存限制。有时候样本量可能是上百万,维度可能也是上千,直接拟合数据可能会让内存爆掉, 此时可以用IncrementalPCA类来解决这个问题。IncrementalPCA先将数据分成多个batch,然后对每个batch依次递增调用partial_fit函数,这样一步步的得到最终的样本最优降维。
- SparsePCA和MiniBatchSparsePCA。二者和其他PCA类的区别主要是使用了L1正则化,这样可以将很多非主要成分的影响度降为0,这样在PCA降维的时候仅仅需要对那些相对比较主要的成分进行PCA降维,避免了噪声对PCA降维的影响。
SparsePCA和MiniBatchSparsePCA二者之间的区别是MiniBatchSparsePCA通过使用一部分样本特征和给定的迭代次数来进行PCA降维,以解决在大样本时特征分解过慢的问题,当然,代价就是PCA降维的精确度可能会降低。
使用SparsePCA和MiniBatchSparsePCA需要对L1正则化参数进行调参。
2.sklearn.decomposition.PCA
PCA类基本不需要调参,只需给出需要降维到的维度,或者希望降维后的主成分的方差和占原始维度所有特征方差和的比例阈值就可以了。
sklearn.decomposition.PCA的主要方法及其参数如下:
- PCA方法:新建一个pca对象时必用方法,主要参数有n_components:指定希望PCA降维后的特征维度数目,默认值为min(样本数,特征数),三种常用设置。
第一种,直接指定降维到的维度数,此时n_components是一个大于等于1的整数;
第二种,指定主成分的方差和所占的最小比例阈值,PCA类自己根据样本特征方差来决定降维到的维度数,此时n_components是一个(0,1]之间的小数;
第三种,设置为"mle", 此时PCA类会用MLE算法根据特征的方差分布情况自己去选择一定数量的主成分特征来降维。
copy:类型:bool,默认为True。表示是否在运行算法时,将原始训练数据复制一份。若为True,则在原始数据的副本上运行PCA算法,原始训练数据的值不会有任何改变;若为False,在原始数据上运行PCA算法,原始训练数据的值会改。
whiten :判断是否进行白化。默认值是False,即不进行白化。所谓白化,就是对降维后的数据的每个特征进行归一化,让方差都为1。对于PCA降维本身来说,一般不需要白化。如果降维后有后续的数据处理动作,可以考虑白化。
svd_solver:即指定奇异值分解SVD的方法,由于特征分解是奇异值分解SVD的一个特例,一般的PCA库都是基于SVD实现的。有4个可以选择的值:{‘auto’, ‘full’, ‘arpack’, ‘randomized’}。randomized一般适用于数据量大,数据维度多同时主成分数目比例又较低的PCA降维,它使用了一些加快SVD的随机算法。 full则是传统意义上的SVD,使用了scipy库对应的实现。arpack和randomized的适用场景类似,区别是randomized使用的是scikit-learn自己的SVD实现,而arpack直接使用了scipy库的sparse SVD实现。默认是auto,即PCA类会自己去在前面讲到的三种算法里面去权衡,选择一个合适的SVD算法来降维。一般来说,使用默认值就够了。
- fit_transform()方法,传入的参数为需要降维的numpy.ndarray数组,并返回降维后的数据,降维后的数据与原数据不可能一一对应,比如一个4维的数据,降到2维后,这里的2维并不是原来4维中的某2个维度,而是4个维度综合起来得到的2个维度。
- inverse_transform()方法,传入的参数为降维后的数据,返回原始数据,很多时候转换回去的原始数据都有偏差。
- explained_variance_方法,返回主成分的贡献率,代表降维后的各主成分的方差贡献绝对值。方差值越大,越是重要的主成分。
- explained_variance_ratio_方法,返回降维后的各主成分的方差贡献占比,比例越大,越是重要的主成分。
3.实例
本代码基于python3.7,编译器是pycharm,亲测没问题。
import numpy as np
from sklearn.decomposition import PCA
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
pca = PCA(n_components=1)
newX = pca.fit_transform(X)
invX = pca.inverse_transform(newX)
print(X)
print(newX)
print(invX)
print(pca.explained_variance_ratio_)
运行结果:
print(X):原数据
[[-1 -1]
[-2 -1]
[-3 -2]
[ 1 1]
[ 2 1]
[ 3 2]]
print(newX):降维后的数据
[[ 1.38340578]
[ 2.22189802]
[ 3.6053038 ]
[-1.38340578]
[-2.22189802]
[-3.6053038 ]]
print(invX):将降维后的数据转换成原数据,有偏差
[[-1.15997501 -0.75383654]
[-1.86304424 -1.21074232]
[-3.02301925 -1.96457886]
[ 1.15997501 0.75383654]
[ 1.86304424 1.21074232]
[ 3.02301925 1.96457886]]
print(pca.explained_variance_ratio_):主成分方差贡献比,99%的占比表示这1个维度就可以很好的代表原来的高维度数据
[0.99244289]
原理参考文章
代码参考文章