可能是一个简单的问题,但到目前为止我找不到一个简单的解决方案。我正在为一个非常具体的用例开发一个简单的图像识别软件。
鉴于是一堆据说是直线的点。但是,有些点被错误地放置并远离线路。特别是在线的末端附近,点可能或多或少不准确。
示例:
X // this guy is off
X // this one even more
X // looks fine
X
X
X // a mistake in the middle
X
X // another mistake, not as bad as the previous
X
X
X
X
X // we're off the line again
线的大致方向是已知的,在这种情况下,它是垂直的。实例中的实际线条实际上是垂直的,具有轻微的对角线斜率。
我只对无限线感兴趣(即它的斜率和偏移量),端点的位置并不重要。
作为附加信息(不确定是否重要),2个点不可能水平相邻。例如:
X
X
X
X X // cannot happen
X
X
表现并不重要。我在C#工作,但我对任何语言都很好,或者只是一个通用的想法。
答案 0 :(得分:4)
答案 1 :(得分:3)
double[] xVals = {...};
double[] yVals = {...};
double xMean = 0;
double yMean = 0;
double Sxy = 0;
double Sxx = 0;
double beta0, beta1;
int i;
for (i = 0; i < xVals.Length; i++)
{
xMean += xVals[i]/xVals.Length;
yMean += yVals[i]/yVals.Length;
}
for (i = 0; i < xVals.Length; i++)
{
Sxy += (xVals[i]-xMean)*(yVals[i]-yMean);
Sxx += (xVals[i]-xMean)*(xVals[i]-xMean);
}
beta1 = Sxy/Sxx;
beta0 = yMean-beta1*xMean;
使用beta1作为斜率,使用beta0作为y轴截距!
答案 2 :(得分:3)
如果您知道没有异常值,则线性回归(如其他人所述)很好。
如果你有异常值,那么我最喜欢的方法之一是中位数中值线方法: http://education.uncc.edu/droyster/courses/spring00/maed3103/Median-Median_Line.htm
基本上,您可以按X值对点进行排序,然后将点拆分为三个大小相等的组(最小值,中值和最大值)。最终斜率是通过小组中位数和大组中位数的线的斜率。中间组的中位数与其他中位数一起用于计算最终偏移/截距。
这是一个简单的算法,可以在几个图形计算器上找到。
通过取三个中位数,你完全忽略了任何异常值(在最左边,最右边,远边或远处)。
下图显示了具有几个大异常值的一组数据的线性回归和中位数 - 中值线。