Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 数据集的简单线性回归_C#_.net_Statistics_Linear Algebra_Linear Regression - Fatal编程技术网

C# 数据集的简单线性回归

C# 数据集的简单线性回归,c#,.net,statistics,linear-algebra,linear-regression,C#,.net,Statistics,Linear Algebra,Linear Regression,我想在C#中为一组数据创建一个趋势函数,似乎使用一个大的数学库对我的需求来说有点过分了 给出一个值列表,如6,13,7,9,12,4,2,2,1。我想得到简单线性回归的斜率(看看它是递减还是递增)和下一个估计值。我知道有大量的图书馆可以做到这一点和更多,但我想要一个更简单的方法 我对统计不太在行,所以如果有人能引导我这样做,我将不胜感激 您不需要大量的库。公式相对简单 给定x和y数据的一对数组,计算最小二乘拟合系数如下 公式(27)和(28)是您想要的两个。编码只涉及输入数组值的平方和和和 下面

我想在C#中为一组数据创建一个趋势函数,似乎使用一个大的数学库对我的需求来说有点过分了

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


我对统计不太在行,所以如果有人能引导我这样做,我将不胜感激

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

给定x和y数据的一对数组,计算最小二乘拟合系数如下

公式(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;
    }
}

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

static void Main(字符串[]args)
{
双精度[]xVal=新双精度[9]
{
...
};
双精度[]yVal=新双精度[9]{
...
};
双平方;
双阴受体;
双坡;
线性回归(xVal,yVal,0,9,不平方,不平方,不平方,不斜率);
Console.WriteLine(yintercept+(slope*15));//15是未来的xvalue(从1开始的天数)
Console.ReadKey();
}
公共静态无效线性回归(双[]xVAL,双[]yVAL,
int inclusiveStart,int exclusiveEnd,
输出双平方,输出双平方,
出双坡)
{
Assert(xVals.Length==yVals.Length);
双相乘x=0;
双总和y=0;
双相乘xsq=0;
双总和YSQ=0;
双ssX=0;
双ssY=0;
双相沉积相=0;
双sCo=0;
双重计数=排他性-包容性开始;
对于(int ctr=inclusiveStart;ctr
google搜索
c#线性回归
显示了相当多的点击,似乎可以通过一个简单的函数满足您的需求。它们有什么不足之处?当我只关注一维数据集时,大多数处理的是二维元素的矩阵。它不是真正的一维。您只是暗示元素之间的间距相等。所以你似乎真的有[0,6],[1,13],[2,7],[3,9]等等。最终你似乎需要知道斜率和截距,这样你才能计算出下一个估计值。表面上看,这个似乎很有用:这个“相对简单”的配方让我有点大便你不应该害怕。这只不过是添加数字列表的总和,因为所使用的语法对于不熟悉它的读者来说并不直观。这是一个很好的例子,一个简单的例子可以极大地简化理解。我想我在五年前写这篇文章时不清楚需要多大的勺子来填充它。@duffymo字节大小的勺子总是很有用的。。)当我用0,1,2,3…馈送X数组时效果很好,Y数组也由线性递增的值组成。我知道数组X中的值与数组Y中的值之间的距离相同,所以它们应该线性增加,正如Chris Farmer所说的那样。当我向Y数组输入类似于:1,2,3,4,5,6,5,4,3,2,1的内容时,它无法再正确预测是不是因为该方法期望Y数组中的“大致”线性进度?当您绘制XY窗格时,X和Y都有线性进度,顺便问一下@Aristo,如果您将其放入excel并应用线性回归,它是否与输出值匹配
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);
    }
}
  static void Main(string[] args)
    {
        double[] xVal = new double[9]
        {

    ...


           };
        double[] yVal = new double[9]  {
     ...

        };
        double rsquared;
        double yintercept;
        double slope;
        LinearRegression(xVal, yVal,0,9, out rsquared, out yintercept, out slope);
        Console.WriteLine( yintercept + (slope*15));//15 is xvalue of future(no of day from 1)

        Console.ReadKey();
    }
    public static void LinearRegression(double[] xVals, double[] yVals,
                                        int inclusiveStart, int exclusiveEnd,
                                        out double rsquared, out double yintercept,
                                        out double slope)
    {
        Debug.Assert(xVals.Length == yVals.Length);
        double sumOfX = 0;
        double sumOfY = 0;
        double sumOfXSq = 0;
        double sumOfYSq = 0;
        double ssX = 0;
        double ssY = 0;
        double sumCodeviates = 0;
        double sCo = 0;
        double count = exclusiveEnd - inclusiveStart;

        for (int ctr = inclusiveStart; ctr < exclusiveEnd; ctr++)
        {
            double x = xVals[ctr];
            double y = yVals[ctr];
            sumCodeviates += x * y;
            sumOfX += x;
            sumOfY += y;
            sumOfXSq += x * x;
            sumOfYSq += y * y;
        }
        ssX = sumOfXSq - ((sumOfX * sumOfX) / count);
        ssY = sumOfYSq - ((sumOfY * sumOfY) / count);
        double RNumerator = (count * sumCodeviates) - (sumOfX * sumOfY);
        double RDenom = (count * sumOfXSq - (sumOfX * sumOfX))
         * (count * sumOfYSq - (sumOfY * sumOfY));
        sCo = sumCodeviates - ((sumOfX * sumOfY) / count);

        double meanX = sumOfX / count;
        double meanY = sumOfY / count;
        double dblR = RNumerator / Math.Sqrt(RDenom);
        rsquared = dblR * dblR;
        yintercept = meanY - ((sCo / ssX) * meanX);
        slope = sCo / ssX;
    }