Google Spreadsheetなどで「トレンドライン」を引く際に利用される計算。
全データから、誤差の2乗が最小になるようにラインを引く方法・・らしい。
計算式は以下。(Wikipediaから引用)
a = \frac{n\sum_{k=1}^{n}x_ky_k - \sum_{k=1}^{n}x_k\sum_{k=1}^{n}y_k}{n\sum_{k=1}^{n}x^2_k - (\sum_{k=1}^{n}x_k)^2}
b = \frac{\sum_{k=1}^{n}x^2_k\sum_{k=1}^{n}y_k - \sum_{k=1}^{n}x_ky_k\sum_{k=1}^{n}x_k}{n\sum_{k=1}^{n}x^2_k - (\sum_{k=1}^{n}x_k)^2}
上記 $a$, $b$ を算出し、 $y = ax +b$ という形にして利用します。
なお、計算式の導き方はこちらが参考になりました。(最小二乗法)
ただ、例に出されているデータと、最後に
最初に示したのデータについて計算してみると
で表示されている数値がどうやら違うっぽいので注意です。(別のサイトでデータ入れてみたら違う数値が出た)
また、最後に導き出されている数式もWikipediaに載っているのと若干違いました。
(function (ns) {
'use strict';
function sum(data, func) {
var val = 0;
for (var i = 0; i < data.length; i++) {
val += func(data[i]);
}
return val;
}
function leastSquare(data) {
var N = data.length;
var sumX = sum(data, function (item) {
return item[0];
});
var sumX2 = sum(data, function (item) {
return item[0] * item[0];
});
var sumY = sum(data, function (item) {
return item[1];
});
var sumXY = sum(data, function (item) {
return item[0] * item[1];
});
var a, b;
var denominator = (N * sumX2) - Math.pow(sumX, 2);
var molecule1 = (N * sumXY) - (sumX * sumY);
a = molecule1 / denominator;
var molecule2 = (sumX2 * sumY) - (sumXY * sumX);
b = molecule2 / denominator;
return {
a: a,
b: b
};
}
ns.leastSquare = leastSquare;
}(window));
これを使って、以下のように計算します。
var data = [
[1.2, 2.2],
[2.1, 3.8],
[3.3, 5.6],
[4.1, 7.1],
[5, 8.8]
];
var test = leastSquare(data);
console.log(test); // => Object {a: 1.7142239515780355, b: 0.1173367920449656}