Регрессия, которая соответствует лучшему графику рассеяния - PullRequest
0 голосов
/ 09 мая 2018

У меня есть следующий график рассеяния, и я хочу добавить линейную полиномиальную регрессию (наиболее подходящую) к моим данным. Есть ли простой способ сделать это?

Моя диаграмма проста, сделана библиотекой c3 v4 (в зависимости от d3 v3):

            <div id="chart2"></div>
            <script>
                var chart = c3.generate({
                    bindto: '#chart2',
                    data: {
                        url: '../static/CSV/Chart_data/grades_access.csv'+(new Date).getTime(),
                        x:'Access_grade',
                        type: 'scatter'
                    },
                    axis: {
                        y: {
                            label: {
                                text:"Average grade",
                                position: "outer-middle"
                            },
                            min:1,
                            max:9
                        },
                        x: {
                            label: {
                                text:"Access grade PAU",
                                position: "outer-center"
                            },
                            min:9,
                            max:14
                        }
                    },
                    size: {
                        height: 400,
                        width: 800
                    },
                    zoom: {
                        enabled: true
                    },
                    legend: {
                        show: true,
                        position: 'inset',
                        inset: {
                            anchor: 'top-right',
                            x: 20,
                            y: 300,
                            step: 1
                        }
                    }     
                }); 
            </script>

И grades_access.csv это:

Access_grade,Subject
9.85,2.5
10.64,8.1
10.0,3.2
10.92,4.0
11.69,2.9
11.79,7.8
11.03,5.0
10.47,6.2
...

Может ли кто-нибудь дать мне подсказку? Я хочу простую вещь, не слишком изощренную. Но с уравнением регрессии, если это возможно :) Спасибо!

1 Ответ

0 голосов
/ 09 мая 2018

Я пару раз отвечал на этот вопрос для других библиотек , но никогда c3.js. Вот код для соответствия линейной регрессии с использованием простого метода наименьших квадратов. Он делает это onrendered, так что вы все еще можете использовать способность c3 для получения и анализа вашего CSV-файла:

<div id="chart2"></div>
<script>
    var chart = c3.generate({
      bindto: '#chart2',
      data: {
        url: 'data.csv',
        x: 'Access_grade',
        type: 'scatter'
      },
      axis: {
        y: {
          label: {
            text: "Average grade",
            position: "outer-middle"
          },
          min: 1,
          max: 9
        },
        x: {
          label: {
            text: "Access grade PAU",
            position: "outer-center"
          },
          min: 9,
          max: 14
        }
      },
      size: {
        height: 400,
        width: 800
      },
      zoom: {
        enabled: true
      },
      legend: {
        show: true,
        position: 'inset',
        inset: {
          anchor: 'top-right',
          x: 20,
          y: 300,
          step: 1
        }
      },

      onrendered: function(c) {
        var points = chart.data()[0].values.map((d) => [d.x, d.value]),
          slopeIntercept = slopeAndIntercept(points),
          fitPoints = chart.data()[0].values.map((d) => slopeIntercept.slope * d.x + slopeIntercept.intercept);

        chart.load({
          columns: [
            ['Regression'].concat(fitPoints)
          ],
          type: 'line'
        });
      }
    });

    // simple linear regression
    slopeAndIntercept = function(points) {
      var rV = {},
        N = points.length,
        sumX = 0,
        sumY = 0,
        sumXx = 0,
        sumYy = 0,
        sumXy = 0;

      // can't fit with 0 or 1 point
      if (N < 2) {
        return rV;
      }

      for (var i = 0; i < N; i++) {
        var x = points[i][0],
          y = points[i][1];
        sumX += x;
        sumY += y;
        sumXx += (x * x);
        sumYy += (y * y);
        sumXy += (x * y);
      }

      // calc slope and intercept
      rV['slope'] = ((N * sumXy) - (sumX * sumY)) / (N * sumXx - (sumX * sumX));
      rV['intercept'] = (sumY - rV['slope'] * sumX) / N;
      rV['rSquared'] = Math.abs((rV['slope'] * (sumXy - (sumX * sumY) / N)) / (sumYy - ((sumY * sumY) / N)));

      return rV;
    }
</script>

Вот пример работы .

...