繁体   English   中英

Matlab中的多项式拟合谷点

[英]polynomial fit trough points in matlab

我正在尝试找到最适合输入点集的多项式。

到目前为止,这是我的代码:

    x=(1:length(meanValues));
    y=meanValues(:);        

    A=fliplr(vander(x));
    v=A \ y;
    P(1: length(x))=0;
    for i=1: length(x)
        for j=1: length(v)
            P(i)=P(i)+v(j)*x(i).^(j-1);
        end
    end    
    plot(x,y,'r*');
    hold on;
    plot(x, P);
  • meanValues是[1x127]向量,其填充范围为(0.0000-5.0000]之间的双精度值

波纹管绘制平均值:

原始点集

结果: polyfit的结果

谁知道错误在哪里?

编辑1:

所以这一次,我浏览了所有多项式阶并找到了最合适的阶。 这是否更好? 我可以优化此代码吗? 计算大约需要1s,因此总共需要30s。

    tic
    x=(1:length(meanValues));
    y=meanValues(:)'; 
    for i=1:length(meanValues)-1
        [p,s,mu] = polyfit(x,y, i);
        [f,delta] = polyval(p,x,s,mu);
        if i==1
            minf=f;
            minmse = mean(delta.^2);
            minp=p;
        elseif minmse>mean(delta.^2)
            minf=f;
            minmse = mean(delta.^2);
            minp=p;
        end
    end
    toc
    plot(x,y,'r*',x,minf,'-');
    axis([0 length(meanValues) 0 max(meanValues)]);

多边形拟合

您需要开发一种迭代所有想要适合的多项式阶次的方法。 在整个迭代过程中,您可以计算出模型P和数据y之间的误差。 均方误差是我建议的一种相似性的常用度量。

当前,您无法更改模型顺序,实际上它非常高(127),因此最终结果不稳定。

在此修改后的代码中,我生成了自己的嘈杂的meanValues,使用二阶拟合最适合。 但是阶值设置为4,因此您会发现v中的第三阶和第四阶系数与第0阶,第1阶和第2阶系数相比非常小。

至少对于我生成的数据,您应该能够验证2阶拟合的y和P之间的MSE低于4阶拟合。 您的数据似乎没有太大的趋势,因此您最好测试一些不同的订单,并选择MSE最低的订单。 这并不是说它可以正确地对生成数据的系统进行建模,所以要小心。

clear all;
meanValues = (1:127)/25;
meanValues(:) = meanValues(:).^2;
for i = 1:length(meanValues)
    meanValues(i) = meanValues(i) + rand(1,1)*4;
end

x=(1:length(meanValues));
y=meanValues(:);

Order = 4;
A(:,1) = ones(127,1);
for j = 1:Order
    A(:,j+1) = (x'.^j);
end
%   A=fliplr(vander(x));
v=A \ y;
P(1: length(x))=0;
for i=1: length(x)
    for j=1: length(v)
        P(i)=P(i)+v(j)*x(i).^(j-1);
    end
end
plot(x,y,'r*');
hold on;
plot(x, P);

编辑:此版本计算MSE并找到最小订单。 仅需0.324198秒即可检查100阶拟合。 使用polyfit也许有一些优势...我不确定。

clear all;
meanValues = (1:127)/25;
meanValues(:) = meanValues(:).^2;
for i = 1:length(meanValues)
    meanValues(i) = meanValues(i) + rand(1,1)*4;
end

x=(1:length(meanValues));
y=meanValues(:);
tic
minMSE = Inf;
nOrder = 100;
for Order = 1:nOrder

    A(:,1) = ones(127,1);
    for j = 1:Order
        A(:,j+1) = (x'.^j);
    end
    %   A=fliplr(vander(x));
    v=A \ y;
    P = zeros(1,length(x));
    for i=1: length(x)
        for j=1: length(v)
            P(i)=P(i)+v(j)*x(i).^(j-1);
        end
    end
   P = P';
    newMSE = norm(P-y);
    if (newMSE < minMSE)
        minMSE = newMSE;
        minOrder = Order;
        minP = P';
    end
end

toc
plot(x,y,'r*');
hold on;
plot(x, minP);
minMSE
minOrder

这段代码可以正常工作:

% Data and regression
y = cumsum(randn(100, 1));
x=(1:length(y));
x = x(:);
A=fliplr(vander(x));
A = A(:, 1:7);
v=A \ y;

% Calculate P your way
P(length(x))=0;
for i=1: length(x)
  for j=1: length(v)
    P(i)=P(i)+v(j)*x(i).^(j-1);
  end
end

% Calculate P by vectorization
Q = A * v;

% P and Q should be the same - they are!
tmp = P - Q';
plot(tmp, '.')

% Plot data and fitted data
figure
plot(x,y,'r*');
hold on;
plot(x, P, '-b');
plot(x, Q, '-g');

此回归等效于

p = fliplr(polyfit(x,y,6))';

返回警告

Warning: Polynomial is badly conditioned. Add points with distinct X
         values, reduce the degree of the polynomial, or try centering
         and scaling as described in HELP POLYFIT. 

如果你尝试这个

A=fliplr(vander(x));
A = A(:, 1:8);
v=A \ y;

它返回警告:

Warning: Rank deficient, rank = 7,  tol =   5.9491e+000. 

因为A(end)1.0000e+014

因此,您看到,多项式回归是讨厌的方法。 您必须找到另一种方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM