機器學習基石 机器学习基石 (Machine Learning Foundations) 作业二 Q19-20 C++实现
Posted Mac Jiang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了機器學習基石 机器学习基石 (Machine Learning Foundations) 作业二 Q19-20 C++实现相关的知识,希望对你有一定的参考价值。
大家好,我是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
其他解答看汇总帖:http://blog.csdn.net/a1015553840/article/details/51085129
(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
其他解答看汇总帖:http://blog.csdn.net/a1015553840/article/details/51085129
以上是关于機器學習基石 机器学习基石 (Machine Learning Foundations) 作业二 Q19-20 C++实现的主要内容,如果未能解决你的问题,请参考以下文章
機器學習基石 机器学习基石 (Machine Learining Foundations) 作业2 Q16-18 C++实现
機器學習基石(Machine Learning Foundations) 机器学习基石 作业四 Q13-20 MATLAB实现
機器學習基石 (Machine Learning Foundations) 作业1 Q18-20的C++实现(pocket)