【问题标题】:Why does sklearn's PCA not return reproducible results? [duplicate]为什么 sklearn 的 PCA 不返回可重现的结果? [复制]
【发布时间】:2019-04-03 16:11:02
【问题描述】:

我正在使用scikit's PCA 并注意到一些非常奇怪的行为。本质上,当使用超过 500 个样本时,结果是不可重现的。这个例子展示了正在发生的事情:

import numpy as np
from sklearn.decomposition import PCA

Ncomp = 15
Nsamp = 501
Nfeat = 30

PCAnalyzer = PCA(n_components = Ncomp)
ManySamples = np.random.rand(Nsamp, Nfeat)
TestSample = np.ones((1, Nfeat))

print(PCAnalyzer.fit(ManySamples).transform(TestSample))
print(PCAnalyzer.fit(ManySamples).transform(TestSample))
print(PCAnalyzer.fit(ManySamples).transform(TestSample))
print(PCAnalyzer.fit(ManySamples).transform(TestSample))

它输出:

>>> print(PCAnalyzer.fit(ManySamples).transform(TestSample))
[[-0.25641111  0.42327221  0.4616427  -0.72047479 -0.12386481  0.10608497
   0.28739712 -0.26003239  1.27305465  1.05307604 -0.53915119 -0.07127874
   0.25312454 -0.12052255 -0.06738885]]
>>> print(PCAnalyzer.fit(ManySamples).transform(TestSample))
[[-0.26656397  0.42293446  0.45487161 -0.7339531  -0.16134778  0.15389179
   0.27052166 -0.33565591  1.26289845  0.96118269  0.5362569  -0.54688338
   0.08329318 -0.08423136 -0.00253318]]
>>> print(PCAnalyzer.fit(ManySamples).transform(TestSample))
[[-0.21899525  0.38527988  0.45101669 -0.73443888 -0.20501978  0.09640448
   0.17826649 -0.37653009  1.04856884  1.10948052  0.60700417 -0.39864793
   0.18020651  0.08061955  0.05383696]]
>>> print(PCAnalyzer.fit(ManySamples).transform(TestSample))
[[-0.27070256  0.41532602  0.45936926 -0.73820121 -0.18160026 -0.13139435
   0.28015907 -0.28144421  1.16554587  1.00472104  0.16983399 -0.67157762
  -0.3005816   0.54645421  0.09807374]]

将样本数 (Nsamp) 减少到 500 个或更少,或将组件数 (Ncomp) 增加到 20 个或更多,可以解决问题 - 但这对我来说并不实用。

【问题讨论】:

    标签: python scikit-learn pca


    【解决方案1】:

    这是因为sklearn 使用的默认求解器。来自docs

    求解器由基于 X.shape 和 n_components 的默认策略选择:如果输入数据大于 500x500 并且要提取的组件数低于数据最小维度的 80%,则越多启用有效的“随机”方法。否则,将计算精确的完整 SVD,然后可以选择截断。

    如果您需要可重现的结果,请使用不同的求解器,或设置 random_state

    【讨论】:

      【解决方案2】:

      有时,阅读文档会有所帮助:

      它使用完整 SVD 的 LAPACK 实现或通过 Halko 等人的方法随机截断的 SVD。 2009,取决于输入数据的形状和要提取的组件数量。

      这解决了问题:

      PCAnalyzer = PCA(n_components = Ncomp, svd_solver = 'full')
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-23
        • 2021-12-08
        • 2018-05-06
        • 2021-09-03
        • 2016-03-31
        • 2014-11-19
        • 1970-01-01
        相关资源
        最近更新 更多