• 在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]]
  • 相关阅读:
    C++ Primer学习笔记(三) C++中函数是一种类型!!!
    C++类的成员函数的形参列表后面的const
    C++ const总结
    简单的使用Gson (序列化 和 反序化)
    HTML 获取class里的多个值 和 dataset的使用
    SiteMesh的简单使用
    IDEA 使用LiveEdit插件
    Java 转发和重定向的区别
    Web.xml 定制URL
    java 枚举类(简单使用)
  • 原文地址:https://www.cnblogs.com/okokok/p/6822885.html
Copyright © 2020-2023  润新知