【发布时间】:2021-08-28 14:07:47
【问题描述】:
我尝试使用“machine learning in action”中提供的PCA,但发现它得到的结果与sklearn中的PCA得到的结果不一样。我不太明白这是怎么回事。
下面是我的代码:
import numpy as np
from sklearn.decomposition import PCA
x = np.array([
[1,2,3,4,5, 0],
[0.6,0.7,0.8,0.9,0.10, 0],
[110,120,130,140,150, 0]
])
def my_pca(data, dim):
remove_mean = data - data.mean(axis=0)
cov_data = np.cov(remove_mean, rowvar=0)
eig_val, eig_vec = np.linalg.eig(np.mat(cov_data))
sorted_eig_val = np.argsort(eig_val)
eig_index = sorted_eig_val[:-(dim+1):-1]
transfer = eig_vec[:,eig_index]
low_dim = remove_mean * transfer
return np.array(low_dim, dtype=float)
pca = PCA(n_components = 3)
pca.fit(x)
new_x = pca.transform(x)
print("sklearn")
print(new_x)
new_x = my_pca(x, 3)
print("my")
print(new_x)
输出:
sklearn
[[-9.32494230e+01 1.46120285e+00 2.37676120e-15]
[-9.89004904e+01 -1.43283197e+00 2.98143675e-14]
[ 1.92149913e+02 -2.83708789e-02 2.81307176e-15]]
my
[[ 9.32494230e+01 -1.46120285e+00 7.39333927e-14]
[ 9.89004904e+01 1.43283197e+00 -7.01760428e-14]
[-1.92149913e+02 2.83708789e-02 1.84375626e-14]]
【问题讨论】:
-
我认为您的 PCA 实施没有任何问题。我认为第三列中的数字刚好接近浮点精度的限制。即使我只将 sklearn 结果与您的结果进行比较,我在系统上得到的值也与这些值不同。
-
您的两个解决方案几乎相同 (
np.allclose(first * -1, second))。 -
顺便说一句,在某些情况下,PCA 对数值非常敏感,甚至会给出一些输出轴看起来完全随机的投影。如果
x @ x.t(数据云的最大方差轴)的两个(或更多)特征向量具有彼此非常接近的对应特征值,则它们跨越惯性各向同性的子空间:惯性椭圆体是圆形的(或球形)在这些轴跨越的超平面中。这些轴的任何旋转都是等效的。当仅一个点的采样差异产生不同的 PCA 输出时,我经常发现人们感到惊讶。
标签: python numpy scikit-learn pca