最小二乘法C#实现,简单代码

来源:互联网 发布:淘宝商城女包特卖 编辑:程序博客网 时间:2024/05/12 16:07

根据http://zh.wikipedia.org/wiki/%E6%9C%80%E5%B0%8F%E4%BA%8C%E4%B9%98%E6%B3%95里面的说法:

线性函数模型

典型的一类函数模型是线性函数模型。最简单的线性式是y = b_0 + b_1 t,写成矩阵式,为

 \min_{b_0,b_1}\left\|\begin{pmatrix}1 & t_1 \\ \vdots & \vdots \\ 1 & t_n  \end{pmatrix} \begin{pmatrix} b_0\\ b_1\end{pmatrix} - \begin{pmatrix} y_1 \\ \vdots \\ y_{n}\end{pmatrix}\right\|_{2} = \min_b\|Ab-Y\|_2.

直接给出该式的参数解:

b_1 = \frac{\sum_{i=1}^n t_iy_i - n \cdot \bar t \bar y}{\sum_{i=1}^n t_i^2- n \cdot (\bar t)^2} 和 b_0 = \bar y - b_1 \bar t

其中\bar t = \frac{1}{n} \sum_{i=1}^n t_i,为t值的算术平均值。也可解得如下形式:

b_1 = \frac{\sum_{i=1}^n (t_i - \bar t)(y_i - \bar y)}{\sum_{i=1}^n (t_i - \bar t)^2}
b1为斜率,b0为截距,可以先根据x,y数组,以及上面的公式先计算出斜率,再计算截距。

因为原来参考代码中,返回为一个数组,根据与原来代码的兼容性,调用LinearResult(double[],double[])方法返回是一个数组。result[0]为斜率,result[1]为截距。

 class Linear    {        public double[] LinearResult(double[] arrayX, double[] arrayY)        {            double[] result = { 0, 0 };            if (arrayX.Length == arrayY.Length)            {                double averX = arrayX.Average();                double averY = arrayY.Average();                result[0] = Scale(averX, averY, arrayX, arrayY);                result[1] = Offset(result[0],averX,averY);            }            return result;        }        private double Scale(double averX, double averY, double[] arrayX, double[] arrayY)        {            double scale = 0;            if (arrayX.Length == arrayY.Length)            {                double Molecular = 0;                double Denominator = 0;                for (int i = 0; i < arrayX.Length; i++)                {                    Molecular += (arrayX[i] - averX) * (arrayY[i] - averY);                    Denominator += Math.Pow((arrayX[i] - averX), 2);                }                scale = Molecular / Denominator;            }            return scale;        }        private double Offset(double scale, double averX,double averY)        {            double offset = 0;            offset = averY - scale * averX;            return offset;        }    }



0 1
原创粉丝点击