I am using 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或更多,可以解决此问题-但这对我来说不切实际。
答案 0 :(得分:2)
这是由于sklearn
使用的默认求解器。来自docs:
通过基于X.shape和n_components的默认策略选择求解器:如果输入数据大于500x500,并且要提取的组件数小于数据最小维度的80%,则该数量更多启用了有效的“随机化”方法。否则,将计算出精确的完整SVD,然后选择截断。
如果需要可重复的结果,请使用其他求解器,或设置random_state
答案 1 :(得分:0)
有时候,阅读文档会有所帮助:
它通过Halko等人的方法使用完整SVD或随机截短SVD的LAPACK实现。 2009,具体取决于输入数据的形状和要提取的组件数。
这解决了这个问题:
PCAnalyzer = PCA(n_components = Ncomp, svd_solver = 'full')