Javascript D3.js线性回归

Javascript D3.js线性回归,javascript,d3.js,linear-regression,Javascript,D3.js,Linear Regression,我搜索了一些关于构建线性回归的帮助,并在这里找到了一些示例: 还有一些js库应该涵盖这一点,但不幸的是,我无法使它们正常工作: 还有这个: 使用regression.js,我能够获得直线的m和b值,因此我可以使用y=m*x+b绘制曲线图线性回归后的直线,但无法将这些值应用到直线生成器,我尝试的代码如下: d3.csv("typeStatsTom.csv", function (error, dataset) { //Here I plot other stuff, setup the x &am

我搜索了一些关于构建线性回归的帮助,并在这里找到了一些示例: 还有一些js库应该涵盖这一点,但不幸的是,我无法使它们正常工作: 还有这个: 使用regression.js,我能够获得直线的m和b值,因此我可以使用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");
控制台中的结果值如下所示:

    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

从控制台中可以看出,我应该正确设置x和y值,但当然,结果svg中的路径不是显示而是绘制的,因此我不知道该怎么做。非常感谢您的帮助,即使是包含simple.statistics.js库的解决方案也会很有帮助!谢谢

在我看来,你的道路正在画出来,离屏幕很远

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

var data = [x.domain(), y.domain()];
var result = regression('linear', data);
如果原始数据看起来像[[1500],[2300]],这将找到[[1,2],[300500]的线性回归,这可能不是您想要的


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

我使用以下代码实现了这一点:


使用我找到的代码

从github加载的regression.js在JSFIDLE中出现错误,因此无法正常工作。不幸的是,这是我的dropbox中的文件tho:看起来你到处都在显式调用各种生成器。我不确定这是否与你遇到的问题有关,但它可能会对你有所帮助花些时间学习惯用D3。与其显式地对数据调用linereg,不如将数据绑定到一个选择,然后让D3负责调用生成器。有关选择的更多信息,请参阅Mike Bostock的教程。如果您指的是D3.selectelenco2之类的部件,那是因为我必须对其进行更新我用'linereg'尝试的是用d3的线生成器设置函数'y=m*x+b'。我的问题实际上是如何设置线生成器来绘制一条从'result'获取数据的线。编辑:在我的键盘上,我没有正确的'代码,sorryA旁注:有很多地方可以让D3变得更简单,调试也更容易-你可以检查DOM中的数据!通过利用数据绑定:第115-118行可以使用通用行生成器,第140-159行的鼠标悬停处理程序,以及你提到的从第295行开始的更改处理程序。你可以将数字传递给D3您还可以通过删除URL中的.between-raw和GitHub;-嘿,感谢您的输入,但由于我不是一个真正的程序员,我不知道如何改进这一点以使您突出显示的行更简单…我知道可能有许多冗余行等,但不幸的是,我无法使其正常工作,我的编码知识仅限于简单的html和css以及一些d3.js,因此在控制台中没有奇怪的错误警告已经是一项成就:是的,你指出的是正确的,事实上,这正是我所问的:我使用的域是我所使用的数据的极值对于圆,我认为如果我有这两个点,这条线无论如何都会通过我使用这条线得到它的方式生成:我还尝试使用:var assex=[dataset.mapfunction d{return d.Ascendenti;}];var assey=[dataset.mapfunction d{return d.xHeight;}];但这样我无法获得所需的数组,因为它需要[[x0,y0],[x1,y1]…[xn,yn]]离开代码的最后一部分,我尝试创建一个包含每个点的值的数组,如下所示:var coord=dataset.mapfunction d{return[d.astenti+,+d.xHeight];};这实际上返回了一个数组,其中包含每对x和y值,但是var结果的控制台日志记录为NaN,所以我真的不知道现在该怎么办,我有点不知所措。你为什么要进行字符串连接?如果你只返回两个元素的数组,而不是将它们转换为strin,那么你被截取的代码应该可以正常工作g:var coord=dataset.mapfunction d{return[d.Ascendenti,d.xHeight];};好的,我设法获得了拦截器和斜率值,问题是这些值是作为字符串而不是值添加到数组中的,所以我在值前面添加了parseFloat。我还使用了这个
   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);
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");