Рассчитать линейную регрессию на основе данных в пределах диапазона, а не полного набора данных - PullRequest
0 голосов
/ 27 февраля 2019

Итак, в настоящее время скрипт, доступный по адресу: //rawgithub.com/phpepe/highcharts-regression/master/highcharts-regression.js, рассчитывает линейную регрессию для полного набора данных в серии.Можно ли изменить это для расчета линейной регрессии на основе данных в пределах диапазона.т.е. линейная регрессия за 1 месяц, линейная регрессия за 3 месяца ...

function _linear(data, decimalPlaces, extrapolate) {
    var sum = [0, 0, 0, 0, 0], n = 0, results = [], N = data.length;

    for (; n < data.length; n++) {
        if (data[n]['x'] != null) {
            data[n][0] = data[n].x;
            data[n][1] = data[n].y;
        }
        if (data[n][1] != null) {
            sum[0] += data[n][0]; //Σ(X)
            sum[1] += data[n][1]; //Σ(Y)
            sum[2] += data[n][0] * data[n][0]; //Σ(X^2)
            sum[3] += data[n][0] * data[n][1]; //Σ(XY)
            sum[4] += data[n][1] * data[n][1]; //Σ(Y^2)
        } else {
            N -= 1;
        }
    }

Я вижу, что в настоящее время она рассчитывает линейную регрессию для полной длины данных.Как я могу установить длину данных, чтобы быть в пределах выбранного диапазона.Я хочу, чтобы каждая отдельная линия регрессии отличалась от одной линии регрессии.

См. Jsfiddle: http://jsfiddle.net/x0pya5gt/

1 Ответ

0 голосов
/ 27 февраля 2019

highcharts-regression не имеет этой функции по умолчанию.Вы можете изменить regression.js и добавить эту функцию.Вы должны сначала загрузить код (очевидно) и поместить его куда-нибудь и включить файл в свой код.тогда вы должны изменить функцию processSerie следующим образом:

var processSerie = function (s, method, chart) {
    if (s.regression && !s.rendered) {
        s.regressionSettings = s.regressionSettings || {};
        s.regressionSettings.tooltip = s.regressionSettings.tooltip || {};
        s.regressionSettings.dashStyle = s.regressionSettings.dashStyle || 'solid';
        s.regressionSettings.decimalPlaces = s.regressionSettings.decimalPlaces || 2;
        s.regressionSettings.useAllSeries = s.regressionSettings.useAllSeries || false;
        s.regressionSettings.selectedRange = s.regressionSettings.selectedRange || []; // Add selectedRange for passing the range to regression.

        var regressionType = s.regressionSettings.type || "linear";
        var regression;
        var extraSerie = {
            data: [],
            color: s.regressionSettings.color || '',
            yAxis: s.yAxis,
            lineWidth: s.regressionSettings.lineWidth || 2,
            marker: {enabled: false},
            isRegressionLine: true,
            visible: s.regressionSettings.visible,
            type: s.regressionSettings.linetype || 'spline',
            name: s.regressionSettings.name || "Equation: %eq",
            id: s.regressionSettings.id,
            dashStyle: s.regressionSettings.dashStyle || 'solid',
            showInLegend: !s.regressionSettings.hideInLegend,
            tooltip: {
                valueSuffix: s.regressionSettings.tooltip.valueSuffix || ' '
            }
        };

        if (typeof s.regressionSettings.index !== 'undefined') {
            extraSerie.index = s.regressionSettings.index;
        }
        if (typeof s.regressionSettings.legendIndex !== 'undefined') {
            extraSerie.legendIndex = s.regressionSettings.legendIndex;
        }

        var mergedData = s.data;
        if (s.regressionSettings.useAllSeries) {
            mergedData = [];
            for (di = 0; di < series.length; di++) {
                var seriesToMerge = series[di];
                mergedData = mergedData.concat(seriesToMerge.data);
            }
        }

        if (regressionType == "linear") {
            var extrapolate = s.regressionSettings.extrapolate || 0;
            regression = _linear(mergedData, s.regressionSettings.decimalPlaces, extrapolate, s.regressionSettings.selectedRange); // Here you add selectedRange parameter for _linear function
            extraSerie.type = "line";
        } else if (regressionType == "exponential") {
            var extrapolate = s.regressionSettings.extrapolate || 0;
            regression = _exponential(mergedData, extrapolate);
        }
        else if (regressionType == "polynomial") {
            var order = s.regressionSettings.order || 2;
            var extrapolate = s.regressionSettings.extrapolate || 0;
            regression = _polynomial(mergedData, order, extrapolate);
        } else if (regressionType == "power") {
            var extrapolate = s.regressionSettings.extrapolate || 0;
            regression = _power(mergedData, extrapolate);
        } else if (regressionType == "logarithmic") {
            var extrapolate = s.regressionSettings.extrapolate || 0;
            regression = _logarithmic(mergedData, extrapolate);
        } else if (regressionType == "loess") {
            var loessSmooth = s.regressionSettings.loessSmooth || 25;
            regression = _loess(mergedData, loessSmooth / 100);
        } else {
            console.error("Invalid regression type: ", regressionType);
            return;
        }

        regression.rSquared = coefficientOfDetermination(mergedData, regression.points);
        regression.rValue = _round(Math.sqrt(regression.rSquared), s.regressionSettings.decimalPlaces);
        regression.rSquared = _round(regression.rSquared, s.regressionSettings.decimalPlaces);
        regression.standardError = _round(standardError(mergedData, regression.points), s.regressionSettings.decimalPlaces);
        extraSerie.data = regression.points;
        extraSerie.name = extraSerie.name.replace("%r2", regression.rSquared);
        extraSerie.name = extraSerie.name.replace("%r", regression.rValue);
        extraSerie.name = extraSerie.name.replace("%eq", regression.string);
        extraSerie.name = extraSerie.name.replace("%se", regression.standardError);

        if (extraSerie.visible === false) {
            extraSerie.visible = false;
        }
        extraSerie.regressionOutputs = regression;
        return extraSerie;

    }
}

рассмотрите добавленную строку:

        s.regressionSettings.selectedRange = s.regressionSettings.selectedRange || []; // Add selectedRange for passing the range to regression.

И эту строку, которая изменяется:

        regression = _linear(mergedData, s.regressionSettings.decimalPlaces, extrapolate, s.regressionSettings.selectedRange); // Here you add selectedRange parameter for _linear function

Тогда в _linear функция, вы должны добавить эти изменения:

function _linear(data, decimalPlaces, extrapolate, selectedRange) {
    var sum = [0, 0, 0, 0, 0], n = 0, i = 0, results = [], N = data.length;

    for (; i < data.length; i++) {
        if (selectedRange.length == 2)
            if (i < selectedRange[0] || i > selectedRange[1])
                continue;
        if (data[n]['x'] != null) {
            data[n][0] = data[n].x;
            data[n][1] = data[n].y;
        }
        if (data[n][1] != null) {
            sum[0] += data[n][0]; //Σ(X)
            sum[1] += data[n][1]; //Σ(Y)
            sum[2] += data[n][0] * data[n][0]; //Σ(X^2)
            sum[3] += data[n][0] * data[n][1]; //Σ(XY)
            sum[4] += data[n][1] * data[n][1]; //Σ(Y^2)
        } else {
            N -= 1;
    }

n ++;}

Снова рассмотрите возможность добавления selectedRange к параметрам функции и добавленным ниже строкам:

        if (selectedRange.length == 2)
            if (i < selectedRange[0] || i > selectedRange[1])
                continue;

И i = 0 и n++.

Наконецчтобы использовать его, вы можете передать свойство selectedRange в regressionSetting объект, который вы используете в своей серии.

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