梯度下降及logistic回归

来源:互联网 发布:硅谷大数据公司排名 编辑:程序博客网 时间:2024/06/13 03:50

批量梯度下降是一种对参数的update进行累积,然后批量更新的一种方式。用于在已知整个训练集时的一种训练方式,但对于大规模数据并不合适。

随机梯度下降是一种对参数随着样本训练,一个一个的及时update的方式。常用于大规模训练集,当往往容易收敛到局部最优解。

logistics是离散的,必须是分类变量,一般用于分类问题,比如身高高矮;

而线性回归必须是连续性数据变量,比如告诉你一些身高与体重,得到身高与体重的关系。

这是一开始的程序,后来发现有误,因为权重的更新应该是在所有样本在这次的迭代之后.(英文太难理解了,看得一知半解)

#include <stdio.h>#include <string.h> int main() {     double matrix[4][3]={{1,1,4},{1,2,5},{1,5,1},{1,4,2}};//4组数据,每组数据有2个因素(第一个为1)     double result[4]={19,26,19,20};     double theta[3]={0,0,0};//也就是要求的系数,因为影响的因素有两个,所以系数有两个     double loss,sum,error_sum,h;     int t,i,j,k;     loss=10;//loss是为了当精度已经符合要求时提前退出的操作,可省略     for (t=1;t<=100000&&loss>0.01;t++)//迭代1000次     {        for (i=0;i<4;i++)//4组数据        {         h=0;         error_sum=0;         for (k=0;k<3;k++)//2个影响因子         {         h=h+matrix[i][k]*theta[k];//按照现在的系数和数据得到的拟合值         }         error_sum=result[i]-h;         for (k=0;k<3;k++)         {         theta[k]=theta[k]+0.01*error_sum*matrix[i][k];         }        }      loss=0;//接下来的部分是评估系数是否合格,如果迭代次数够多肯定也没问题      for (j=0;j<4;j++)      {          sum=0;          for (k=0;k<3;k++)          {           sum=sum+matrix[j][k]*theta[k];          }          loss=loss+(sum-result[j])*(sum-result[j]);//这个差值的评估函数与最小二乘法是一致的      }      }    printf("%lf,%lf,%lf,%lf\n",theta[0],theta[1],theta[2],loss);    return 0; }

后来修正权重的更新(写到后面有点乱,有点乱..语言是硬伤)

#include <stdio.h>#include <string.h> int main() {     double matrix[4][2]={{1,4},{2,5},{5,1},{4,2}};//4组数据,每组数据有2个因素(第一个为1)     double result[4]={19,26,19,20};     double theta[2]={0,0};//也就是要求的系数,因为影响的因素有两个,所以系数有两个     double loss,sum,h;     int t,i,j,k;     loss=10;//loss是为了当精度已经符合要求时提前退出的操作,可省略     for (t=1;t<=10000&&loss>0.01;t++)//迭代1000次     {        double error_sum[2]={0.0,0.0};//注意更新权重是在所有样本求和之后进行梯度下降的        for (i=0;i<4;i++)//4组数据        {         h=0.0;         for (k=0;k<2;k++)//2个影响因子         {         h=h+matrix[i][k]*theta[k];//按照现在的系数和数据得到的拟合值         }         for (k=0;k<2;k++)         {         error_sum[k]=error_sum[k]+(result[i]-h)*matrix[i][k];//先记录下cost数组,但是不跟新(等到所有样本在该次迭代中都被访问过了,再迭代)         }        }         for (k=0;k<2;k++)         {         theta[k]=theta[k]+0.001*error_sum[k]/4;         }      loss=0;//接下来的部分是评估系数是否合格,如果迭代次数够多肯定也没问题      for (j=0;j<4;j++)      {          sum=0;          for (k=0;k<2;k++)          {           sum=sum+matrix[j][k]*theta[k];          }          loss=loss+(sum-result[j])*(sum-result[j]);//这个差值的评估函数与最小二乘法是一致的      }      }    printf("%lf,%lf,%lf\n",theta[0],theta[1],loss);    return 0; }



代码和线性回归基本一样,唯一的区别是增加了一个sigmoid函数,把原来的h(x)变为1/1+e^(-hx) 然后求误差,梯度下降改参数,同上

另外注意引入sigmoid函数,其实这个函数的目的就是将原来梯度下降求得的y值转化为0~1区间的一个值。

/* sigmoid函数是一个良好的阈值函数,连续,光滑严格单调关于(0,0.5)中心对称对阈值函数有一个良好的近似原函数:f(x) = 1/[1+e^(-x)]其中,当你写代码的时候,如果f(x)不好写,你可以写成f(x)=ex/1+ex的形式,其中ex是pow(2.7182818228,x)的形式,即e的x次幂*/#include <stdio.h>#include <math.h>double Function(double x){    double ex=exp(x);    return ex/(1+ex);}int main(){    double matrix[6][4]= {{1,47,76,24},              {1,46,77,23},              {1,48,74,22},              {1,34,76,21},              {1,35,75,24},              {1,34,77,25},                };    double result[6]={1,1,1,0,0,0};    double theta[4]={0,0,0,0};    int i,j,k;    double h,error,sum;    for (i=0;i<100000;i++)    {       double cost[4]={0,0,0,0};       for (j=0;j<6;j++)       {           h=0;           for (k=0;k<4;k++)           h=h+matrix[j][k]*theta[k];           error=Function(h)-result[j];           for (k=0;k<4;k++)           {               cost[k]=cost[k]+error*matrix[j][k];           }       }       for (k=0;k<4;k++)       theta[k]=theta[k]-cost[k]*0.01/4;//这里的正负是与前面的加减法有关的      printf("%.4f %.4f %.4f %.4f\n",theta[0],theta[1],theta[2],theta[3]);    }    return 0;}




0 0
原创粉丝点击