Regresión lineal en Javascript
jquery statistics (7)
¿Qué tipo de regresión lineal? Para algo simple como mínimos cuadrados, lo programaría yo mismo:
http://mathworld.wolfram.com/LeastSquaresFitting.html
El cálculo no es demasiado difícil de seguir allí, pruébelo durante una hora aproximadamente y hágame saber si es demasiado difícil, puedo intentarlo.
EDITAR:
Encontré a alguien que lo hizo:
http://dracoblue.net/dev/linear-least-squares-in-javascript/159/
Quiero hacer Ajuste de mínimos cuadrados en Javascript en un navegador web.
Actualmente, los usuarios ingresan información de puntos de datos utilizando entradas de texto HTML y luego tomo esos datos con jQuery y los grafico con Flot .
Después de que el usuario haya ingresado sus puntos de datos, me gustaría presentarles una "línea de mejor ajuste". Imagino que calcularía las ecuaciones lineales, polinómicas, exponenciales y logarítmicas y luego elegiría la que R^2
valor R^2
más alto.
Parece que no puedo encontrar ninguna biblioteca que me ayude a hacer esto. Me topé con jStat , pero falta la documentación (hasta donde puedo encontrar) y después de buscar en el código fuente, no parece tener ninguna función de regresión lineal incorporada. Basándome en esta función. nombres sin embargo.
¿Alguien sabe alguna biblioteca de Javascript que ofrezca análisis de regresión simple?
La esperanza sería que pudiera usar la biblioteca así ...
Si tuviera algún conjunto de puntos de dispersión en una matriz var points = [[3,4],[15,45],...[23,78]]
, podría entregarlo a alguna función como lin_reg(points)
y devolvería algo así como [7.12,3]
si la ecuación lineal fuera y = 7.12 x + 3
.
Algo basado en la respuesta de Nic Mabon.
function linearRegression(x, y)
{
var xs = 0; // sum(x)
var ys = 0; // sum(y)
var xxs = 0; // sum(x*x)
var xys = 0; // sum(x*y)
var yys = 0; // sum(y*y)
var n = 0;
for (; n < x.length && n < y.length; n++)
{
xs += x[n];
ys += y[n];
xxs += x[n] * x[n];
xys += x[n] * y[n];
yys += y[n] * y[n];
}
var div = n * xxs - xs * xs;
var gain = (n * xys - xs * ys) / div;
var offset = (ys * xxs - xs * xys) / div;
var correlation = Math.abs((xys * n - xs * ys) / Math.sqrt((xxs * n - xs * xs) * (yys * n - ys * ys)));
return { gain: gain, offset: offset, correlation: correlation };
}
Entonces y ''= x * ganancia + desplazamiento.
Aquí hay un fragmento que tomará una serie de tripletes (x, y, r) donde r es el peso del punto de datos (x, y) y devuelve [a, b] de manera que Y = a * X + b se aproxima al datos.
// return (a, b) that minimize
// sum_i r_i * (a*x_i+b - y_i)^2
function linear_regression( xyr )
{
var i,
x, y, r,
sumx=0, sumy=0, sumx2=0, sumy2=0, sumxy=0, sumr=0,
a, b;
for(i=0;i<xyr.length;i++)
{
// this is our data pair
x = xyr[i][0]; y = xyr[i][1];
// this is the weight for that pair
// set to 1 (and simplify code accordingly, ie, sumr becomes xy.length) if weighting is not needed
r = xyr[i][2];
// consider checking for NaN in the x, y and r variables here
// (add a continue statement in that case)
sumr += r;
sumx += r*x;
sumx2 += r*(x*x);
sumy += r*y;
sumy2 += r*(y*y);
sumxy += r*(x*y);
}
// note: the denominator is the variance of the random variable X
// the only case when it is 0 is the degenerate case X==constant
b = (sumy*sumx2 - sumx*sumxy)/(sumr*sumx2-sumx*sumx);
a = (sumr*sumxy - sumx*sumy)/(sumr*sumx2-sumx*sumx);
return [a, b];
}
He encontrado esta gran biblioteca de JavaScript .
Es muy simple, y parece funcionar perfectamente.
Tampoco puedo recomendar Math.JS lo suficiente.
La solución más sencilla que encontré para la pregunta en cuestión se puede encontrar en la siguiente publicación: http://trentrichardson.com/2010/04/06/compute-linear-regressions-in-javascript/
Tenga en cuenta que además de la ecuación lineal, también devuelve el puntaje R2, que puede ser útil.
** EDIT **
Aquí está el fragmento de código real:
function linearRegression(y,x){
var lr = {};
var n = y.length;
var sum_x = 0;
var sum_y = 0;
var sum_xy = 0;
var sum_xx = 0;
var sum_yy = 0;
for (var i = 0; i < y.length; i++) {
sum_x += x[i];
sum_y += y[i];
sum_xy += (x[i]*y[i]);
sum_xx += (x[i]*x[i]);
sum_yy += (y[i]*y[i]);
}
lr[''slope''] = (n * sum_xy - sum_x * sum_y) / (n*sum_xx - sum_x * sum_x);
lr[''intercept''] = (sum_y - lr.slope * sum_x)/n;
lr[''r2''] = Math.pow((n*sum_xy - sum_x*sum_y)/Math.sqrt((n*sum_xx-sum_x*sum_x)*(n*sum_yy-sum_y*sum_y)),2);
return lr;
}
Para usar esto solo necesitas pasarle dos matrices, known_y''s y known_x''s, así que esto es lo que podrías pasar:
var known_y = [1, 2, 3, 4];
var known_x = [5.2, 5.7, 5.0, 4.2];
var lr = linearRregression(known_y, known_x);
// now you have:
// lr.slope
// lr.intercept
// lr.r2
Regresión lineal simple con medidas de variación (suma total de cuadrados = suma de cuadrados de regresión + suma de cuadrados de error), error estándar de la estimación (error estándar residual) y coeficientes de determinación R2 y correlación R.
const regress = (x, y) => {
const n = y.length;
let sx = 0;
let sy = 0;
let sxy = 0;
let sxx = 0;
let syy = 0;
for (let i = 0; i < n; i++) {
sx += x[i];
sy += y[i];
sxy += x[i] * y[i];
sxx += x[i] * x[i];
syy += y[i] * y[i];
}
const mx = sx / n;
const my = sy / n;
const yy = n * syy - sy * sy;
const xx = n * sxx - sx * sx;
const xy = n * sxy - sx * sy;
const slope = xy / xx;
const intercept = my - slope * mx;
const r = xy / Math.sqrt(xx * yy);
const r2 = Math.pow(r,2);
let sst = 0;
for (let i = 0; i < n; i++) {
sst += Math.pow((y[i] - my), 2);
}
const sse = sst - r2 * sst;
const see = Math.sqrt(sse / (n - 2));
const ssr = sst - sse;
return {slope, intercept, r, r2, sse, ssr, sst, sy, sx, see};
}
regress([1, 2, 3, 4, 5], [1, 2, 3, 4, 3]);
Visite https://web.archive.org/web/20150523035452/https://cgwb.nci.nih.gov/cgwbreg.html (calculadora de regresión javascript) - JavaScript puro, no llamadas CGI al servidor. Los datos y el procesamiento permanece en su computadora. Complete los resultados del estilo R y el código R para verificar el trabajo y una visualización de los resultados.
Consulte el código fuente para las implementaciones de JavaScript incrustadas de OLS y las estadísticas asociadas con los resultados.
El código es mi esfuerzo por portar las funciones de la biblioteca GSL a JavaScript.
Los códigos se publican bajo GPL porque es básicamente la línea para la transferencia de líneas del código de Gnu Scientific Library (GSL) con licencia GPL.
EDITAR: Paul Lutus también proporciona un código GPL para la regresión en: http://arachnoid.com/polysolve/index.html