Линейная регрессия в Javascript - PullRequest
27 голосов
/ 01 июня 2011

Я хочу сделать пример наименьших квадратов в Javascript в веб-браузере.

В настоящее время пользователи вводят информацию о точке данных с помощью текстового ввода HTML, а затем я собираю эти данные с помощью jQuery и отображаю их с помощью Flot .

После того, как пользователь ввел свои данные, я хотел бы представить им «линию наилучшего соответствия». Я предполагаю, что вычислю линейные, полиномиальные, экспоненциальные и логарифмические уравнения, а затем выберу то, которое имеет наибольшее значение R^2.

Я не могу найти библиотек, которые бы помогли мне сделать это. Я наткнулся на jStat , но в нем полностью отсутствует документация (насколько я могу найти), и после копания в исходном коде в нем, похоже, нет встроенной функциональности линейной регрессии - I ' Однако это основано исключительно на именах функций.

Кто-нибудь знает какие-либо библиотеки Javascript, которые предлагают простой регрессионный анализ?


Есть надежда, что я смогу использовать библиотеку вот так ...

Если бы у меня был некоторый набор точек рассеяния в массиве var points = [[3,4],[15,45],...[23,78]], я мог бы передать это некоторой функции, такой как lin_reg(points), и она вернула бы что-то вроде [7.12,3], если линейное уравнение было y = 7.12 x + 3.

Ответы [ 7 ]

21 голосов
/ 01 июня 2011

Что за линейная регрессия? Для чего-то простого, например наименьших квадратов, я бы запрограммировал это сам:

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

По математике не так уж сложно следовать, сделайте укол в течение часа или около того и дайте мне знать, если это слишком сложно, я могу попробовать.

EDIT:

Нашел кого-то, кто это сделал:

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

10 голосов
/ 22 июля 2015

Самое простое решение, которое я нашел для данного вопроса, можно найти в следующем посте: http://trentrichardson.com/2010/04/06/compute-linear-regressions-in-javascript/

Обратите внимание, что в дополнение к линейному уравнению он также возвращает оценку R2, что может быть полезно.

** РЕДАКТИРОВАТЬ **

Вот фактический фрагмент кода:

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

Чтобы использовать это, вам просто нужно передать ему два массива, known_y's и known_x's, так что это то, что вы можете передать:

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
8 голосов
/ 22 июля 2013

Я нашел эту замечательную библиотеку JavaScript .

Это очень просто и, кажется, работает отлично.

Я также не могу рекомендовать Math.JS достаточно.

7 голосов
/ 20 октября 2012

Выезд https://web.archive.org/web/20150523035452/https://cgwb.nci.nih.gov/cgwbreg.html (калькулятор регрессии JavaScript) - чистый JavaScript, а не CGI-вызовы на сервер. Данные и обработка остаются на вашем компьютере. Заполните результаты в стиле R и код R для проверки работы и визуализации результатов.

См. Исходный код для встроенных JavaScript-реализаций OLS и статистику, связанную с результатами.

Код - моя попытка портировать функции библиотеки GSL на JavaScript.

Коды выпущены под лицензией GPL, потому что они в основном предназначены для линейного переноса лицензионного кода Gnu Scientific Library (GSL), лицензированного по GPL.

РЕДАКТИРОВАТЬ: Пол Лутус также предоставляет код GPL для регрессии по адресу: http://arachnoid.com/polysolve/index.html

4 голосов
/ 27 апреля 2012

Вот фрагмент, который будет принимать массив триплетов (x, y, r), где r - вес точки данных (x, y) и возвращать [a, b] так, что Y = a * X +б приблизительные данные.

// 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];
}
2 голосов
/ 04 марта 2017

Простая линейная регрессия с мерами вариации (Общая сумма квадратов = Сумма квадратов регрессии + Сумма ошибок квадратов), Стандартная ошибка оценки SEE (Остаточная стандартная ошибка) и коэффициенты определения R2 и корреляции 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 голос
/ 10 июня 2015

Отчасти основано на ответе Ника Мейбона.

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

Тогда y '= x * усиление + смещение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...