リニア回帰の勾配降下(コード付)

3322 ワード

ここ数日、知乎上子楠大神の機械学習ノート(住所:http://zhuanlan.zhihu.com/p/21340974)、その中で線形回帰は勾配降下法がfunctionを解くことを話して、私は自分で実現しました. 
文字の説明ノートの中ですでに詳しく話して、ここは直接効果をあげて、図、コード:
线性回归之梯度下降(附代码)_第1张图片
线性回归之梯度下降(附代码)_第2张图片
线性回归之梯度下降(附代码)_第3张图片
コード:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

typedef long long ll;
const int maxn=1000+5;
const ll inf=1e9;
const ll mod=1e9+7;
const double eps=1e-4;
double x[maxn],y[maxn],alpha;
int m;

double dec0(double th0,double th1){
    double ans=0;
    for(int i=0;i0?-ans:ans;
}

double dec1(double th0,double th1){
    double ans=0;
    for(int i=0;i0?-ans:ans;
}

double nextth0(double th0,double th1){
    return th0-alpha*dec0(th0,th1);
}

double nextth1(double th0,double th1){
    return th1-alpha*dec1(th0,th1);
}

double Jth(double th0,double th1){
    double ans=0;
    for(int i=0;i  GradientDescent(){ //    
    double th0=0,th1=0;
    alpha=0.4;
    while(true){
        double now=Jth(th0,th1);
        double nth0=nextth0(th0,th1);
        double nth1=nextth1(th0,th1);
        double next=Jth(nth0,nth1);
        if(fabs(next-now)now){
            alpha/=2;
            th0=th1=0;
        }
        else{
            th0=nth0;
            th1=nth1;
        }
    }
    return make_pair(th0,th1);
}

int main()
{
    printf("           
:"); while(scanf("%d",&m)){ if(m<1){ printf(" 1,
"); } else break; } printf(" , : x y
"); for(int i=0;i ans=GradientDescent(); double th0=ans.first; double th1=ans.second; printf(" function h(x)= %.4f + %.4f * x

",th0,th1); printf(" , x:
"); double xx=0; while(scanf("%lf",&xx)){ printf(" y = %.4f
",th0+th1*xx); } return 0; }