C++代码实现梯度下降算法并给出测试用例
2015-04-24 15:09
344 查看
此处仅给出代码实现,具体原理及过程请看前面的博文
测试文件输入格式如下:
含义如下:
特征值的归一化方法与之前的博文不太一样,采用了另一种归一方式:
具体的实现代码如下:
执行结果如下:
测试文件输入格式如下:
2 10 0.01 10 2104 3 399900 1600 3 329900 2400 3 369000 1416 2 232000 3000 4 539900 1985 4 299900 1534 3 314900 1427 3 198999 1380 3 212000 1494 3 242500 输出如下:
53052890086.237 51993904900.868 50956770155.817 49941026552.120 48946224657.273 47971924687.609 47017696295.619 46083118362.109 45167778793.089 44271274321.262 30014.457 8183.543 4763.016
含义如下:
特征值的归一化方法与之前的博文不太一样,采用了另一种归一方式:
具体的实现代码如下:
#include <iostream> #include <stdio.h> #include <math.h> using namespace std; double predict(double* w,double* data,int feature_num){ double sum=0; for(int i=0;i<feature_num;i++){ sum+=w[i]*data[i]; } return sum; } double Theta(double **training_set,int featue_num,int training_num,double* w){ double sum=0; for(int i=0;i<training_num;i++){ sum+=(training_set[i][featue_num]-predict(w,training_set[i],featue_num))*(training_set[i][featue_num]-predict(w,training_set[i],featue_num)); } return sum/(2*training_num); } void gradient_descent(double** training_set,int feature_num,int training_num,double* w,double a,int iterator_time){ while(iterator_time--){ double* del_theta=new double[feature_num]; for(int i=0;i<feature_num;i++){ del_theta[i]=0; for(int j=0;j<training_num;j++){ del_theta[i]+=(predict(w,training_set[j],feature_num)-training_set[j][feature_num])*training_set[j][i]; } } //w[i]的更新必须等所有的del_theta测算出来了才可以!不然更新的会影响没更新的 //上述问题在代码内表示即是下面的for循环不能和上面的合并! for(int i=0;i<feature_num;i++) w[i]-=a*del_theta[i]/(double)training_num; printf("%.3lf\n", Theta(training_set,feature_num,training_num,w)); delete[] del_theta; } for(int i=0;i<feature_num-1;i++){ printf("%.3lf ", w[i]); } printf("%.3lf\n", w[feature_num-1]); return; } void feature_normalize(double **feature_set,int feature_num,int training_num){ //特征归一化,此处特征归一化方法略有不同于梯度下降那篇的特征归一化方法 //问题:特征归一化Y的值需要归一化么?不需要! double *average=new double[feature_num]; double *stanrd_divition=new double[feature_num]; for(int i=1;i<feature_num;i++){ double sum=0; for(int j=0;j<training_num;j++){ sum+=feature_set[j][i]; } average[i]=sum/training_num; } for(int i=1;i<feature_num;i++){ double sum=0; for(int j=0;j<training_num;j++){ sum+=(feature_set[j][i]-average[i])*(feature_set[j][i]-average[i]); } stanrd_divition[i]=sqrt((sum/(training_num-1))); } for(int i=1;i<feature_num;i++) for(int j=0;j<training_num;j++){ feature_set[j][i]=(feature_set[j][i]-average[i])/(double)stanrd_divition[i]; } delete[] stanrd_divition; delete[] average; } int main(){ int feature_num,training_num,times; double a; //自己测试时请修改路径 freopen("in.txt","r",stdin); while(cin>>feature_num>>training_num>>a>>times){ double **featurn_set=new double*[training_num]; //int *arr=new int[10] 意味着声明了一个数组,大小为10,类型为int for(int i=0;i<training_num;i++){ featurn_set[i]=new double[feature_num+2]; } for(int i=0;i<training_num;i++) featurn_set[i][0]=1; for(int i=0;i<training_num;i++){ for(int j=1;j<=feature_num+1;j++){ cin>>featurn_set[i][j]; } } //在特征标准化的时候w0完全一样,就直接赋值为一,不要进行标准化了,不然会出错 feature_normalize(featurn_set,feature_num+1,training_num); for(int i=0;i<training_num;i++) featurn_set[i][0]=1; double* w=new double[feature_num+1]; for(int i=0;i<=feature_num;i++) w[i]=0; gradient_descent(featurn_set,feature_num+1,training_num,w,a,times); for(int i=0;i<training_num;i++) delete[] featurn_set[i]; delete[] featurn_set; delete[] w; //一般情况,需要将w=NULL,原因是为了防止w再次调用delete删除了不该删除的东西 } return 0; }
执行结果如下:
相关文章推荐
- 【代码】C++实现二叉树基本操作及测试用例
- 自己实现的C++智能指针的功能代码和测试用例
- 【代码】C++实现广义表及其测试用例
- 【代码】C++实现广义表及其测试用例
- 【代码】C++实现二叉树基本操作及测试用例
- TestLink测试用例:Excel转换XML工具<二>实现代码
- C++实现链表的基本操作及测试用例
- 转:TestLink1.9.3测试用例:Excel转换XML工具<二>实现代码
- TestLink1.9.3测试用例:Excel转换XML工具<二>实现代码
- 反转指向字符串反转C++实现源码(带测试用例)
- 决策树ID3算法C++代码及测试用例(bug版)
- 实现一个无锁的Stack,并写一段测试代码(多线程访问),证明这个Stack是线程安全的。给出程序以及运行的截图。
- C++实现链表的进本操作及测试用例
- C++实现链表的进本操作及测试用例
- 使用WDM驱动实现在NT下读取物理端口,特殊寄存器,物理内存的代码(C++测试代码)
- 字符串反转C++实现源码(带测试用例)
- C++ 回调函数 实现 的测试代码
- 螺旋队列C++代码实现实例及运行结果
- GBK转UTF8 C++实现代码
- RGB空间与HSV空间的相互转换(C++实现,修正网上大多数的代码错误)