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
    
  • 相关阅读:
    Eclipse用法和技巧二十六:浅谈快捷键
    Eclipse用法和技巧二十五:eclipse图标的含义
    Eclipse用法和技巧二十四:当git遇上eclipse
    Eclipse用法和技巧二十三:查看JDK源码
    Eclipse用法和技巧二十二:快速调整字体大小
    Eclipse用法和技巧二十一:工程的展示途径
    94. Binary Tree Inorder Traversal
    110. Balanced Binary Tree
    595. Big Countries
    720. Longest Word in Dictionary(important!!!about sort)
  • 原文地址:https://www.cnblogs.com/zyf3855923/p/11460864.html
Copyright © 2011-2022 走看看