最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。

利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小。

public class RegLinear
{
    public double A
    {
        get;
        private set;
    }

    public double B
    {
        get;
        private set;
    }

    public double R2
    {
        get;
        private set;
    }

    private double[] OriginX = null;
    private double[] OriginY = null;
    public ShRegLinear()
    {
        // Y = a * X + b
        this.A = 0.0;
        this.B = 0.0;
    }

    //  外面应该剔除无效值以后再传进来,里面不做判断
    public void SetOriginData(double[] x, double[] y)
    {
        this.OriginX = x;
        this.OriginY = y;
    }

    public bool CalculateRegression()
    {
        if (this.OriginX == null || this.OriginX.Length < 3 ||
                this.OriginY == null || this.OriginX.Length != this.OriginY.Length)
            return false;

        // 最小二乘法 https://zh.wikipedia.org/wiki/%E6%9C%80%E5%B0%8F%E4%BA%8C%E4%B9%98%E6%B3%95
        double averX = this.OriginX.Average();
        double averY = this.OriginY.Average();

        double differencexy = 0.0;
        double sumxy = 0.0;
        double sumx = 0.0;
        double sumy = 0.0;
        for (int i = 0; i < this.OriginX.Length; i++)
        {
            differencexy += (this.OriginX[i] - averX) * (this.OriginY[i] - averY);
            sumxy += this.OriginX[i] * this.OriginY[i];
            sumx += Math.Pow((this.OriginX[i] - averX), 2);
            sumy += Math.Pow((this.OriginY[i] - averY), 2);
        }
        // 经验回归系数
        this.A = differencexy / sumx;
        this.B = averY - this.A * averX;
        this.R2 = Math.Pow(differencexy, 2) / (sumx * sumy);
        return true;
    }

    public double CalculateValue(double x)
    {
        return (this.A * x + this.B);
    }

    public double[] GetResult()
    {
        double[] result = new double[]
        {
            this.A,
            this.B,
        };
        return result;
    }

    public double GetR2()
    {
        return this.R2;
    }
}