scikit-learn PCA:矩阵变换产生具有翻转符号的PC估计

Cla*_*lay 5 python pca scikit-learn

我正在使用scikit-learn在此数据集上执行PCA .scikit-learn文档说明了这一点

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

问题是我不认为我使用不同的估算器对象,但与SAS PROC PRINCOMP程序的结果相比,我的某些PC的迹象被翻转.

对于数据集中的第一次观察,SAS PC是:

PC1      PC2      PC3       PC4      PC5
2.0508   1.9600   -0.1663   0.2965   -0.0121
Run Code Online (Sandbox Code Playgroud)

从scikit-learn,我得到以下(其数量非常接近):

PC1      PC2      PC3       PC4      PC5
-2.0536  -1.9627  -0.1666   -0.297   -0.0122
Run Code Online (Sandbox Code Playgroud)

这是我正在做的事情:

import pandas as pd
import numpy  as np
from sklearn.decomposition.pca import PCA

sourcef = pd.read_csv('C:/mydata.csv')
frame = pd.DataFrame(sourcef)

# Some pandas evals, regressions, etc... that I'm not showing
# but not affecting the matrix

# Make sure we are working with the proper data -- drop the response variable
cols = [col for col in frame.columns if col not in ['response']]

# Separate out the data matrix from the response variable vector 
# into numpy arrays
frame2_X = frame[cols].values
frame2_y = frame['response'].values

# Standardize the values
X_means = np.mean(frame2_X,axis=0)
X_stds  = np.std(frame2_X,axis=0)

y_mean = np.mean(frame2_y)
y_std  = np.std(frame2_y)

frame2_X_stdz = np.copy(frame2_X)
frame2_y_stdz = frame2_y.astype(numpy.float32, copy=True)

for (x,y), value in np.ndenumerate(frame2_X_stdz):
    frame2_X_stdz[x][y] = (value - X_means[y])/X_stds[y]

for index, value in enumerate(frame2_y_stdz):
    frame2_y_stdz[index] = (float(value) - y_mean)/y_std

# Show the first 5 elements of the standardized values, to verify
print frame2_X_stdz[:,0][:5]

# Show the first 5 lines from the standardized response vector, to verify
print frame2_y_stdz[:5]
Run Code Online (Sandbox Code Playgroud)

那些结账可以:

[ 0.9508 -0.5847 -0.2797 -0.4039 -0.598 ]
[ 1.0726 -0.5009 -0.0942 -0.1187 -0.8043]
Run Code Online (Sandbox Code Playgroud)

继续......

# Create a PCA object
pca = PCA()
pca.fit(frame2_X_stdz)

# Create the matrix of PC estimates
pca.transform(frame2_X_stdz)
Run Code Online (Sandbox Code Playgroud)

这是最后一步的输出:

Out[16]: array([[-2.0536, -1.9627, -0.1666, -0.297 , -0.0122],
       [ 1.382 , -0.382 , -0.5692, -0.0257, -0.0509],
       [ 0.4342,  0.611 ,  0.2701,  0.062 , -0.011 ],
       ..., 
       [ 0.0422,  0.7251, -0.1926,  0.0089,  0.0005],
       [ 1.4502, -0.7115, -0.0733,  0.0013, -0.0557],
       [ 0.258 ,  0.3684,  0.1873,  0.0403,  0.0042]])
Run Code Online (Sandbox Code Playgroud)

我通过替换pca.fit()pca.transform()使用它来尝试它pca.fit_transform(),但我最终得到了相同的结果.

我在这里做错了,我正在拿着标牌翻转的电脑?

gon*_*opp 5

你没有做错任何事.

文档警告你的是,重复调用fit可能产生不同的主要组件 - 而不是它们与另一个PCA实现的关系.

在所有组件上都有一个翻转符号不会导致结果错误 - 只要符合定义,结果就是正确的(选择每个组件以便捕获数据中的最大差异量).就目前而言,您所获得的投影似乎只是镜像 - 它仍然符合定义,因此是正确的.

如果在正确性之下,您担心实现之间的一致性,则可以在必要时简单地将组件乘以-1.