我正在尝试实现一种将线拟合到 2D 中的一组点的方法。我编写了以下代码,它从两个数组(X,Y 坐标)中读取数据,并应使用最小二乘法计算最佳拟合线的参数。我使用了这里给出的公式: mathworld.wolfram
- (void) linearRegressionOfUserAcceleration
{
double avgX = [[_accelBufferX valueForKeyPath:@"@avg.doubleValue"] doubleValue];
double avgY = [[_accelBufferY valueForKeyPath:@"@avg.doubleValue"] doubleValue];
int n = _accelBufferX.count;
double ssX, ssY, ssXY;
ssX = ssY = ssXY = 0;
int i;
// Sum of squares X, Y & X*Y
for (i = 0; i < n; i++)
{
ssX += pow([[_accelBufferX objectAtIndex:i] doubleValue],2);
ssY += pow([[_accelBufferY objectAtIndex:i] doubleValue],2);
ssXY += [[_accelBufferX objectAtIndex:i] doubleValue] * [[_accelBufferY objectAtIndex:i] doubleValue];
}
ssX = ssX - n * pow(avgX,2);
ssY = ssY - n * pow(avgY,2);
ssXY = ssXY - n * avgX * avgY;
// Best fit of line y_i = a + b * x_i
b = ssXY / ssX;
a = avgY - b * avgX;
// Correlationcoefficent gives the quality of the estimate: 1 = perfect to 0 = no fit
corCoeff = pow(ssXY,2) / ssX * ssY;
NSLog(@"n: %d, a: %f --- b: %f --- cor: %f --- avgX: %f --- avgY: %f --- ssX: %f - ssY: %f - ssXY: %f", n, a, b, corCoeff, avgX, avgY, ssX, ssY, ssXY);
}
我得到这样的输出:
n: 15, a: -0.095204 --- b: 0.929245 --- cor: 3.567163 --- avgX: -0.017827 -- avgY: -0.111770 --- ssX: 2.176048 - ssY: 1.898429 - ssXY: 2.022081
结果线根本不适合数据,尽管 corelationCoefficient 有时大于一,恕我直言,如果一切正常,则永远不会发生这种情况。
有人在我的实施中看到任何错误吗?
- 编辑 -
这是更正的代码,遵循 CRD 的提示。我用它来提取两个步骤之间水平面上采样的用户加速度的方向向量,以获得步骤方向。
这对我有用:
- (void) linearRegressionOfUserAcceleration
{
NSUInteger n = _accelBufferX.count;
double ax, ay, sX, sY, ssX, ssY, ssXY, avgX, avgY;
// Sum of squares X, Y & X*Y
for (NSUInteger i = 0; i < n; i++)
{
@synchronized(self) {
ax = [[_accelBufferX objectAtIndex:i] doubleValue];
ay = [[_accelBufferY objectAtIndex:i] doubleValue];
}
sX += ax;
sY += ay;
ssX += ax * ax;
ssY += ay * ay;
ssXY += ax * ay;
}
avgX = sX / n;
avgY = sY / n;
radius = hypot(avgX, avgY);
ssX = ssX - n * (avgX * avgX);
ssY = ssY - n * (avgY * avgY);
ssXY = ssXY - n * avgX * avgY;
// Best fit of line y_i = a + b * x_i
b = ssXY / ssX;
a = (avgY - b * avgX);
theta = atan2(1, b);
// Correlationcoefficent gives the quality of the estimate: 1 = perfect to 0 = no fit
corCoeff = (ssXY * ssXY) / (ssX * ssY);
NSLog(@"n: %d, a: %f --- b: %f --- cor: %f --- avgX: %f -- avgY: %f --- ssX: %f - ssY: %f - ssXY: %f", n, a, b, corCoeff, avgX, avgY, ssX, ssY, ssXY);
}