在我的代码中,我有一个瓶颈,我在其中为我的数据拟合线性函数。只需在数据点上插入一条线,然后找到方程k
的参数b
,R^2
和y=k*x+b
。
MATLAB中有很多功能可以做到这一点。我使用polyfit()
函数。但对我的需求来说似乎有些过分。问题是我必须执行大量的这些拟合(10 ^ 8或接近它)。
以下是我的代码示例:
nLines=5; % may be up to 10^8;
X=cellfun(@(x) rand(randi([50 100]),1),num2cell([1:nLines]'),...
'UniformOutput',false);
Y=cellfun(@(x) rand(numel(x),1),X,...
'UniformOutput',false);
K=nan(numel(X),1);
B=nan(numel(X),1);
R=nan(numel(X),1);
for iLine=1:numel(X)
coefs = polyfit(X{iLine}, Y{iLine}, 1);
yf=polyval(coefs,X{iLine});
K(iLine)=coefs(1);
B(iLine)=coefs(2);
R(iLine)=corr(Y{iLine},yf);
end
你能为这种大规模的线性拟合提供更快的解决方案吗?
P.S。我正在使用MATLAB R2017b,其中包含以下工具箱:
Optimization Toolbox
Signal Processing Toolbox
Statistics and Machine Learning Toolbox
答案 0 :(得分:0)
我似乎找到了答案。我可以使我的seqs大小相同,只是添加NaN到最后这个变体非常快,然后是polyfit
解决方案。
%% Generate data
nLines=10^3; % may be up to 10^8;
X=cellfun(@(x) rand(randi([50 100]),1),num2cell([1:nLines]'),...
'UniformOutput',false);
Y=cellfun(@(x) rand(numel(x),1),X,...
'UniformOutput',false);
K=nan(numel(X),1);
B=nan(numel(X),1);
R=nan(numel(X),1);
dur1=[];
dur2=[];
%% Small hack
% elongate all seqs by NaNs to obtain same size
longestLineSize=max(cellfun(@(x) numel(x),X));
matrixX=[];
matrixY=[];
N=[];
for iLine=1:numel(X)
matrixX=[matrixX,[X{iLine};nan(longestLineSize-numel(1,X{iLine}),1)]];
matrixY=[matrixY,[Y{iLine};nan(longestLineSize-numel(1,X{iLine}),1)]];
N=[N, numel(1,X{iLine})];
end
for iRep=1:100
%% Vectorized approach
start=tic;
sumX=nansum(matrixX);
sumY=nansum(matrixY);
sumX2=nansum(matrixX.^2);
sum2X=sumX.^2;
sum2Y=sumY.^2;
XY=matrixX.*matrixY;
sumXY=nansum(XY);
nominator=N.*sumXY-sumX.*sumY;
denominator=(N.*sumX2-sum2X);
k=nominator./denominator;
b=(sumY-k.*sumX)./N;
r=nominator./sqrt(denominator.*(N.*nansum(matrixY.^2)-sum2Y));
dur1(end+1)=toc(start);
%% polyfit solution
start=tic;
for iLine=1:numel(X)
coefs = polyfit(X{iLine}, Y{iLine}, 1);
yf=polyval(coefs,X{iLine});
K(iLine)=coefs(1);
B(iLine)=coefs(2);
R(iLine)=corr(Y{iLine},yf);
end
dur2(end+1)=toc(start);
end