Pocket_PLA算法
2016-06-27 21:51
323 查看
PLA的口袋算法,就是拿PLA训练好的Wf(从训练资料中已经不断修复好的最佳表现的权重集)和以存储的一个W作比较,如果前者很好,就替代已存储的W。
下面这个程序,前提是,现在做训练的数据是数据集的前50个样本,但是每次训练之前会用函数random_shuffle()打乱顺序,然后这种训练后比较W然后再用来测试test_data的过程重复2000次。
training_data的下载地址:https://d396qusza40orc.cloudfront.net/ntumlone%2Fhw1%2Fhw1_18_train.dat
test_data的下载地址:https://d396qusza40orc.cloudfront.net/ntumlone%2Fhw1%2Fhw1_18_test.dat
参考博客:http://blog.csdn.net/a1015553840/article/details/50979640
下面这个程序,前提是,现在做训练的数据是数据集的前50个样本,但是每次训练之前会用函数random_shuffle()打乱顺序,然后这种训练后比较W然后再用来测试test_data的过程重复2000次。
training_data的下载地址:https://d396qusza40orc.cloudfront.net/ntumlone%2Fhw1%2Fhw1_18_train.dat
test_data的下载地址:https://d396qusza40orc.cloudfront.net/ntumlone%2Fhw1%2Fhw1_18_test.dat
#include<fstream> #include<iostream> #include<vector> #include<algorithm> using namespace std; #define DEMENSION 5 //数据维度,包括特征属性x的维度和标签y //样本结构体 struct record { double x[DEMENSION]; int y; }; //读取文件数据 void getData(fstream &datafile,vector<record> &dataset){ while(!datafile.eof()){ record curRecord; curRecord.x[0] = 1;//这里初始化的值必须为1 int i; for(i=1 ; i<DEMENSION ; i++)datafile>>curRecord.x[i]; datafile>>curRecord.y; dataset.push_back(curRecord); } datafile.close(); } //计算sign值 int sign(double x){ if(x <= 0)return -1; else return 1; } //计算两个向量内积,判断是否需要修正 double multiply(double *v1, double *v2){ int i; double temp = 0.0; for(i = 0; i < DEMENSION; i++)temp += v1[i] * v2[i]; return temp; } //函数重载,计算向量v与整数num的积,用于计算y*x(y为+1或-1,x为向量) void multiply(double *result,double *v,int num){ int i; for(i = 0; i < DEMENSION; i++)result[i] = num * v[i]; } //计算两向量的和放入result中,用于计算w(i+1)=w(i)+y*x void add(double *v1,double *v2) { int i; for(i = 0; i < DEMENSION; i++) v1[i] += v2[i]; } //计算错误率 double getErrorRate(double *weight,vector<record> dataset){ int n = dataset.size();//所有的样本个数为n cout<<"样本个数为: "<<n<<endl; double errorRate= 0.0; int i; for(i=0;i<n;i++) if(sign(multiply(weight,dataset[i].x)) != dataset[i].y)errorRate++; cout<<"error rate : "<<errorRate<<endl; return errorRate/n; } //口袋PLA算法,式中的iteration是迭代次数,是每次做训练的样本的个数,但是由于每次训练之前都有一个打乱样本的过程,所以每次的50个样本是不一样的 void pocketPLA(double *pocketWeights,double *weights,vector<record> trainingSet,int iteration) { int index = 0; int iter= 1; int n = trainingSet.size(); while(iter <= iteration){ if(sign(multiply(trainingSet[index].x,weights)) != trainingSet[index].y)//判断标签不一致,准备correct { double temp[DEMENSION]; multiply(temp,trainingSet[index].x,trainingSet[index].y); int i; for(i=0;i<DEMENSION;i++)weights[i] += temp[i];//也可以用add(weight,temp)替代 if(getErrorRate(weights,trainingSet) < getErrorRate(pocketWeights,trainingSet)) { //如果修正后的权重集比口袋里的要好,则把口袋里的权重集换成这个 int j; for(j = 0;j<DEMENSION;j++)pocketWeights[j] = weights[j]; } iter++; cout<<"iter: "<<iter<<endl; } if(index == n-1)index = 0; else index++; } } void main() { vector<record> trainingSet; vector<record> testSet; fstream datafile1("training_data.txt"); fstream datafile2("test_data.txt"); if(datafile1.is_open()&&datafile2.is_open()){ getData(datafile1,trainingSet); getData(datafile2,testSet); } else { cout<<"can not open file!"<<endl; exit(1); } double weights[DEMENSION],pocketWeights[DEMENSION]; double ave_error = 0.0 ; int j; for(j = 0; j < 2000; j++ )//每次训练好的权重集去测试这个权重集在data(资料)为test_data上的表现如何(错误率多少) { random_shuffle(trainingSet.begin(), trainingSet.end());//只取前50个样本做训练,每次都随机打乱顺序,用函数random_shuffle int i; for(i=0;i<DEMENSION;i++) { //注意,这里需要初始化!!!不初始化值会乱码,程序出错!!! weights[i]=0.0; pocketWeights[i]=0.0; } pocketPLA(pocketWeights,weights,trainingSet,50); double trainingError = getErrorRate(pocketWeights,trainingSet); double testError = getErrorRate(pocketWeights,testSet); ave_error += testError; cout<<"第"<<j<<"次实验---"<<"training error:"<<trainingError<<" test error:"<<testError<<endl; } cout<<"average error rate:"<<ave_error/2000<<endl; }最后的结果,每个计算机应该不太一样,我的是0.12364。
参考博客:http://blog.csdn.net/a1015553840/article/details/50979640
相关文章推荐
- css之缩进
- c++栈和堆
- 关于xpath相对路径前加点与不加点的区别
- Swift Access Control 权限控制的黑与白
- 第一次接触Spring
- C++函数总结归纳
- 最近邻(kNN,k-NearestNeighbor), 贝叶斯(Bayes), BPNN 人工神经网络(BPNN)算法之花的分类
- 使用MAP文件快速定位程序崩溃代码行
- java安全框架-Shiro学习笔记(四)-注解式授权+Jsp标签授权
- 快排
- 一步步教你写StepView(流程指示器)
- 语法总结(Summary of the Grammar)
- (转)通过地址获取对应的源代码信息
- 个性化推荐项目架构
- Swift 泛型参数(Generic Parameters and Arguments)
- Swift 模式(Patterns)
- Swift 特性(Attributes)
- (转)指针为初学者服务
- 《Java JD7 学习笔记》课后练习题3
- iOS block基础