梯度下降算法解决多元线性回归问题 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\n",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\n",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

 

posted @ 2019-09-04 18:32  行远山  阅读(2044)  评论(0编辑  收藏  举报