二元线性回归的部分相关代码整理及说明。

来源:互联网 发布:淘宝卖家祝福语范文 编辑:程序博客网 时间:2024/06/05 05:28

一、原始数据

    说明:

Y---结果数据    Xi---变量 (共k个)    n组已知实验数据

Y

X1

X2

………

Xk

Y1

X11

X21

………

Xk1

Y2

X12

X22

………

Xk2

………

Yn

X1n

X2n

 

Xkn

 

二、有一可知其线性回归方程模式

Y=bo+b1 X1+b2 X2+………+bk Xk (+u); u:正太 分布

 

则有:

Y1     =         1    X11               X21                 …        Xk1     b0        u1

Y2    =     1         X12               X22                 …        Xk2     b1     +   u2

…    =        1        …          …           …        …   …         …

Yn       =        1         X1n               X2n                Xkn     bk        uk

 

令Y,X,B,U依次对应,经过整理后可得:

  XXB^=XY,   即B^=(XX)-1XY。


三、相关代码:


       //矩阵的转置     k+1(n)


        public double[,] MatrixTranspose(double[,] tempArray)
        {                  
          double[,] tempArrayT = new double[tempArray.GetLength(1),tempArray.GetLength(0) ];
            //MessageBox.Show(tempArray.Rank);
            //MessageBox.Show(tempArray.GetLength(1));


            for (int i=0;i<tempArray.GetLength(0);i++)  //行数
            {
                for(int j=0;j<tempArray.GetLength(1);j++)  //列数
                {
                    tempArrayT[j, i] = tempArray[i, j];
                }
            }
    
            return tempArrayT;
        }

       //矩阵相乘  temparray1*tempArray2
        public double[,] MatrixMul(double[,] tempArray1, double[,] tempArray2)
        {          
            int a = tempArray1.GetLength(0);//返回矩阵的行数  转置矩阵
            int b = tempArray2.GetLength(1);//获取指定维度中的元素个数,即返回矩阵的列数;
            double[,] tempArray3 = new double[a, b];


            //乘法运算
            double sum = 0.0;    //初次测试时没有考虑sum值的重新初始化问题。 通过简单实例数据测试才发现。
            for (int i = 0; i < tempArray1.GetLength(0); i++)
            {
                for (int j = 0; j < tempArray2.GetLength(1); j++)
                {    
                    sum=0.0;
                    for (int k = 0; k < tempArray1.GetLength(1); k++)
                    {
                        sum += tempArray1[i, k] * tempArray2[k, j];
                    }
                    tempArray3[i, j] = sum;
                }


            }


            return tempArray3;
        }


   //矩阵求逆
        public static double[,] Matrix_Ni(double[,] Array)
        {
            int m = 0;
            int n = 0;
            m = Array.GetLength(0);
            n = Array.GetLength(1);
            double[,] array = new double[2 * m + 1, 2 * n + 1];
            for (int k = 0; k < 2 * m + 1; k++)  //初始化数组
            {
                for (int t = 0; t < 2 * n + 1; t++)
                {
                    array[k, t] = 0.00000000;
                }
            }
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    array[i, j] = Array[i, j];
                }
            }


            for (int k = 0; k < m; k++)
            {
                for (int t = n; t <= 2 * n; t++)
                {
                    if ((t - k) == m)
                    {
                        array[k, t] = 1.0;
                    }
                    else
                    {
                        array[k, t] = 0;
                    }
                }
            }

     
            for (int k = 0; k < m; k++)
            {
                if (array[k, k] != 1)
                {
                    double bs = array[k, k];
                    array[k, k] = 1;
                    for (int p = k + 1; p < 2 * n; p++)
                    {
                        array[k, p] /= bs;
                    }
                }
                for (int q = 0; q < m; q++)
                {
                    if (q != k)
                    {
                        double bs = array[q, k];
                        for (int p = 0; p < 2 * n; p++)
                        {
                            array[q, p] -= bs * array[k, p];
                        }
                    }
                    else
                    {
                        continue;
                    }
                }
            }
            double[,] NI = new double[m, n];
            for (int x = 0; x < m; x++)
            {
                for (int y = n; y < 2 * n; y++)
                {
                    NI[x, y - n] = array[x, y];
                }
            }
            return NI;
        }



     四、对多元线性回归的检测

    #region 对多元线性回归的检测


        //拟合程度的测定  R2(R的平方)=E(Y的拟合结果-y的平均值)的平方
        public void DeterminationFittingDegree(DataSet tempDS ,double b0,double b1,double b2,double[,]NIjuzhen)
        { 
            double S1=0.0;    //回归平方和;即总变差平方和中有回归方程解释的部分
            double S2 = 0.0; //残差平方和;即总变差平方和中未被回归方程解释的部分,有解释变量X中未包含的一切因素对被解释变量Y影响而造成的
            double R2 = 0.0;//拟合程度:越接近1,拟合程度越高
            double R22 = 0.0;
            double YY = 0.0;//存放Y的平均值


            b0 = double.Parse(textBox0.Text);
            b1 = double.Parse(textBox1.Text);
            b2 = double.Parse(textBox2.Text);


            string X1 = TxtX1.Text.ToString().Trim();
            string X2 = TxtX2.Text.ToString().Trim();
            string Y = TxtY.Text.ToString().Trim();
            
            //求Y的平均值
            for (int i = 0; i < tempDS.Tables["DuoyuanNiHe"].Rows.Count; i++)
            {
                YY += double.Parse(tempDS.Tables["DuoyuanNiHe"].Rows[i][Y].ToString());
            }
            YY = YY / tempDS.Tables["DuoyuanNiHe"].Rows.Count;


            //求S1:回归平方和
            for (int i = 0; i < tempDS.Tables["DuoyuanNiHe"].Rows.Count;i++)
            {
                S1 += (b1 * double.Parse(tempDS.Tables["DuoyuanNiHe"].Rows[i][X1].ToString()) + b2 * double.Parse(tempDS.Tables["DuoyuanNiHe"].Rows[i][X2].ToString()) + b0 - YY)*
                      (b1 * double.Parse(tempDS.Tables["DuoyuanNiHe"].Rows[i][X1].ToString()) + b2 * double.Parse(tempDS.Tables["DuoyuanNiHe"].Rows[i][X2].ToString()) + b0 - YY);
            }


            //求S2:总变差
            for (int i = 0; i < tempDS.Tables["DuoyuanNiHe"].Rows.Count; i++)
            {
                S2 += (double.Parse(tempDS.Tables["DuoyuanNiHe"].Rows[i][Y].ToString()) - YY) *
                      (double.Parse(tempDS.Tables["DuoyuanNiHe"].Rows[i][Y].ToString()) - YY);
            }


            R2 = S1 / S2;
            MessageBox.Show(R2.ToString(), "拟合程度", MessageBoxButtons.OK, MessageBoxIcon.Information);
        
            ///<summary>
            ///回归方程的显著性检验:  因为需要用到S1和S2,故此程序直接在拟合程度方法中检验
            /// </ summary >
            double F = 0.0;//统计量
            double S3 = 0.0;  //y-y的平方和


         //   S1 /= 2;//////////////   2指自变量的个数,需要手动修改         //////////////////////////


            for (int i = 0; i < tempDS.Tables["DuoyuanNiHe"].Rows.Count; i++)
            {
                S3 += (double.Parse(tempDS.Tables["DuoyuanNiHe"].Rows[i][Y].ToString()) - 
                      (b1 * double.Parse(tempDS.Tables["DuoyuanNiHe"].Rows[i][X1].ToString()) + b2 * double.Parse(tempDS.Tables["DuoyuanNiHe"].Rows[i][X2].ToString()) + b0))*
                      (double.Parse(tempDS.Tables["DuoyuanNiHe"].Rows[i][Y].ToString()) - 
                      (b1 * double.Parse(tempDS.Tables["DuoyuanNiHe"].Rows[i][X1].ToString()) + b2 * double.Parse(tempDS.Tables["DuoyuanNiHe"].Rows[i][X2].ToString()) + b0));
            }
            //     S3 /= tempDS.Tables["DuoyuanNiHe"].Rows.Count - 2 - 1;//////////////   2指自变量的个数,需要手动修改         ////////////////


            //     F = (S1/2) / (S3/ (tempDS.Tables["DuoyuanNiHe"].Rows.Count - 2 - 1));
            F = S1 * (tempDS.Tables["DuoyuanNiHe"].Rows.Count - 2 - 1) / 2 / S3;
            MessageBox.Show(F.ToString());
            if(F>(3.23+6.01)/2)
            {
                MessageBox.Show("回归方程具有显著意义");
            }
            else
            {
                MessageBox.Show("回归效果不明显");
            }






            ///估计标准误差  即因变量y的实际值与回归方程求出的估计值 之间的标准误差,
            ///估计标准误差越小,回归方程拟合程度越高
            double Sy = S3 / (20 - 2 - 1);
                Sy= Math.Pow(Sy, 0.5);
            MessageBox.Show(Sy.ToString(), "估计标准误差", MessageBoxButtons.OK, MessageBoxIcon.Information);


            ///回归系数的显著性检验
             /*         //X1的检验
            PrintArray(NIjuzhen);
            double t1 = b1 / (Sy * Math.Pow(NIjuzhen[1, 1], 0.5));
      /*      TxtShow.AppendText("b1=");
            TxtShow.AppendText(b1.ToString());
            TxtShow.AppendText("\r\n");
            TxtShow.AppendText("Sy=");
            TxtShow.AppendText(Sy.ToString());
            TxtShow.AppendText("\r\n");
            TxtShow.AppendText("t1=");
            TxtShow.AppendText(t1.ToString());
            TxtShow.AppendText("\r\n");   






            t1 = Math.Abs(t1);
            if (t1 > 2.56694)
            {
                MessageBox.Show("变量X1显著");
             }
            else
            {
                MessageBox.Show("变量X1不显著,应当剔除","提示",MessageBoxButtons.OK,MessageBoxIcon.Warning);  //在进行T检测时,此语句执行了:公式时没有问题的,原因应该是:编译器是通过数据关系来计算的,它并不能识别X1与Y在现实中的实际关系,决解方法:在确定自变量和因变量有绝对关系是,对此自变量不进行检验。
            }         */
           //X2的检验
            double t2 = b2 / (Sy * Math.Pow(NIjuzhen[2, 2], 0.5));
            t2 = Math.Abs(t2);
            if (t2 > 2.56694)
            {
                MessageBox.Show("变量X2显著");
            }
            else
            {
                MessageBox.Show("变量X2不显著,应当剔除", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }






        }


        #endregion



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 买到华为翻新机怎么办 华为畅享8声音小怎么办 华为5a安全模式怎么办 手机跳屏怎么办金立 苹果手机触控不灵敏怎么办 华为mate8手机声音小怎么办 华为mate9相机无法对焦怎么办 新疆外地电信卡信号差怎么办 华为手机搜索不到wifi怎么办 华为浏览器恢复只有一个页面怎么办 华为手机触摸屏没反应怎么办 快递不给送上楼怎么办 华为荣耀手机声音小怎么办 华为手机来电铃声小怎么办 s弯出来时老压线怎么办 苹果7p手机弯了怎么办 小米手机摔弯了怎么办 华为畅享5没声音怎么办 掌阅语音闪退怎么办 华为mate开屏成排线怎么办 华为mate8电池坏了怎么办 8plus拍照不清晰怎么办 荣耀手环3丢了怎么办 华为mate9手机声音小怎么办 华为麦芒6丢了怎么办 华为麦芒4无法访问移动网络怎么办 自拍时屏幕是白的怎么办 华为麦芒5手机音量小怎么办 小米5x玩王者卡怎么办 小米5x打王者卡怎么办 华为荣耀10卡顿怎么办 麦芒6记不得密码怎么办 华为麦芒4镜头碎了怎么办 三星s5出像网的信号怎么办 华为手机进海水资料怎么办 华为手机进海水了怎么办 苹果手机玩王者荣耀卡怎么办 玩王者荣耀闪屏怎么办 王者荣耀太卡了怎么办 想卖王者号qq怎么办 小米4电视发热严重怎么办