/**
* [简单线性回归](http://en.wikipedia.org/wiki/Simple_linear_regression)
* 用于在坐标点集中寻找最佳拟合直线。本算法通过最小二乘法
* 计算回归直线的斜率和截距。
*
* @param {Array<Array<number>>} data 二维数据数组,格式为
* `[[0, 1], [2, 3]]`
* @returns {Object} 包含回归直线斜率和截距的对象
* @example
* linearRegression([[0, 0], [1, 1]]); // => { m: 1, b: 0 }
*/
function linearRegression(data) {
let m;
let b;
// 将数据长度存储在局部变量中以减少
// 重复的对象属性查找
const dataLength = data.length;
// 当仅有一个数据点时,设置斜率为0
// 截距取该点的y值
if (dataLength === 1) {
m = 0;
b = data[0][1];
} else {
// 初始化求和变量,限定定义直线的
// m(斜率)和b(截距)作用域
let sumX = 0;
let sumY = 0;
let sumXX = 0;
let sumXY = 0;
// 使用局部变量存储坐标点值
// 最小化对象属性访问
let point;
let x;
let y;
// 计算以下统计量的累加和:
// x总和、y总和、x平方和、x*y乘积和
//
// 数学符号表示为 SS_x, SS_y, SS_xx, SS_xy
for (let i = 0; i < dataLength; i++) {
point = data[i];
x = point[0];
y = point[1];
sumX += x;
sumY += y;
sumXX += x * x;
sumXY += x * y;
}
// 根据最小二乘法公式计算斜率m
m =
(dataLength * sumXY - sumX * sumY) /
(dataLength * sumXX - sumX * sumX);
// 计算截距b
b = sumY / dataLength - (m * sumX) / dataLength;
}
// 返回包含斜率和截距的对象
return {
m: m,
b: b
};
}
export default linearRegression;