【问题标题】:find the line which best fits to the data找到最适合数据的线
【发布时间】:2017-07-19 15:19:31
【问题描述】:

我正在尝试找到最适合数据的行。我使用下面的代码,但现在 我希望将数据放入一个排序的数组中,以便它首先拥有最接近该行的数据我该怎么做? 还有 polyfit 是正确的函数用于这个?

x=[1,2,2.5,4,5];
y=[1,-1,-.9,-2,1.5];
n=1;
p = polyfit(x,y,n)

f = polyval(p,x);
plot(x,y,'o',x,f,'-')

PS:我使用的是 Octave 4.0,类似于 Matlab

【问题讨论】:

    标签: matlab octave curve-fitting data-fitting


    【解决方案1】:

    您可以先计算真实值y与预测值f之间的误差

    err = abs(y-f);
    

    然后对误差向量进行排序

    [val, idx] = sort(err);
    

    并使用已排序的索引对您的 y 值进行排序

    y2 = y(idx);
    

    现在y2y 具有相同的值,但更接近拟合值的优先。

    对 x 做同样的事情来计算 x2,这样你就有了 x2 和 y2 之间的对应关系

    x2 = x(idx);
    

    【讨论】:

      【解决方案2】:

      Sembei Norimaki 很好地解释了你的主要问题,所以我会看看你的次要问题 = polyfit 是正确的函数吗?

      最佳拟合线定义为平均误差为零的线。

      如果它必须是一条“线”,我们可以使用 polyfit,它可以拟合多项式。当然,“线”可以定义为一次多项式,但一次多项式具有一些易于处理的特性。您要查找的一阶多项式(或线性)方程应采用以下形式:

      y = mx + b
      

      其中 y 是您的因变量,X 是您的自变量。所以挑战是这样的:找到 m 和 b 使得建模的 y 尽可能接近实际的 y。事实证明,与线性拟合相关的误差是凸的,这意味着它有一个最小值。为了计算这个最小值,最简单的方法是将偏差和 x 向量组合如下:

      Xcombined = [x.' ones(length(x),1)];
      

      然后利用正规方程,从误差最小化导出

      beta = inv(Xcombined.'*Xcombined)*(Xcombined.')*(y.')
      

      太好了,现在我们的行定义为 Y = Xcombined*beta。要画一条线,只需从 x 的某个范围内采样并添加 b 项

      Xplot = [[0:.1:5].' ones(length([0:.1:5].'),1)];
      Yplot = Xplot*beta;
      plot(Xplot, Yplot);
      

      那么为什么 polyfit 的效果这么差呢?好吧,我不能肯定地说,但我的假设是你需要转置你的 x 和 y 矩阵。我想这会给你一个更合理的路线。

      x = x.';
      y = y.';
      

      那就试试

      p = polyfit(x,y,n)
      

      我希望这会有所帮助。一位智者曾经告诉我(我每天都在学习),不要相信你不懂的算法!

      【讨论】:

      • xy 是向量,转置它们不会有任何效果。问题中的示例的回归结果非常差,因为您可以看到数据相关性非常低。回归不能变魔术,所以如果你想在低相关数据中拟合一条线,你应该预料到会有很大的错误。无论如何,智者的好建议。
      • 是的,回头看看我在想什么。这绝对没有理由成为问题。我想我认为它可能会将训练集视为 5 个特征、1 个样本的数据集。
      【解决方案3】:

      这里有一些测试代码可以帮助其他人处理线性回归和最小二乘

      %https://youtu.be/m8FDX1nALSEmatlab代码

      %https://youtu.be/1C3olrs1CUw如果你想测试,可以手工制作的好视频

      function [a0 a1] = rtlinreg(x,y) 
        x=x(:);
        y=y(:);
        n=length(x);
        a1 = (n*sum(x.*y) - sum(x)*sum(y))/(n*sum(x.^2) - (sum(x))^2);  %a1 this is the slope of linear model
        a0 = mean(y) - a1*mean(x); %a0 is the y-intercept
      end
      
      x=[65,65,62,67,69,65,61,67]'
      y=[105,125,110,120,140,135,95,130]'
      
      [a0 a1] = rtlinreg(x,y);  %a1 is the slope of linear model, a0 is the y-intercept
      
      x_model =min(x):.001:max(x);
      y_model = a0 + a1.*x_model;  %y=-186.47 +4.70x   
      plot(x,y,'x',x_model,y_model)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-09
        • 1970-01-01
        • 2019-11-26
        • 1970-01-01
        相关资源
        最近更新 更多