javascript D3.js 线性回归

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20507536/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 18:38:24  来源:igfitidea点击:

D3.js linear regression

javascriptd3.jslinear-regression

提问by tomtomtom

I searched for some help on building linear regression and found some examples here:
nonlinear regression function
and also some js libraries that should cover this, but unfortunately I wasn't able to make them work properly:
simple-statistics.jsand this one: regression.js
With regression.jsI was able to get the mand bvalues for the line, so I could use y = m*x + bto plot the line that followed the linear regression of my graph, but couldn't apply those values to the line generator, the code I tried is the following:

我搜索了一些关于构建线性回归的帮助,并在这里找到了一些示例:
非线性回归函数
以及一些应该涵盖这一点的 js 库,但不幸的是我无法使它们正常工作:
simple-statistics.js和这个:Regression.js
因为regression.js我能够获得线的mb值,所以我可以y = m*x + b用来绘制跟随我的图形的线性回归的线,但不能将这些值应用于线生成器,我尝试的代码是下列:

d3.csv("typeStatsTom.csv", function (error, dataset) {
//Here I plot other stuff, setup the x & y scale correctly etc. 
//Then to plot the line:

        var data = [x.domain(), y.domain()];
        var result = regression('linear', data);
        console.log(result)
        console.log(result.equation[0]);
        var linereg = d3.svg.line()
                        .x(function (d) { return x(d.Ascendenti); })
                        .y(function (d) { return y((result.equation[0] * d.Ascendenti) + result.equation[1]); });
        var reglinepath = svg.append("path")
                            .attr("class", "line")
                            .attr("d", linereg(dataset))
                            .attr("fill", "none")
                            .attr("stroke", "#386cb0")
                            .attr("stroke-width", 1 + "px");

The values of result are the following in the console:

结果在控制台中的值如下:

    Object
      equation: Array[2]
        0: 1.8909425770308126
        1: 0.042557422969139225
      length: 2
      __proto__: Array[0]
      points: Array[2]
      string: "y = 1.89x + 0.04"
      __proto__: Object

From what I can tell in the console I should have set up the xand yvalues correctly, but of course the path in the resulting svg is not shown (but drawn), so I don't know what to do anymore.
Any help is really really appreciated, even a solution involving the simple.statistics.jslibrary would be helpful!
Thanks!

从我在控制台中可以看出,我应该正确设置xy值,但是当然没有显示(但绘制)生成的 svg 中的路径,所以我不知道该怎么做了。
真的非常感谢任何帮助,即使是涉及simple.statistics.js图书馆的解决方案也会有所帮助!
谢谢!

回答by tomtomtom

I made it work using the following code found here:

我使用此处找到的以下代码使其工作:

   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;

};

var yval = dataset.map(function (d) { return parseFloat(d.xHeight); });
var xval = dataset.map(function (d) { return parseFloat(d.Ascendenti); });


var lr = linearRegression(yval,xval);
// now you have:
// lr.slope
// lr.intercept
// lr.r2
console.log(lr);

And then plotting a line with:

然后绘制一条线:

var max = d3.max(dataset, function (d) { return d.OvershootingSuperiore; });
var myLine = svg.append("svg:line")
            .attr("x1", x(0))
            .attr("y1", y(lr.intercept))
            .attr("x2", x(max))
            .attr("y2", y( (max * lr.slope) + lr.intercept ))
            .style("stroke", "black");

Using the code I found here

使用我在这里找到的代码

回答by couchand

It looks to me like your path is getting drawn, just way off the screen.

在我看来,您的路径正在绘制,就在屏幕外。

path element in firebug

firebug中的路径元素

Perhaps the regression is calculated incorrectly? The problem may be on line 202:

也许回归计算不正确?问题可能出在202行:

var data = [x.domain(), y.domain()];
var result = regression('linear', data);

If the raw data looks like [[1, 500], [2, 300]]this will find the linear regression of [[1, 2], [300, 500]which probably isn't what you want.

如果原始数据看起来像[[1, 500], [2, 300]]这样,则会发现其线性回归[[1, 2], [300, 500]可能不是您想要的。

I'm guessing what you'd like to do is compute the regression with the entire set of data points rather than with the graph's bounds. Then rather than charting this line for every data value, you want to just plot the endpoints.

我猜你想做的是用整个数据点集而不是图的边界来计算回归。然后,您不想为每个数据值绘制这条线,而是只想绘制端点。