zoukankan      html  css  js  c++  java
  • 梯度下降算法解决多元线性回归问题 c++实现

    没有数据标准化的版本,效率非常低,而且训练结果并不好。

    #include <iostream>
    #define maxn 105
    #include <cstdio>
    #include <cmath>
    using namespace std;
    int n,m;  //n个特征,m个数据
    double theta[maxn];//参数集
    double temp[maxn];
    double data[maxn][maxn];//数据集
    double Y[maxn];//结果集
    double hx[maxn];
    const double eps=1e-9;
    double alpha=0.00001;
    double h(int x)//计算假设函数
    {
        double res=0;
        for(int i=0;i<=n;++i)
        {
            res+=theta[i]*data[x][i];
        }
        return res;
    }
    double J_theta()//计算cost function
    {
        double res=0;
        for(int i=1;i<=m;++i)
        {
            res+=(h(i)-Y[i])*(h(i)-Y[i]);
        }
        res=res/(2*m);
        return res;
    }
    double f(int x)//求偏导数
    {
        double res=0;
        for(int i=1;i<=m;++i)
        {
            res+=hx[i]*data[i][x];
        }
        res/=m;
        return res;
    }
    void Gradient_Descent()//梯度下降
    {
        for(int i=1;i<=m;++i)
        {
            data[i][0]=1;
        }
        for(int i=0;i<=n;++i)
        {
            theta[i]=1;//初始化
        }
        double now,nex;
        do
        {
            now=J_theta();
            for(int i=1;i<=m;++i)
            {
                hx[i]=h(i)-Y[i];
            }
            for(int i=0;i<=n;++i)
            {
                temp[i]=theta[i]-alpha*f(i);
            }
            for(int i=0;i<=n;++i)
            {
                theta[i]=temp[i];
            }
            nex=J_theta();
            //cout<<J_theta()<<endl;
        }while (abs(nex-now)>eps);
    }
    int main()
    {
        freopen("in.txt","r",stdin);
        cin>>n>>m;
        for(int i=1;i<=m;++i)
        {
            for(int j=1;j<=n;++j)
            {
                cin>>data[i][j];
            }
        }
        for(int i=1;i<=m;++i)
        {
            cin>>Y[i];
        }
        Gradient_Descent();
        for(int i=0;i<=n;++i)
        {
            printf("%.2lf
    ",theta[i]);
        }
        return 0;
    }
    

    下面是将数据归一化之后的版本,效率较高:

    #include <iostream>
    #define maxn 105
    
    #include <cmath>
    #include <algorithm>
    #include <cstdio>
    using namespace std;
    int n,m;  //n个特征,m个数据
    double theta[maxn];//参数集
    double temp[maxn];
    double data[maxn][maxn];//数据集
    double Y[maxn];//结果集
    double hx[maxn];
    const double eps=1e-9;
    double alpha=0.001;
    double ave[maxn];
    void Mean_Normaliazation()
    {
    
        for(int i=0;i<=n;++i)
        {
            double maxim=-1e9;
            double minum=1e9;
            double tmp=0;
            for(int j=1;j<=m;++j)
            {
                tmp+=data[j][i];
            }
            tmp/=m;
            double mb=0;
            for (int j=1;j<=m;++j)
            {
                mb+=(data[j][i]-tmp)*(data[j][i]-tmp);
            }
            mb/=m;
            mb=sqrt(mb);
            for(int j=1;j<=m;++j)
            {
                data[j][i]=(data[j][i]-tmp)/mb;
            }
        }
        double maxim=-1e9;
        /*double tmp=0;
        for(int i=1;i<=m;++i)
        {
            maxim=max(Y[i],maxim);
            tmp+=Y[i];
        }
        tmp/=m;
        for(int i=1;i<=m;++i)
        {
            Y[i]=(Y[i]-tmp)/maxim;
        }*/
    }
    double h(int x)//计算假设函数
    {
        double res=0;
        for(int i=0;i<=n;++i)
        {
            res+=theta[i]*data[x][i];
        }
        return res;
    }
    double J_theta()//计算cost function
    {
        double res=0;
        for(int i=1;i<=m;++i)
        {
            res+=(h(i)-Y[i])*(h(i)-Y[i]);
        }
        res=res/(2*m);
        return res;
    }
    double f(int x)//求偏导数
    {
        double res=0;
        for(int i=1;i<=m;++i)
        {
            res+=hx[i]*data[i][x];
        }
        res/=m;
        return res;
    }
    void Gradient_Descent()//梯度下降
    {
        for(int i=1;i<=m;++i)
        {
            data[i][0]=1;
        }
        for(int i=0;i<=n;++i)
        {
            theta[i]=1;//初始化
        }
        double now,nex;
        do
        {
            now=J_theta();
            for(int i=1;i<=m;++i)
            {
                hx[i]=h(i)-Y[i];
            }
            for(int i=0;i<=n;++i)
            {
                temp[i]=theta[i]-alpha*f(i);
            }
            for(int i=0;i<=n;++i)
            {
                theta[i]=temp[i];
            }
            nex=J_theta();
            //cout<<J_theta()<<endl;
        }while (abs(nex-now)>eps);
    }
    int main()
    {
        freopen("in.txt","r",stdin);
        cin>>n>>m;
        for(int i=1;i<=m;++i)
        {
            for(int j=1;j<=n;++j)
            {
                cin>>data[i][j];
            }
        }
        for(int i=1;i<=m;++i)
        {
            cin>>Y[i];
        }
        Mean_Normaliazation();
        Gradient_Descent();
        for(int i=0;i<=n;++i)
        {
            printf("%.2lf
    ",theta[i]);
        }
        return 0;
    }
    

    训练数据在这里:

    2 10
    100 4
    50 3
    100 4
    100 2
    50 2
    80 2
    75 3
    65 4
    90 3
    90 2
    9.3 4.8 8.9 6.5 4.2 6.2 7.4 6.0 7.6 9.3 4.8 8.9 6.5
    
  • 相关阅读:
    mongodb
    python中读取文件的read、readline、readlines方法区别
    uva 129 Krypton Factor
    hdu 4734
    hdu 5182 PM2.5
    hdu 5179 beautiful number
    hdu 5178 pairs
    hdu 5176 The Experience of Love
    hdu 5175 Misaki's Kiss again
    hdu 5174 Ferries Wheel
  • 原文地址:https://www.cnblogs.com/zyf3855923/p/11460864.html
Copyright © 2011-2022 走看看