这几天看了知乎上子楠大神的机器学习笔记(地址:http://zhuanlan.zhihu.com/p/21340974),其中线性回归讲到梯度下降法求解function,我就自己实现了一下。
文字讲解笔记里已经讲的很详细了,这里直接上效果,图,代码:
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<cstring>
#include<queue>
#include<stack>
#include<list>
#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;i<m;i++){
ans=ans+th0+th1*x[i]-y[i];
}
ans/=m;
return ans>0?-ans:ans;
}
double dec1(double th0,double th1){
double ans=0;
for(int i=0;i<m;i++){
ans=ans+(th0+th1*x[i]-y[i])*x[i];
}
ans/=m;
return ans>0?-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<m;i++){
ans=ans+(th0+th1*x[i]-y[i])*(th0+th1*x[i]-y[i]);
}
return ans/m*0.5;
}
pair<double,double> 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)<eps)break;
if(next>now){
alpha/=2;
th0=th1=0;
}
else{
th0=nth0;
th1=nth1;
}
}
return make_pair(th0,th1);
}
int main()
{
printf("欢迎来到机器学习的世界\n请输入样本数量:");
while(scanf("%d",&m)){
if(m<1){
printf("样本数量不能少于1,请重新输入\n");
}
else break;
}
printf("请按格式输入样本数据,如: x y\n");
for(int i=0;i<m;i++){
scanf("%lf%lf",&x[i],&y[i]);
}
pair<double ,double > ans=GradientDescent();
double th0=ans.first;
double th1=ans.second;
printf("您要的function为 h(x)= %.4f + %.4f * x\n\n",th0,th1);
printf("好了现在您可以进行数据预测了,请输入自变量 x:\n");
double xx=0;
while(scanf("%lf",&xx)){
printf("预测的应变量 y = %.4f\n",th0+th1*xx);
}
return 0;
}