在SCIKIT中做PCA 逆变换 -- 新旧特征转换
PCA(Principal Component Analysis)是一种常用的数据分析方法。PCA通过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降维。
在Scikit中运用PCA很简单:
import numpy as np from sklearn import decomposition from sklearn import datasets iris = datasets.load_iris() X = iris.data y = iris.target pca = decomposition.PCA(n_components=3) pca.fit(X) X = pca.transform(X)
以上代码是将含有4个特征的数据经过PCA压缩为3个特征。PCA的压缩由如下特点:
- 新的3个特征并不是随便删除一个特征后留下的,而是4个特征的线性组合。
- 新的3个特征保留了原有4个特征的绝大部分信息,换句话说就是略有损失。
那么PCA的损失到底是什么? 新特征能否转回旧特征?
这要从PCA过程说起,我把过程缩减如下,毕竟本文重点不是说PCA过程:
PCA过程
1.均值化矩阵X
2.通过一系列矩阵运算得出 特征矩阵P
3.矩阵运算 Y = P * X
Y 即为原始数据降维后的结果,也就是说,得到矩阵P后,我们还可以通过Y=P * X这个算式, 反推回X:
Y = P * X ==> P(-1) * Y = P(-1) * P * X, P(-1)是P的逆矩阵, 即 P(-1) * P = 1
==> P(-1) * Y = X
需要注意的是,程序一开始就已经将原始数据均值化,所以实际上, P(-1)*Y的结果需要去均值化才是原来的样子
在Scikit中,pca.components_就是P的逆矩阵. 从源代码就可以看出(行号33)
1 def transform(self, X, y=None): 2 """Apply dimensionality reduction to X. 3 4 X is projected on the first principal components previously extracted 5 from a training set. 6 7 Parameters 8 ---------- 9 X : array-like, shape (n_samples, n_features) 10 New data, where n_samples is the number of samples 11 and n_features is the number of features. 12 13 Returns 14 ------- 15 X_new : array-like, shape (n_samples, n_components) 16 17 Examples 18 -------- 19 20 >>> import numpy as np 21 >>> from sklearn.decomposition import IncrementalPCA 22 >>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]]) 23 >>> ipca = IncrementalPCA(n_components=2, batch_size=3) 24 >>> ipca.fit(X) 25 IncrementalPCA(batch_size=3, copy=True, n_components=2, whiten=False) 26 >>> ipca.transform(X) # doctest: +SKIP 27 """ 28 check_is_fitted(self, ['mean_', 'components_'], all_or_any=all) 29 print self.mean_ 30 X = check_array(X) 31 if self.mean_ is not None: 32 X = X - self.mean_ 33 X_transformed = fast_dot(X, self.components_.T) 34 if self.whiten: 35 X_transformed /= np.sqrt(self.explained_variance_) 36 return X_transformed
回到开头的压缩代码增加一些输出语句:
iris = datasets.load_iris() X = iris.data y = iris.target print X[0] pca = decomposition.PCA(n_components=3) pca.fit(X) X = pca.transform(X) a = np.matrix(X) b = np.matrix(pca.components_) c = a * b mean_of_data = np.matrix([5.84333333, 3.054, 3.75866667, 1.19866667]) print c[0] print c[0] + mean_of_data
程序打印出原始数据中的第一行,然后将降维后的数据乘上特征矩阵的逆矩阵,加上均值还原回原来的4特征。
输出如下:
1 [ 5.1 3.5 1.4 0.2] 2 3 [[-0.74365254 0.44632609 -2.35818399 -0.99942241]] 4 5 [[ 5.09968079 3.50032609 1.40048268 0.19924426]]
由此可看, 经还原后的特征值(行号5)和原来(行号1)相比,每一个特征都略有变化。
如果维度不降,我们可以再看看结果
pca = decomposition.PCA(n_components=4) pca.fit(X) X = pca.transform(X) a = np.matrix(X) b = np.matrix(pca.components_) c = a * b mean_of_data = np.matrix([5.84333333, 3.054, 3.75866667, 1.19866667]) print c[0] print c[0] + mean_of_data
完美还原:
1 [ 5.1 3.5 1.4 0.2] 2 3 [[-0.74333333 0.446 -2.35866667 -0.99866667]] 4 5 [[ 5.1 3.5 1.4 0.2]]