Regresión lineal en Javascript


Quiero hacer ajustes de Mínimos Cuadrados en Javascript en un navegador web.

Actualmente los usuarios ingresan información de puntos de datos usando 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 tenga el valor R^2 más alto.

I sin embargo, no puedo encontrar ninguna biblioteca que me ayude a hacer esto. Me topé con jStat , pero le falta documentación por completo (por lo que puedo encontrar) y después de excavar a través del código fuente no parece tener ninguna funcionalidad de regresión lineal incorporada however Estoy basando esto puramente en nombres de funciones sin embargo.

¿Alguien conoce alguna librería Javascript que ofrezca análisis de regresión simple?


La esperanza sería que podría usar la biblioteca como tan...

Si tuviera algún conjunto de puntos de dispersión en una matriz var points = [[3,4],[15,45],...[23,78]], sería capaz de darle eso a alguna función como lin_reg(points) y devolvería algo como [7.12,3] si la ecuación lineal fuera y = 7.12 x + 3.

Author: Chris W., 2011-06-01

7 answers

¿Qué tipo de regresión lineal? Para algo simple como mínimos cuadrados, simplemente lo programaría yo mismo:

Http://mathworld.wolfram.com/LeastSquaresFitting.html

Las matemáticas no son demasiado difíciles de seguir, inténtalo durante una hora más o menos y avísame si es demasiado difícil, puedo intentarlo.

EDITAR:

Encontré a alguien que lo hizo:

Http://dracoblue.net/dev/linear-least-squares-in-javascript/159 /

 20
Author: Milimetric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-01 04:25:45

Encontré esta gran biblioteca JavaScript.

Es muy simple, y parece funcionar perfectamente.

Tampoco puedo recomendar Matemáticas.JS suficiente.

 7
Author: JZL003,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-07 22:26:58

Echa un vistazo 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 permanecen en su computadora. Complete los resultados de estilo R y el código R para verificar el trabajo y una visualización de los resultados.

Consulte el código fuente de las implementaciones JavaScript incrustadas de OLS y las estadísticas asociadas con los resultados.

El código es mi esfuerzo para portar la biblioteca GSL funciona con JavaScript.

Los códigos se publican bajo la GPL porque son básicamente portación línea por línea del código de la Gnu Scientific Library (GSL) con licencia GPL.

EDITAR: Paul Lutus también proporciona algún código GPL para regresión en: http://arachnoid.com/polysolve/index.html

 7
Author: Richard Finney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-30 10:06:34

La solución más simple que encontré para la pregunta en cuestión se puede encontrar en el siguiente post: 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 la puntuación R2, que puede ser útil.

* * EDITAR * *

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 utilizar esto le basta para pasar dos matrices, conocido_y y conocido_x, así que esto es lo que podría 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
 5
Author: o_c,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-22 16:02:48

Aquí hay un fragmento que tomará una matriz de trillizos (x, y, r) donde r es el peso del punto de datos (x, y) y devolverá [a, b] de modo que Y = a*X + b aproxime los 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];
}
 4
Author: Nic Mabon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-27 15:06:47

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.

 1
Author: Timmmm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-10 10:02:55

Regresión lineal simple con medidas de variación ( Suma total de cuadrados = Regresión suma de cuadrados + Error suma de cuadrados ), Error estándar de estimación VÉASE (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]);
 1
Author: didinko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-28 18:48:09