【问题标题】:scikit KernelPCA unstable resultsscikit KernelPCA 结果不稳定
【发布时间】:2015-09-19 07:23:27
【问题描述】:

我正在尝试使用 KernelPCA 将数据集的维度减少到 2D(用于可视化目的和进一步的数据分析)。

我尝试在不同的 Gamma 值下使用 RBF 内核计算 KernelPCA,但结果不稳定:

(每一帧是一个略有不同的Gamma值,其中Gamma从0到1连续变化)

看起来它不是确定性的。

有没有办法稳定它/使其具有确定性?

用于生成转换数据的代码:

def pca(X, gamma1):
    kpca = KernelPCA(kernel="rbf", fit_inverse_transform=True, gamma=gamma1)
    X_kpca = kpca.fit_transform(X)
    #X_back = kpca.inverse_transform(X_kpca)
    return X_kpca

【问题讨论】:

    标签: python scikit-learn pca dimensionality-reduction


    【解决方案1】:

    KernelPCA 应该是确定性的,并且随着 gamma 不断发展。
    它与 RBFSampler 不同,它确实具有内置随机性,以便提供 RBF 内核的有效(更可扩展)近似。

    然而,在 KernelPCA 中可以改变的是 主成分的顺序:在 scikit-learn 中,它们按特征值降序排序返回,所以如果你有 2 个特征值彼此接近,它可以是顺序随伽玛变化。

    我的猜测(来自 gif)是这里正在发生的事情:您绘制的轴不是恒定的,因此您的数据似乎在跳跃。

    你能提供你用来制作 gif 的代码吗?

    我猜它是沿 2 个第一个主成分绘制的数据点图,但它有助于了解您是如何生成它的。

    您可以尝试通过查看每个 gamma 值的 kpca.alphas_(特征向量)的值来进一步检查它。

    希望这是有道理的。

    编辑:正如您所指出的,这些点看起来像轴上的反射,最合理的解释是特征向量之一翻转符号(注意这不会影响特征值)。

    我输入了a simple gist 来重现该问题(您需要一个 Jupyter 笔记本来运行它)。更改 gamma 值时可以看到符号翻转。

    作为补充说明,这种差异的发生只是因为您多次拟合 KernelPCA 对象多次。一旦您确定了一个特定的伽玛值并且您已经适合 kpca 一次,您可以多次调用 transform 并获得一致的结果。 对于经典的 PCA the docs,请提及:

    由于在此实现中使用的奇异值分解 (SVD) 的实现微妙,在同一矩阵上运行两次拟合可能会导致主成分的符号翻转(方向改变)。因此,始终使用相同的估算器对象以一致的方式转换数据非常重要。

    我不知道您可以多次拟合的单个 KernelPCA 对象的行为(我在文档中没有找到任何相关内容)。

    它不适用于您的情况,因为您必须使用多个伽玛值来拟合对象。

    【讨论】:

    • 是的,情节是前两个主成分
    • 好的。你看到组件的顺序如何影响你的情节吗?假设您的前 2 个组件是 e1 和 e2,具有关联的特征值 a1 和 a2。对于 gamma = 0.5,a1 > a2。所以 KernelPCA 按 e1、e2、e3 的顺序返回特征向量...对于 gamma = 0.6,a2 > a1。现在你得到 e2、e1、e3... 并且你在绘图上的轴被交换了。
    • 看起来更像是特征值翻转符号。如果交换轴(x 和 y),我应该观察点 transpose。取而代之的是 x 或 y 中的点反射。你不同意吗?
    • 是的,我有点同意你的观点;)。我们确实看到了一些看起来像反射的东西(实际上我看到了 2 个不同的反射)。然而负特征值在 PCA 中不是一个选项,因此我宁愿自欺欺人并相信它是一个转置......你能给我们每个阶段的特征向量/特征值(分别为 kpca.alphas_ 和 kpca.lambdas_)吗?
    • 好吧,你对符号翻转的看法是对的,但翻转符号的不是 eigenvalues。它只是改变为 - 1 * 本身的特征向量。
    【解决方案2】:

    所以...我无法明确回答为什么 KernelPCA 不是确定性的。这种行为类似于我在 PCA 和 RandomizedPCA 的结果之间观察到的差异。 PCA 是确定性的,但 RandomizedPCA 不是,并且有时特征向量相对于 PCA 特征向量的符号翻转。

    这使我对如何获得更多确定性结果产生了模糊的想法……也许。使用带有固定种子的RBFSampler:

    def pca(X, gamma1):
        kernvals = RBFSampler(gamma=gamma1, random_state=0).fit_transform(X)
        kpca = PCA().fit_transform(X)
        X_kpca = kpca.fit_transform(X)
        return X_kpca
    

    【讨论】:

      猜你喜欢
      • 2013-12-07
      • 1970-01-01
      • 2014-10-19
      • 2018-03-17
      • 2018-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多