【问题标题】:scikit-learn kernel PCA explained variancescikit-learn 内核 PCA 解释方差
【发布时间】:2015-06-19 03:33:22
【问题描述】:

我一直在使用来自 scikit-learn 的普通 PCA,并且没有任何问题地获得每个主成分的方差比。

pca = sklearn.decomposition.PCA(n_components=3)
pca_transform = pca.fit_transform(feature_vec)
var_values = pca.explained_variance_ratio_

我想使用内核 PCA 探索不同的内核,并且还想要解释的方差比,但我现在看到它没有这个属性。有谁知道如何获取这些值?

kpca = sklearn.decomposition.KernelPCA(kernel=kernel, n_components=3)
kpca_transform = pca.fit_transform(feature_vec)
var_values = kpca.explained_variance_ratio_

AttributeError: 'KernelPCA' 对象没有属性 'explained_variance_ratio_'

【问题讨论】:

    标签: python scikit-learn


    【解决方案1】:

    我知道这个问题很老,但是当我意识到pca.explained_variance_ 只是组件的方差时,我遇到了同样的“问题”并找到了一个简单的解决方案。您可以通过以下方式简单地计算解释的方差(和比率):

    kpca_transform = kpca.fit_transform(feature_vec)
    explained_variance = numpy.var(kpca_transform, axis=0)
    explained_variance_ratio = explained_variance / numpy.sum(explained_variance)
    

    作为奖励,获得解释方差的累积比例(通常用于选择组件和估计空间的维度):

    numpy.cumsum(explained_variance_ratio)
    

    【讨论】:

    • 很好的发现!只是一个简短的说明:这仅在您考虑 n-1 个组件时才有效。其中 n 是数据集中的特征数。
    • @yellow01 如果我考虑少于 n-1 个组件,为什么我没有收到错误消息?
    • 我认为这是不对的。我相信@Krishna Kalyan 是对的(答案如下)
    • 这个答案肯定是错误的,根本原因是:如果你在 KPCA 中给出 N 个分量,那么前 N 个分量不计入 100% 方差。但是您的代码只是给出了这样的结果。
    【解决方案2】:

    K-PCA 没有explained_variance_ratio_ 的主要原因是因为在内核转换后您的数据/向量存在于不同的特征空间中。因此,K-PCA 不应该像 PCA 那样被解释。

    【讨论】:

      【解决方案3】:

      我也对此很感兴趣,所以我做了一些测试。下面是我的代码。

      这些图将显示 kernelpca 的第一个组件是数据集的更好鉴别器。但是,当根据@EelkeSpaak 解释计算解释的方差比率时,我们看到只有 50% 的方差解释比率没有意义。因此,我倾向于同意@Krishna Kalyan 的解释。

      #get data
      from sklearn.datasets import make_moons 
      import numpy as np
      import matplotlib.pyplot as plt
      
      x, y = make_moons(n_samples=100, random_state=123)
      plt.scatter(x[y==0, 0], x[y==0, 1], color='red', marker='^', alpha=0.5)
      plt.scatter(x[y==1, 0], x[y==1, 1], color='blue', marker='o', alpha=0.5)
      plt.show()
      
      ##seeing effect of linear-pca-------
      from sklearn.decomposition import PCA
      pca = PCA(n_components=2)
      x_pca = pca.fit_transform(x)
      
      x_tx = x_pca
      fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(7,3))
      ax[0].scatter(x_tx[y==0, 0], x_tx[y==0, 1], color='red', marker='^', alpha=0.5)
      ax[0].scatter(x_tx[y==1, 0], x_tx[y==1, 1], color='blue', marker='o', alpha=0.5)
      ax[1].scatter(x_tx[y==0, 0], np.zeros((50,1))+0.02, color='red', marker='^', alpha=0.5)
      ax[1].scatter(x_tx[y==1, 0], np.zeros((50,1))-0.02, color='blue', marker='o', alpha=0.5)
      ax[0].set_xlabel('PC-1')
      ax[0].set_ylabel('PC-2')
      ax[0].set_ylim([-0.8,0.8])
      ax[1].set_ylim([-0.8,0.8])
      ax[1].set_yticks([])
      ax[1].set_xlabel('PC-1')
      plt.show()
      
      ##seeing effect of kernelized-pca------
      from sklearn.decomposition import KernelPCA
      kpca = KernelPCA(n_components=2, kernel='rbf', gamma=15)
      x_kpca = kpca.fit_transform(x)
      
      
      x_tx = x_kpca
      fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(7,3))
      ax[0].scatter(x_tx[y==0, 0], x_tx[y==0, 1], color='red', marker='^', alpha=0.5)
      ax[0].scatter(x_tx[y==1, 0], x_tx[y==1, 1], color='blue', marker='o', alpha=0.5)
      ax[1].scatter(x_tx[y==0, 0], np.zeros((50,1))+0.02, color='red', marker='^', alpha=0.5)
      ax[1].scatter(x_tx[y==1, 0], np.zeros((50,1))-0.02, color='blue', marker='o', alpha=0.5)
      ax[0].set_xlabel('PC-1')
      ax[0].set_ylabel('PC-2')
      ax[0].set_ylim([-0.8,0.8])
      ax[1].set_ylim([-0.8,0.8])
      ax[1].set_yticks([])
      ax[1].set_xlabel('PC-1')
      plt.show()
      
      ##comparing the 2 pcas-------
      
      #get the transformer
      tx_pca = pca.fit(x)
      tx_kpca = kpca.fit(x)
      
      #transform the original data
      x_pca = tx_pca.transform(x)
      x_kpca = tx_kpca.transform(x)
      
      #for the transformed data, get the explained variances
      expl_var_pca = np.var(x_pca, axis=0)
      expl_var_kpca = np.var(x_kpca, axis=0)
      print('explained variance pca: ', expl_var_pca)
      print('explained variance kpca: ', expl_var_kpca)
      
      expl_var_ratio_pca = expl_var_pca / np.sum(expl_var_pca)
      expl_var_ratio_kpca = expl_var_kpca / np.sum(expl_var_kpca)
      
      print('explained variance ratio pca: ', expl_var_ratio_pca)
      print('explained variance ratio kpca: ', expl_var_ratio_kpca)
      

      【讨论】:

      • 将图添加到答案中
      • 这是 SO 中需要的证明类型!
      【解决方案4】:

      使用特征值,它会提供您需要的类似信息和直觉:

      pca = KernelPCA(n_components=30, kernel="rbf")
      pca.fit(x)
      var_values = pca.eigenvalues_ / sum(pca.eigenvalues_)
      print(sum(var_values))
      plt.plot(np.arange(1, pca.n_components + 1), var_values, "+", linewidth=2)
      plt.ylabel("PCA explained variance ratio")
      plt.show()
      

      【讨论】:

        猜你喜欢
        • 2019-12-09
        • 2020-11-23
        • 1970-01-01
        • 2017-09-30
        • 2016-05-19
        • 2013-11-24
        • 2013-02-28
        • 2017-09-07
        相关资源
        最近更新 更多