直线拟合之最小二乘法 Ax+By+C=0

最小二乘法拟合直线,对于大多数人都不是很陌生,直线方程 y=kx+b,令sum((y-kx-b)^2),分别对k和b求导便可求出最佳的参数,但是如果遇到诸如“X=5”这样的直线方程,又该如何呢?这时候就不再适用了,参考如下描述http://mathforum.org/library/drmath/view/51809.html,这样拟合出来的才是直线的一般方程。

Let the line sought be A*x + B*y + C = 0, with no restriction on A, B, 
and C, except not both of A and B are zero. Then the distance from a 
point (x[n],y[n]) to this line is given by

   d[n] = |A*x[n]+B*y[n]+C|/sqrt(A^2+B^2).

Then the sum of the squares of the distances of the r points from the 
line is

   F(A,B,C) = SUM d[n]^2
            = SUM (A*x[n]+B*y[n]+C)^2/(A^2+B^2).

Here and henceforth, the sums run over the range 1 <= n <= r.

Now take the partial derivatives of F with respect to A, B, and C, and 
set them equal to zero. This will give you a set of three simultaneous 
nonlinear equations in A, B, and C, and you need to solve them. They 
will be polynomial, of degree 3. When I did this, the equations turned 
out to be

   SUM (A*x[n]+B*y[n]+C)*(A*C-B^2*x[n]+A*B*y[n]) = 0,
   SUM (A*x[n]+B*y[n]+C)*(B*C+A*B*x[n]-A^2*y[n]) = 0,
   SUM A*x[n]+B*y[n]+C = 0.

These can be rewritten as polynomials in A, B, and C with coefficients 
involving

   r = SUM 1,
   s = SUM x[n],
   t = SUM y[n],
   u = SUM x[n]^2,
   v = SUM x[n]*y[n],
   w = SUM y[n]^2,

which are quantities you can compute from your data points.

   -v*A^2*B-s*A^2*C+(u-w)*A*B^2-2*t*A*B*C-r*A*C^2+v*B^3+s*B^2*C = 0,
   v*A^3+(w-u)*A^2*B+t*A^2*C-v*A*B^2-2*s*A*B*C-t*B^2*C-r*B*C^2 = 0,
   s*A+t*B+r*C = 0.

C can be eliminated using the last equation, which is the same as

   C = -(s*A+t*B)/r.

That will leave you with two cubic equations in two unknowns A and B. 
 
They turn out to be equivalent to the single quadratic equation

   (r*v-s*t)*A^2 + (s^2-t^2-r*u+r*w)*A*B - (r*v-s*t)*B^2 = 0.
   A^2 + [(s^2-t^2-r*u+r*w)/(r*v-s*t)]*A*B - B^2 = 0.

Now unless r*v - s*t = 0, you can solve this equation for -A/B, the 
slope of the line. Then you can find C/B, too, and thus the equation 
of the line. You will get two distinct solutions. One is the minimum 
you seek, and the other is a saddle point of F(A,B,C). You can tell 
which is the minimum by evaluating F(A,B,C) at each one and choosing 
the solution that gives you the smaller value.

If r*v = s*t, but the coefficient s^2-t^2-r*u+r*w is nonzero, then the 
minimum will be achieved for either A = 0 or B = 0. Figure out C for 
both of these possibilities, and substitute them into F(A,B,C). The 
one that gives you the lesser value is your solution.

If r*v = s*t and s^2-t^2-r*u+r*w = 0, then any line through the center 
of mass (s/r,t/r) will give the same value of F as any other, and all 
are tied for being the best.

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用最小二乘法拟合一组点到直线。 假设有n个点,坐标为(x1,y1),(x2,y2),...,(xn,yn),我们需要找到一条直线Ax+By+C=0,使得这n个点到这条直线的距离的平方和最小。 首先,我们可以计算每个点到直线的距离d,即:d = (Ax + By + C) / sqrt(A^2 + B^2)。 然后,我们需要最小化所有点到直线距离的平方和,即:E = Σ(di^2),i从1到n。 我们可以对A、B、C分别求偏导数,然后令偏导数等于0,解出A、B、C的值,即可得到最佳的拟合直线。 具体实现可以参考下面的C++代码: ``` #include <iostream> #include <cmath> #include <vector> using namespace std; struct Point { double x; double y; }; void fitLine(vector<Point>& points, double& A, double& B, double& C) { int n = points.size(); double sumX = 0, sumY = 0, sumXY = 0, sumXX = 0, sumYY = 0; for (int i = 0; i < n; i++) { sumX += points[i].x; sumY += points[i].y; sumXY += points[i].x * points[i].y; sumXX += points[i].x * points[i].x; sumYY += points[i].y * points[i].y; } double denom = n * sumXX - sumX * sumX; if (denom == 0) { A = 1; B = 0; C = -points[0].x; } else { A = (n * sumXY - sumX * sumY) / denom; B = (sumXX * sumY - sumX * sumXY) / denom; C = -A * points[0].x - B * points[0].y; } } int main() { vector<Point> points = {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}}; double A, B, C; fitLine(points, A, B, C); cout << "A = " << A << ", B = " << B << ", C = " << C << endl; return 0; } ``` 这个程序可以拟合一个包含5个点的点集,并输出拟合直线的参数A、B、C。你可以根据自己的需要修改点集的内容和数量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值