大家好,我是Mac Jiang,今天和大家分享Coursera-NTU-機器學習基石(Machine Learning Foundations)-作业2 Q19-20的C++实现。虽然有很多大神已经在很多博客中给出了Phython的实现,但是给出C++实现的文章明显较少,这里为大家提供一条C++实现的思路!我的代码虽然能够得到正确答案,但是其中可能有某些思想或者细节是错误的,如果各位博友发现,请及时留言纠正,谢谢!再次声明,博主提供实现代码的原因不是为了让各位通过测试,而是为学习有困难的同学提供一条解决思路,希望我的文章对您的学习有一些帮助!
Q16-18的实验代码已经在前面给出,地址为:http://blog.csdn.net/a1015553840/article/details/51023193
本文出处:http://blog.csdn.net/a1015553840/article/details/51029765
(1)题意:19题和20题要求我们分别从两个网址下载数据作为训练样本和测试样本。这些样本的X的维度为9维,我们要做的就是分别拿出每一维度分别按照16-18的方法计算其错误率,分别在每一维度选取各自最好的Hyphothesis。在得到的9个最好的Hyphothesis中,再选取这9个中最好的Hyphothesis,作为全局最优Hyphothesis,记录此时的Hyphothesis的参数,他所在的维度,最小错误率。第20题要求我们对得到的最好的Hyphothesis,对Dtest对应维度计算E_out。注意,这里计算E_out的方法就不是第18题那样带入公式计算了,我们这里有测试样本,利用测试样本计算E_out。
(2)实现代码
#include<iostream> #include<fstream> #include<vector> #include<math.h> #include<algorithm> using namespace std; #define DEMENSION 9 //数据维度 //数据结构体 struct Record{ double x[DEMENSION]; int y; }; //取数据某一维度的x和数据的y组成的单维度,因为我们前面写的是单维度x的错误率计算,计算多维度只要分别取出每个维度计算就可以了 struct SingleDemension{ double x; int y; }; //hyphothesis格式 struct Hyphothesis{ int s; double theta; }; //从文件读入数据到Record向量中 void getData(fstream &datafile,vector<Record> &data){ while(!datafile.eof()){ Record temp; int i; for(i = 0; i < DEMENSION; i++) datafile>>temp.x[i]; datafile>>temp.y; data.push_back(temp); } datafile.close(); } //sign int sign(double x){ if(x <= 0)return -1; else return 1; } //定义比较方式 bool myCompare( SingleDemension &v1, SingleDemension &v2){ return v1.x < v2.x; } //将输入的单维度X的数据进行排序,比较方法是我们自己定义的 void sortData(vector<SingleDemension> &data){ sort(data.begin(),data.end(),myCompare); } //输入单维度X的数据进行计算其错误率 double calculateError(vector<SingleDemension> &data,Hyphothesis &h,int n){ int i; int error = 0; for(i = 0; i < n; i++){ int temp = h.s * sign(data[i].x - h.theta); if(temp != data[i].y)error++; } return error/double(n); } //分别对每个维度的每个hyphothesis计算错误率,记录最小错误率和最优hyphothesis,以及其对应的维度 double E_in(vector<Record> &trainingData,Hyphothesis &bestH,int &bestDemension,int trainingDataSize){ int i; double min_errorRate = 1.0; Hyphothesis temp = {0,0}; for(i = 0; i < DEMENSION; i++){ //分别对每个维度计算 vector<SingleDemension> singleDemension; int j; for(j = 0; j < trainingDataSize; j++){ //取出此维度的x,取出y组合形成新的单维度x数据 SingleDemension temp = {0,0}; temp.x = trainingData[j].x[i]; temp.y = trainingData[j].y; singleDemension.push_back(temp); } sort(singleDemension.begin(),singleDemension.end(),myCompare);//排序 //s = 1时候计算此维度最优hyphothesis以及最小error(此时theta取值在变) for(j = 0; j < trainingDataSize+1; j++){ temp.s = 1; if(j == 0)temp.theta = singleDemension[0].x -1.0; else if(j == trainingDataSize) temp.theta = singleDemension[trainingDataSize - 1].x + 1.0; else temp.theta = (singleDemension[j-1].x + singleDemension[j].x) / 2.0; double errorRate = calculateError(singleDemension,temp,trainingDataSize); if(errorRate < min_errorRate){ //如果这个hyphothesis比口袋里的更优秀,则将他替代口袋里的hyphothesis,并记录此时全局最小错误,并记录此时的维度 bestH = temp; min_errorRate = errorRate; bestDemension = i+1; } } //s = -1时候计算此维度最优hyohothesis以及最优error(theta取值在变) for(j = 0; j < trainingDataSize+1; j++){ temp.s = -1; if(j == 0)temp.theta = singleDemension[0].x -1.0; else if(j == trainingDataSize) temp.theta = singleDemension[trainingDataSize - 1].x + 1.0; else temp.theta = (singleDemension[j-1].x + singleDemension[j].x) / 2.0; double errorRate = calculateError(singleDemension,temp,trainingDataSize); if(errorRate < min_errorRate){ bestH = temp; min_errorRate = errorRate; bestDemension = i+1; } } } return min_errorRate; } //利用测试数据testData,已经得到的最优hyphothesis,其所在的维度计算此维度的E_out double E_out(vector<Record> testData,int bestDemension,Hyphothesis bestH,int testDataSize){ int j; vector<SingleDemension> bestDemensionData; for(j = 0; j < testDataSize; j++){ SingleDemension temp = {0,0}; temp.x = testData[j].x[bestDemension-1]; temp.y = testData[j].y; bestDemensionData.push_back(temp); } return calculateError(bestDemensionData,bestH,testDataSize); } void main(){ vector<Record> trainingData;//训练样本向量 vector<Record> testData;//测试样本向量 fstream datafile1("training_data.txt"); fstream datafile2("test_data.txt"); if(datafile1.is_open() && datafile2.is_open()){ getData(datafile1,trainingData);//读取训练样本 getData(datafile2,testData);//读取测试样本 } else{ cout<<"文件打开失败!"<<endl; exit(1); } int trainingDataSize = trainingData.size();//训练样本数 int testDataSize = testData.size();//测试样本数 Hyphothesis bestH = {0,0};//记录全局最优hyphothesis int bestDemension = 0;//记录对应的维度 double Error_in = E_in(trainingData,bestH,bestDemension,trainingDataSize);//利用训练样本计算E_in double Error_out = E_out(testData,bestDemension,bestH,testDataSize);//利用测试样本计算E_out cout<<"最佳维度为:"<<bestDemension<<", 最小E_in为:"<<Error_in<<", 其对应的E_out为:"<<Error_out<<endl; }
(3)答案:第19题的计算结果为0.25左右
第20题的计算结果为0.35左右
本文出处:http://blog.csdn.net/a1015553840/article/details/51029765