2Dの点のセットに線を合わせるメソッドを実装しようとしています。2つの配列(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が1より大きい場合もありますが、すべてが正しく機能していれば、IMHOは発生しないはずです。
誰かが私の実装にエラーを見つけましたか?
- 編集 -
これは、CRDからのヒントに従って修正されたコードです。これを使用して、2つのステップ間の水平面でサンプリングされたuserAccelerationの方向ベクトルを抽出し、ステップの方向を取得しました。
これは私のために働いた:
- (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);
}