我使用Matlab执行大量迭代,使用偏最小二乘法(PLS)作为每次迭代中处理数据的算法。它运行得很慢。使用profile
来监控每行代码所用的时间,显示行X = X-t*p'
,其中X
是一个大小为r
的矩阵c
和t
和p
是大小为r
和c
的列向量,大部分时间都是成本。我认为原因可能是t*p'
的内存扩展,它从两个向量生成一个矩阵,这是一个众所周知的原因,它使Matlab中的计算速度变慢。有没有办法加快这个?
PLS代码是:
for iter = 1:maxiter % maxiter is defaultedly set as 10,000
% preparing data....
......
% perform PLS using NIPALS algorithm
for a = 1:A
x = X'*y;
w = x/norm(x);
t = X*w;
tt = sum(t.^2);
p = X'*(t/tt);
q = sum(y.*t)/tt;
X = X-t*p'; % updata X, this line costs most of the time
y = y-t*q; % updata y
end
% output w, P, q
.......
end
答案 0 :(得分:0)
为避免X
与X = X-t*p';
之间的通缩,有三种方法,如"Computational performance and cross-validation error precision of five PLS algorithms using designed and real data sets"中所述。我使用了以下算法:
for iter = 1:maxtest
% preparing data...
... ...
for a = 1:A
% for a vector, eigenvector of S'*S is always 1
ri = s;
t = X*ri;
normt = sqrt(sum(t.^2));
t = t/normt;
ri = ri/normt;
% X loadings
pi = X'*t;
q = y'*t;
%u = y*q;
v = pi;
if a > 1
v = v-V(:,1:a-1)*(V(:,1:a-1)'*pi);
%u = u-T(:,1:a-1)*(T(:,1:a-1)'*u);
end
v = v/sqrt(sum(v.^2));
s = s-v*(v'*s);
V(:,a) = v;
R(:,a) = ri;
Q(a) = q;
end
% PLS coefficient...
b = R*Q;
...
end
for iter = 1:maxtest
% preparint data...
... ...
% NIPALS
for a = 1:A
x = X'*y;
rx = x/norm(x);
w = rx;
if a > 1
rx = rx-R(:,1:a-1)*(P(:,1:a-1)'*w);
end
t = X*rx;
tt = sum(t.^2);
P(:,a) = X'*t/tt;
q(a) = y'*t/tt;
y = y-t*q(a);
% W(:, a) = w;
R(:, a) = rx;
end
% PLS coefficient...
b = R*q;
... ...
end
双对角化
for iter = 1:maxtest
v = X'*y/norm(X'*y);
u = X*v;
normu = sqrt(sum(u.^2));
u = u/normu;
R(1) = normu;
V(:,1) = v;
U(:,1) = u;
for a = 2:A
v = X'*u-normu*v;
normv = sqrt(sum(v.^2));
v = v/normv;
u = X*v-normv*u;
normu = sqrt(sum(u.^2));
u = u/normu;
U(:,a) = u;
V(:,a) = v;
R(a-1,a) = normv;
R(a,a) = normu;
end
% PLS coefficients...
b = V*(R\(U'*y));
end
使用大小为43 by 195
的测试数据和10倍交叉验证,双向对角化方法是最快的,与论文结果一致。