在scikitlearn中PCA function的文档中,默认情况下copy
参数为True
。
文件说明了这个论点:
If False, data passed to fit are overwritten and running fit(X).transform(X) will not yield the expected results, use fit_transform(X) instead.
我不确定这是什么意思,因为该函数将如何覆盖输入X
?当你调用.fit(X)
时,该函数应该只是计算PCA向量并更新PCA对象的内部状态,对吧?
因此,即使您将副本设置为False
,.fit(X)
函数仍应按照文档中的说明返回对象self,那么fit(X).transform(X)
是否仍然可以正常工作?
那么当这个参数设置为False
时会复制什么?
此外,我何时才想将其设置为False
?
编辑: 我将fit和transform函数一起分开运行并获得了不同的结果,即使copy参数对于两者都是相同的。
from sklearn.decomposition import PCA
import numpy as np
X = np.arange(20).reshape((5,4))
print("Separate")
XT = X.copy()
pcaT = PCA(n_components=2, copy=True)
print("Original: ", XT)
results = pcaT.fit(XT).transform(XT)
print("New: ", XT)
print("Results: ", results)
print("\nCombined")
XF = X.copy()
pcaF = PCA(n_components=2, copy=True)
print("Original: ", XF)
results = pcaF.fit_transform(XF)
print("New: ", XF)
print("Results: ", results)
########## Results
Separate
Original: [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]]
New: [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]]
Results: [[ 1.60000000e+01 -2.66453526e-15]
[ 8.00000000e+00 -1.33226763e-15]
[ 0.00000000e+00 0.00000000e+00]
[ -8.00000000e+00 1.33226763e-15]
[ -1.60000000e+01 2.66453526e-15]]
Combined
Original: [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]]
New: [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]]
Results: [[ 1.60000000e+01 1.44100598e-15]
[ 8.00000000e+00 -4.80335326e-16]
[ -0.00000000e+00 0.00000000e+00]
[ -8.00000000e+00 4.80335326e-16]
[ -1.60000000e+01 9.60670651e-16]]
答案 0 :(得分:4)
在您的示例中,copy
的值最终会被忽略,如下所述。但是如果你把它设置为False会发生什么:
X = np.arange(20).reshape((5,4)).astype(np.float64)
print(X)
pca = PCA(n_components=2, copy=False).fit(X)
print(X)
这会打印原始X
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[ 12. 13. 14. 15.]
[ 16. 17. 18. 19.]]
然后显示X被fit
方法突变。
[[-8. -8. -8. -8.]
[-4. -4. -4. -4.]
[ 0. 0. 0. 0.]
[ 4. 4. 4. 4.]
[ 8. 8. 8. 8.]]
罪魁祸首是this line:X -= self.mean_
,其中augmented assignment mutates the array。
如果设置copy = True,这是默认值,则X不会发生变异。
为什么copy
没有对您的示例产生影响? PCA.fit方法对copy
的值唯一做的就是将它传递给实用函数check_array
,它被调用以确保数据矩阵的数据类型为float32或float64。如果数据类型不是其中之一,则会发生类型转换,并且无论如何都会创建副本(在您的示例中,存在从int到float的转换)。这就是为什么在我上面的例子中我将X作为一个浮点数组。
fit().transform()
和fit_transform()
您还问过为什么fit(X).transform(X)
和fit_transform(X)
会返回略有不同的结果。这与copy
参数无关。差异在于双精度算术的误差范围内。它来自以下内容:
fit
执行SVD为X = U @ S @ V.T
(其中@表示矩阵乘法)并将V存储在components_
属性中。 transform
将数据乘以V
fit_transform
执行与fit
相同的SVD,然后返回U @ S
数学上,U @ S
与X @ V
相同,因为V是正交矩阵。但是浮点运算的误差导致了微小的差异。
fit_transform
执行U @ S
代替X @ V
是有道理的;这是一个更简单,更准确的乘法,因为S
是对角线。 fit
不相同的原因是只存储了V
,并且在任何情况下它都不知道它获得的参数与模型到达的{{1}相同}。