我正在训练做python的MNIST的PCA重建,并将它们与我在maltab中的(旧)重建进行比较,我偶然发现我的重建不同意。经过一番调试,我决定打印每个主要组件的独特特征,以显示它们是否相同,并且我发现我的惊讶发现它们是而不是相同。我打印所有组件的总和,并得到不同的数字。我做了MATLAB中的以下内容:为什么Scipy和MATLAB的主成分值不一致?
[coeff, ~, ~, ~, ~, mu] = pca(X_train);
U = coeff(:,1:K)
U_fingerprint = sum(U(:))
%print 31.0244
和在Python/SciPy的:
pca = pca.fit(X_train)
U = pca.components_
print 'U_fingerprint', np.sum(U)
# prints 12.814
为什么在TWI PCA不是计算相同的值?
我所有的尝试和解决这个问题:
我发现,这是因为当我重建我的MNIST图像的方式,蟒蛇重建那里受到了很多非常非常接近他们的原始图像。我在Python中遇到了0.0221556788645
的错误,而在MATLAB中我得到了尺寸为29.07578
的错误。为了找出差异来自哪里,我决定手指打印数据集(也许它们是以不同方式归一化的)。所以,我有两个独立的副本MNIST数据集(即是通过把我的255标准化),并得到了指纹(汇总数据集中的所有号码):
print np.sum(x_train) # from keras
print np.sum(X_train)+np.sum(X_cv) # from TensorFlow
6.14628e+06
6146269.1585420668
这是(基本上)相同的(一个来自副本张量流MNIST,另一个来自Keras MNIST,注意MNIST训练数据集有大约1000个训练集,所以你需要追加缺少的训练集)。令我惊讶的是,我的MATLAB数据有相同指纹:
data_fingerprint = sum(X_train(:))
% prints data_fingerprint = 6.1463e+06
意味着数据集正是相同。好,所以规范化数据不是问题。
在我的MATLAB脚本其实我手工计算重建如下:
U = coeff(:,1:K)
X_tilde_train = (U * U' * X_train);
train_error_PCA = (1/N_train)*norm(X_tilde_train - X_train ,'fro')^2
%train_error_PCA = 29.0759
,所以我想是因为我用的是接口蟒蛇可能是问题了用于计算重建为:
pca = PCA(n_components=k)
pca = pca.fit(X_train)
X_pca = pca.transform(X_train) # M_train x K
#print 'X_pca' , X_pca.shape
X_reconstruct = pca.inverse_transform(X_pca)
print 'tensorflow error: ',(1.0/X_train.shape[0])*LA.norm(X_reconstruct_tf - X_train)
print 'keras error: ',(1.0/x_train.shape[0])*LA.norm(X_reconstruct_keras - x_train)
#tensorflow error: 0.0221556788645
#keras error: 0.0212030354818
这导致不同的误差值0.022 vs 29.07,令人震惊的差异!
因此,我决定在我的Python脚本代码,精确重建式:
pca = PCA(n_components=k)
pca = pca.fit(X_train)
U = pca.components_
print 'U_fingerprint', np.sum(U)
X_my_reconstruct = np.dot( U.T , np.dot(U, X_train.T))
print 'U error: ',(1.0/X_train.shape[0])*LA.norm(X_reconstruct_tf - X_train)
# U error: 0.0221556788645
想不到,它通过使用该接口具有相同的错误作为我MNIST误差计算。因此,得出结论我不认为我有我的PCA的误解。
所有这些都导致我检查主要组件的实际位置以及令我惊讶的scipy和MATLAB的PCA值有不同的指纹。
有谁知道为什么或什么事情发生?
沃伦建议,在PCA分量(特征向量)可能有不同的标志。在幅度将所有组件做一个指纹后只有我发现它们具有相同的指纹:
[coeff, ~, ~, ~, ~, mu] = pca(X_train);
K=12;
U = coeff(:,1:K)
U_fingerprint = sumabs(U(:))
% U_fingerprint = 190.8430
和蟒蛇:
k=12
pca = PCA(n_components=k)
pca = pca.fit(X_train)
print 'U_fingerprint', np.sum(np.absolute(U))
# U_fingerprint 190.843
这意味着差必须因(pca)U矢量的不同符号。我觉得这很令人惊讶,我认为这应该会有很大的变化,我甚至没有考虑到它会产生很大的变化。我猜我错了?
两个版本有多少个组件会返回?比较文件,这可能是一个可能解释观察到的行为的差异点。 – rubenvb
@rubenvb他们都是12(显然是相同的,否则这将是愚蠢的错误,我将在明天早上提供github代码以供人们判断脚本)。 –
在MATLAB变量是列市长和在python行市长。确保你没有计算转置矩阵中的PCA。 –