线性函数的快速拟合。软件
Fast fit of linear function. Matlab
在我的代码中我遇到了一个瓶颈,我在其中为我的数据拟合了一个线性函数。简单地用一条线拟合数据点并找到等式 y=k*x+b
的参数 k
、b
和 R^2
。
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
看来我找到了答案。我可以让我的 seqs 大小相同,只是在最后添加 NaNs 这个变体非常快,然后是 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
在我的代码中我遇到了一个瓶颈,我在其中为我的数据拟合了一个线性函数。简单地用一条线拟合数据点并找到等式 y=k*x+b
的参数 k
、b
和 R^2
。
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
看来我找到了答案。我可以让我的 seqs 大小相同,只是在最后添加 NaNs 这个变体非常快,然后是 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