web-dev-qa-db-fra.com

Régression linéaire en Javascript

Je veux faire des moindres carrés en Javascript dans un navigateur Web.

Actuellement, les utilisateurs saisissent des informations sur les points de données en utilisant des entrées de texte HTML, puis je récupère ces données avec jQuery et les représente graphiquement avec Flot .

Après que l'utilisateur ait entré ses points de données, je voudrais lui présenter une "ligne de meilleur ajustement". J'imagine que je calculerais les équations linéaires, polynomiales, exponentielles et logarithmiques, puis choisirais celle avec la plus haute valeur R^2.

Je n'arrive pas à trouver de bibliothèques qui m'aideront à le faire. Je suis tombé sur jStat , mais il manque complètement de documentation (pour autant que je puisse trouver) et après avoir fouillé le code source, il ne semble pas avoir de fonctionnalité de régression linéaire intégrée - je Je fonde cela uniquement sur des noms de fonction.

Quelqu'un connaît-il des bibliothèques Javascript qui offrent une analyse de régression simple?


L'espoir serait que je puisse utiliser la bibliothèque comme ça ...

Si j'avais un ensemble de points de dispersion dans un tableau var points = [[3,4],[15,45],...[23,78]], Je serais en mesure de le remettre à une fonction comme lin_reg(points) et cela retournerait quelque chose comme [7.12,3] Si le l'équation linéaire était y = 7.12 x + 3.

30
Chris W.

Quel genre de régression linéaire? Pour quelque chose de simple comme les moindres carrés, je le programmerais moi-même:

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

Le calcul n'est pas trop difficile à suivre là-bas, essayez-le pendant une heure environ et faites-moi savoir si c'est trop dur, je peux l'essayer.

MODIFIER:

J'ai trouvé quelqu'un qui l'a fait:

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

21
Milimetric

La solution la plus simple que j'ai trouvée pour la question à portée de main peut être trouvée dans le message suivant: http://trentrichardson.com/2010/04/06/compute-linear-regressions-in-javascript/

Notez qu'en plus de l'équation linéaire, elle renvoie également le score R2, ce qui peut être utile.

** ÉDITER **

Voici l'extrait de code réel:

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;
}

Pour l'utiliser, il vous suffit de lui passer deux tableaux, connus_ et connus_x, c'est donc ce que vous pourriez passer:

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
10
o_c

J'ai trouvé cette grande bibliothèque JavaScript .

C'est très simple et semble fonctionner parfaitement.

Je ne peux pas non plus recommander assez Math.JS.

8
JZL003

Consultez https://web.archive.org/web/20150523035452/https://cgwb.nci.nih.gov/cgwbreg.html (calculateur de régression javascript) - JavaScript pur, pas les appels CGI au serveur. Les données et le traitement restent sur votre ordinateur. Remplissez les résultats de style R et le code R pour vérifier le travail et une visualisation des résultats.

Voir le code source pour les implémentations JavaScript intégrées d'OLS et les statistiques associées aux résultats.

Le code est mon effort pour porter les fonctions de la bibliothèque GSL sur JavaScript.

Les codes sont publiés sous GPL car il s'agit essentiellement de la ligne pour le portage en ligne du code GSL (Gnu Scientific Library) sous licence GPL.

EDIT: Paul Lutus fournit également du code GPL pour la régression à: http://arachnoid.com/polysolve/index.html

7
Richard Finney

Voici un extrait qui prendra un tableau de triplets (x, y, r) où r est le poids du point de données (x, y) et retournera [a, b] de telle sorte que Y = a * X + b se rapproche de la Les données.

// 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
Nic Mabon

Régression linéaire simple avec mesures de variation (Somme totale des carrés = Somme de régression des carrés + Somme d'erreur des carrés), Erreur standard d'estimation SEE (Erreur standard résiduelle), et coefficients de détermination R2 et corrélation 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]);
2
didinko

Un peu basé sur la réponse 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 };
}

Alors y '= x * gain + décalage.

1
Timmmm