【问题标题】:Linear Discriminant Analysis inverse transform线性判别分析逆变换
【发布时间】:2017-08-14 22:33:34
【问题描述】:

我尝试使用 scikit-learn 库中的 Linear Discriminant Analysis,以便对具有 200 多个特征的数据执行降维。但是我在 LDA 类中找不到inverse_transform 函数。

我只是想问一下,如何从 LDA 域中的一个点重建原始数据?

根据@bogatron 和@kazemakase 回答编辑:

我认为“原始数据”一词是错误的,我应该使用“原始坐标”或“原始空间”。我知道如果没有所有 PCA,我们将无法重建 原始数据,但是当我们构建形状空间时,我们会在 PCA 的帮助下将数据向下投影到较低维度。 PCA 尝试仅使用 2 或 3 个组件来解释数据,这些组件可以捕获数据的大部分方差,如果我们根据它们重建数据库,它应该向我们展示导致这种分离的形状部分。

我再次检查了 scikit-learn LDA 的源代码,发现特征向量存储在 scalings_ 变量中。当我们使用svd求解器时,不可能对特征向量(scalings_)矩阵求逆,但是当我尝试矩阵的伪逆时,我可以重建形状。

这里有两幅图像分别从 [4.28, 0.52] 和 [0, 0] 点重建:

我认为,如果有人深入解释 LDA 逆变换的数学限制,那就太好了。

【问题讨论】:

    标签: python machine-learning scikit-learn dimensionality-reduction


    【解决方案1】:

    LDA 的逆不一定有意义,因为它丢失了很多信息。

    为了比较,请考虑 PCA。在这里,我们得到一个用于转换数据的系数矩阵。我们可以通过从矩阵中剥离行来进行降维。为了得到逆变换,我们首先反转整个矩阵,然后删除对应于被删除行的列。

    LDA 没有给我们一个完整的矩阵。我们只得到一个不能直接反转的简化矩阵。可以采用伪逆,但这比使用完整矩阵时效率要低得多。

    考虑一个简单的例子:

    C = np.ones((3, 3)) + np.eye(3)  # full transform matrix
    U = C[:2, :]  # dimensionality reduction matrix
    V1 = np.linalg.inv(C)[:, :2]  # PCA-style reconstruction matrix
    print(V1)
    #array([[ 0.75, -0.25],
    #       [-0.25,  0.75],
    #       [-0.25, -0.25]])
    
    V2 = np.linalg.pinv(U)  # LDA-style reconstruction matrix
    print(V2)
    #array([[ 0.63636364, -0.36363636],
    #       [-0.36363636,  0.63636364],
    #       [ 0.09090909,  0.09090909]])
    

    如果我们有完整的矩阵,我们会得到一个不同的逆变换 (V1),而不是我们简单地逆变换 (V2)。 这是因为在第二种情况下,我们丢失了有关废弃组件的所有信息。

    您已被警告。如果你仍然想做逆 LDA 变换,这里有一个函数:

    import matplotlib.pyplot as plt
    
    from sklearn import datasets
    from sklearn.decomposition import PCA
    from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
    
    from sklearn.utils.validation import check_is_fitted
    from sklearn.utils import check_array, check_X_y
    
    import numpy as np
    
    
    def inverse_transform(lda, x):
        if lda.solver == 'lsqr':
            raise NotImplementedError("(inverse) transform not implemented for 'lsqr' "
                                      "solver (use 'svd' or 'eigen').")
        check_is_fitted(lda, ['xbar_', 'scalings_'], all_or_any=any)
    
        inv = np.linalg.pinv(lda.scalings_)
    
        x = check_array(x)
        if lda.solver == 'svd':
            x_back = np.dot(x, inv) + lda.xbar_
        elif lda.solver == 'eigen':
            x_back = np.dot(x, inv)
    
        return x_back
    
    
    iris = datasets.load_iris()
    
    X = iris.data
    y = iris.target
    target_names = iris.target_names
    
    lda = LinearDiscriminantAnalysis()
    Z = lda.fit(X, y).transform(X)
    
    Xr = inverse_transform(lda, Z)
    
    # plot first two dimensions of original and reconstructed data
    plt.plot(X[:, 0], X[:, 1], '.', label='original')
    plt.plot(Xr[:, 0], Xr[:, 1], '.', label='reconstructed')
    plt.legend()
    

    您看,逆变换的结果与原始数据没有太大关系(好吧,可以猜测投影的方向)。相当一部分的变化已经消失了。

    【讨论】:

      【解决方案2】:

      没有逆变换,因为一般情况下,你不能从低维特征空间返回到你原来的坐标空间。

      把它想象成看你投射在墙上的二维阴影。您无法从单个阴影返回到 3 维几何图形,因为信息在投影过程中丢失。

      要解决您对 PCA 的评论,请考虑一个包含 10 个随机 3 维向量的数据集:

      In [1]: import numpy as np
      
      In [2]: from sklearn.decomposition import PCA
      
      In [3]: X = np.random.rand(30).reshape(10, 3)
      

      现在,如果我们应用主成分变换 (PCT) 并通过仅保留前 2 个(共 3 个)PC 来应用降维,然后应用逆变换,会发生什么?

      In [4]: pca = PCA(n_components=2)
      
      In [5]: pca.fit(X)
      Out[5]: 
      PCA(copy=True, iterated_power='auto', n_components=2, random_state=None,
        svd_solver='auto', tol=0.0, whiten=False)
      
      In [6]: Y = pca.transform(X)
      
      In [7]: X.shape
      Out[7]: (10, 3)
      
      In [8]: Y.shape
      Out[8]: (10, 2)
      
      In [9]: XX = pca.inverse_transform(Y)
      
      In [10]: X[0]
      Out[10]: array([ 0.95780971,  0.23739785,  0.06678655])
      
      In [11]: XX[0]
      Out[11]: array([ 0.87931369,  0.34958407, -0.01145125])
      

      显然,逆变换没有重构原始数据。原因是通过丢弃最低的 PC,我们丢失了信息。接下来,让我们看看如果我们保留所有个 PC(即,我们不应用任何降维)会发生什么:

      In [12]: pca2 = PCA(n_components=3)
      
      In [13]: pca2.fit(X)
      Out[13]: 
      PCA(copy=True, iterated_power='auto', n_components=3, random_state=None,
        svd_solver='auto', tol=0.0, whiten=False)
      
      In [14]: Y = pca2.transform(X)
      
      In [15]: XX = pca2.inverse_transform(Y)
      
      In [16]: X[0]
      Out[16]: array([ 0.95780971,  0.23739785,  0.06678655])
      
      In [17]: XX[0]
      Out[17]: array([ 0.95780971,  0.23739785,  0.06678655])
      

      在这种情况下,我们能够重建原始数据,因为我们没有丢弃任何信息(因为我们保留了所有 PC)。

      LDA 的情况更糟,因为可以保留的最大组件数不是 200(输入数据的特征数);相反,您可以保留的最大组件数是n_classes - 1。因此,例如,如果您正在处理二进制分类问题(2 个类别),则 LDA 转换将从 200 个输入维度下降到仅一个维度。

      【讨论】:

      • 不,这不是真的,一般来说是可以做到的!例如,您可以在执行 PCA PCA inverse_transform 后重建您的数据。
      • 只有在你不执行降维操作时才会这样。在您的问题中,您说“执行降维”。主成分变换只是坐标的移位(如果需要平均减法)和旋转,因此您可以应用反向旋转和移位来取回原始数据。但是如果你减少组件的数量,你会丢失信息(除了被丢弃的组件的方差为零的特殊情况),因此你将无法取回原始数据。
      • 我不知道你是否熟悉形状空间。基本上,您在 2D 或 3D 中选择一个点并在形状的原始空间中重建形状,这意味着仅使用 2 或 3 个主要成分(具有最多的数据变体)您可以猜测形状并且它不会不需要知道其余的组件。也许我应该使用“原始空间”而不是“原始数据”。
      • 不,我不熟悉形状空间,但我认为您是问题的核心,区分“原始空间”和“原始数据”。对于具有降维的 PCA,您可以返回原始空间,因为这只是将与逆变换中丢弃的特征值/向量相关的系数归零的问题。对于 LDA,您没有 200 维的变换空间,您可以在其中将系数归零以变换回原始空间。
      猜你喜欢
      • 2018-02-07
      • 2013-06-19
      • 2014-07-17
      • 2013-12-10
      • 2018-07-08
      • 2022-06-22
      • 2020-02-03
      • 2016-07-06
      • 1970-01-01
      相关资源
      最近更新 更多