数据集的简单线性回归

时间:2013-03-25 19:30:36

标签: c# .net statistics linear-algebra linear-regression

我希望在C#中为一组数据创建一个趋势函数,看起来使用大型数学库对我的需求来说有点过分。

给出一个值列表,如6,13,7,9,12,4,2,2,1。我想获得简单线性回归的斜率(看它是否正在减少或增加)和下一个估计值。我知道有大量的库可以做到这一点,但我想要一个更简单的方法。

我对统计数据并不重视,所以如果有人能以某种方式引导我做这件事,我们将不胜感激。

2 个答案:

答案 0 :(得分:5)

我自己的未来预测代码(从第一天开始的第15天的示例)

 No such file or directory at ./spl.pl line 10, <> line 2.

答案 1 :(得分:4)

您不需要大量的库。公式相对简单。

给出x和y数据的一对数组,你将计算最小二乘拟合系数,如this

公式(27)和(28)是你想要的两个。编码只涉及输入数组值的和和平方和。

这是一个Java类及其JUnit测试类,适合那些想要更多细节的人:

import java.util.Arrays;

/**
 * Simple linear regression example using Wolfram Alpha formulas.
 * User: mduffy
 * Date: 10/22/2018
 * Time: 10:56 AM
 * @link https://stackoverflow.com/questions/15623129/simple-linear-regression-for-data-set/15623183?noredirect=1#comment92773017_15623183
 */
public class SimpleLinearRegressionExample {

    public static double slope(double [] x, double [] y) {
        double slope = 0.0;
        if ((x != null) && (y != null) && (x.length == y.length) && (x.length > 0)) {
            slope = correlation(x, y)/sumOfSquares(x);
        }
        return slope;
    }

    public static double intercept(double [] x, double [] y) {
        double intercept = 0.0;
        if ((x != null) && (y != null) && (x.length == y.length) && (x.length > 0)) {
            double xave = average(x);
            double yave = average(y);
            intercept = yave-slope(x, y)*xave;
        }
        return intercept;
    }

    public static double average(double [] values) {
        double average = 0.0;
        if ((values != null) && (values.length > 0)) {
            average = Arrays.stream(values).average().orElse(0.0);
        }
        return average;
    }

    public static double sumOfSquares(double [] values) {
        double sumOfSquares = 0.0;
        if ((values != null) && (values.length > 0)) {
            sumOfSquares = Arrays.stream(values).map(v -> v*v).sum();
            double average = average(values);
            sumOfSquares -= average*average*values.length;
        }
        return sumOfSquares;
    }

    public static double correlation(double [] x, double [] y) {
        double correlation = 0.0;
        if ((x != null) && (y != null) && (x.length == y.length) && (x.length > 0)) {
            for (int i = 0; i < x.length; ++i) {
                correlation += x[i]*y[i];
            }
            double xave = average(x);
            double yave = average(y);
            correlation -= xave*yave*x.length;
        }
        return correlation;
    }
}

JUnit测试类:

import org.junit.Assert;
import org.junit.Test;

/**
 * JUnit tests for simple linear regression example.
 * User: mduffy
 * Date: 10/22/2018
 * Time: 11:53 AM
 * @link https://stackoverflow.com/questions/15623129/simple-linear-regression-for-data-set/15623183?noredirect=1#comment92773017_15623183
 */
public class SimpleLinearRegressionExampleTest {

    public static double tolerance = 1.0e-6;

    @Test
    public void testAverage_NullArray() {
        // setup
        double [] x = null;
        double expected = 0.0;
        // exercise
        double actual = SimpleLinearRegressionExample.average(x);
        // assert
        Assert.assertEquals(expected, actual, tolerance);
    }

    @Test
    public void testAverage_EmptyArray() {
        // setup
        double [] x = {};
        double expected = 0.0;
        // exercise
        double actual = SimpleLinearRegressionExample.average(x);
        // assert
        Assert.assertEquals(expected, actual, tolerance);
    }

    @Test
    public void testAverage_Success() {
        // setup
        double [] x = { 1.0, 2.0, 2.0, 3.0, 4.0, 7.0, 9.0 };
        double expected = 4.0;
        // exercise
        double actual = SimpleLinearRegressionExample.average(x);
        // assert
        Assert.assertEquals(expected, actual, tolerance);
    }


    @Test
    public void testSumOfSquares_NullArray() {
        // setup
        double [] x = null;
        double expected = 0.0;
        // exercise
        double actual = SimpleLinearRegressionExample.sumOfSquares(x);
        // assert
        Assert.assertEquals(expected, actual, tolerance);
    }

    @Test
    public void testSumOfSquares_EmptyArray() {
        // setup
        double [] x = {};
        double expected = 0.0;
        // exercise
        double actual = SimpleLinearRegressionExample.sumOfSquares(x);
        // assert
        Assert.assertEquals(expected, actual, tolerance);
    }

    @Test
    public void testSumOfSquares_Success() {
        // setup
        double [] x = { 1.0, 2.0, 2.0, 3.0, 4.0, 7.0, 9.0 };
        double expected = 52.0;
        // exercise
        double actual = SimpleLinearRegressionExample.sumOfSquares(x);
        // assert
        Assert.assertEquals(expected, actual, tolerance);
    }

    @Test
    public void testCorrelation_NullX_NullY() {
        // setup
        double [] x = null;
        double [] y = null;
        double expected = 0.0;
        // exercise
        double actual = SimpleLinearRegressionExample.correlation(x, y);
        // assert
        Assert.assertEquals(expected, actual, tolerance);
    }

    @Test
    public void testCorrelation_DifferentLengths() {
        // setup
        double [] x = { 1.0, 2.0, 3.0, 5.0, 8.0 };
        double [] y = { 0.11, 0.12, 0.13, 0.15, 0.18, 0.20 };
        double expected = 0.0;
        // exercise
        double actual = SimpleLinearRegressionExample.correlation(x, y);
        // assert
        Assert.assertEquals(expected, actual, tolerance);
    }

    @Test
    public void testCorrelation_Success() {
        // setup
        double [] x = { 1.0, 2.0, 3.0, 5.0, 8.0 };
        double [] y = { 0.11, 0.12, 0.13, 0.15, 0.18 };
        double expected = 0.308;
        // exercise
        double actual = SimpleLinearRegressionExample.correlation(x, y);
        // assert
        Assert.assertEquals(expected, actual, tolerance);
    }

    @Test
    public void testSlope() {
        // setup
        double [] x = { 1.0, 2.0, 3.0, 4.0 };
        double [] y = { 6.0, 5.0, 7.0, 10.0 };
        double expected = 1.4;
        // exercise
        double actual = SimpleLinearRegressionExample.slope(x, y);
        // assert
        Assert.assertEquals(expected, actual, tolerance);
    }

    @Test
    public void testIntercept() {
        // setup
        double [] x = { 1.0, 2.0, 3.0, 4.0 };
        double [] y = { 6.0, 5.0, 7.0, 10.0 };
        double expected = 3.5;
        // exercise
        double actual = SimpleLinearRegressionExample.intercept(x, y);
        // assert
        Assert.assertEquals(expected, actual, tolerance);
    }
}
相关问题