我在Matlab中有一个75x60阵列。我正在尝试做PCA。我试图通过确保eig(矩阵)返回的最大特征值与[u d v] = svd(矩阵)中的d(1)* d(1)返回相同的东西来检查我的工作。他们疯狂了。唯一可以看出可能出错的是贬低。
以下是我处理贬低的方式:
%v is a 75x60 array
%rowS is 75
avgVector= mean(v,1);
muMatrix = repmat(avgVector,rowS,1);
v = v-muMatrix;
如果我打电话给SVD(v),它将返回与eig(cov(v))极不相同的值,无论v是否经历了上述贬低。
答案 0 :(得分:2)
如果您的矩阵遵循标准Matlab约定,变量是列,而样本是行,那么您的方法基本上是
v = v - repmat(mean(v, 1), size(v, 1), 1);
是对的。虽然不会将手段炸成全尺寸矩阵,但它的内存效率会更高:
v = bsxfun(@minus, v, mean(v, 1));
还可以使用
v = detrend(v, 'constant')
在内部使用以前的代码。
问题出在其他地方:v
的{{3}}是v'*v
的特征值的平方根。如果v
无均值,则v'*v
(在本例中称为“散点矩阵”)与(无偏估计)协方差矩阵cov(v)
- 相同因素 size(v, 1) - 1
。如果您使用代码
[V, D] = eig(cov(v));
[U, S, V] = svd(bsxfun(@minus, v, mean(v, 1)));
你会发现
sort(diag(D), 'descend')
和
diag(S) .^ 2 / (size(x, 1) - 1)
与舍入误差完全相同。额外的sort
是必要的,因为eig
不保证有序的特征值。