MATLAB:使用fittype在曲线拟合工具箱中的分段函数

时间:2013-11-29 12:25:46

标签: matlab plot curve-fitting linear-regression least-squares

首先忽略红色拟合曲线。我想得到蓝色数据点的曲线。我知道第一部分(在这种情况下最多y~200)是线性的,然后是不同的曲线(两个对数曲线的组合,但也可以近似不同)然后它在约250或255饱和。我试过这样的:

func = fittype('(x>=0 & x<=xTrans1).*(A*x+B)+(x>=xTrans1 & x<=xTrans2).*(C*x+D)+(x>=xTrans2).*E*255');
freg = fit(foundData(:,1), foundData(:,2), func);
plot(freg, foundData(:,1), foundData(:,2))

显然我的fittype可以改进,但为什么它实际上是坏/错呢? 我尝试了另一个更简单的模型:

func = fittype('(x>=0 & x<=xTrans1).*(A*x+B)+(x>=xTrans1).*(C*x+D)')
freg = fit(foundData(:,1), foundData(:,2), func);
plot(freg, foundData(:,1), foundData(:,2))

至少我希望有两个线性函数,我得到的是:

或者只是因为拟合的输出是错误的情节:

 General model:
 f_fit(x) = (x>=0 & x<=xTrans1).*(A*x+B)+(x>=xTrans1).*(C*x+D)
 Coefficients (with 95% confidence bounds):
   A =      0.6491
   B =      0.7317
   C =   0.0007511
   D =       143.5
   xTrans1 =       0.547

至少会产生一个好xTrans1(但我在剧情中看不到它)!


修改 感谢您指出更合适的函数编程方法,我尝试了以下(三个不同的线性函数和两个转换点):

function y = singleRegression_ansatzfunktion(x,xtrans1,xtrans2,a,b,c,d,e,f)
y = zeros(size(x));

% 3 Geradengleichungen:
for i = 1:length(x)
    if x(i) < xtrans1
        y(i) = a + b.* x(i);
    elseif(x(i) < xtrans2)
        y(i) = c + d.* x(i);
    else
        y(i) = e + f.* x(i);
    end
end

这样称呼钳工:

freg = fit(foundData(:,1), foundData(:,2), 'singleRegression_ansatzfunktion(x,xtrans1,xtrans2,a,b,c,d,e,f)');
plot(freg, foundData(:,1), foundData(:,2))

导致:

 General model:
 f(x) = singleRegression_ansatzfunktion(x,xtrans1,xtrans2,a,b,c,d,e,f)
 Coefficients (with 95% confidence bounds):
   a =      0.7655
   b =      0.7952
   c =      0.1869
   d =      0.4898
   e =       159.2
   f =   0.0005512
   xtrans1 =      0.7094
   xtrans2 =      0.7547

!!!!奇怪!!!!


EDIT2 当不让MATLAB优化转换点但是我自己输入它们就像我在cftool中做的那样(应该像调用fit一样,但通过自定义等式更快地解决它):

(x>=0 & x<=2.9e4).*(A*x+B)+(x>2.9e4 & x<=1.3e5).*(B*x+D)+(x>1.3e5).*255

效果很好。我不知道为什么MATLAB不能自己做这个但是没关系......结果你现在去了:

所以至少我现在修好了,但我仍然怀疑为什么MATLAB本身不能这样做。

1 个答案:

答案 0 :(得分:2)

您是否在fittype文档页面(“由文件定义的拟合曲线”示例)中尝试​​了该方法,即定义您的函数以适合文件以查看它是否有所作为?

我能想到的另一种方法是将数据分成两个(或更多)不同的数据集,并为每个块做两个单独的拟合(但假设你知道先验的过渡在安装之前,它们是/或可以在它们之外工作。