機器學習基石 机器学习基石 (Machine Learining Foundations) 作业2 Q16-18 C++实现

大家好,我是Mac Jiang,今天和大家分享Coursera-NTU-機器學習基石(Machine Learning Foundations)-作业2 Q16-18的C++实现。虽然有很多大神已经在很多博客中给出了Phython的实现,但是给出C++实现的文章明显较少,这里为大家提供一条C++实现的思路!我的代码虽然能够得到正确答案,但是其中可能有某些思想或者细节是错误的,如果各位博友发现,请及时留言纠正,谢谢!再次声明,博主提供实现代码的原因不是为了让各位通过测试,而是为学习有困难的同学提供一条解决思路,希望我的文章对您的学习有一些帮助!

本文出处:http://blog.csdn.net/a1015553840/article/details/51023193

1.第16题

(1)题意:这道题说的是“positive and negative rays”,这种分类方法在老师课堂中已经分析过了,mH(N)=2N。我们在区间[-1,1]上取若干个点(17题为20个),这20个点将[-1,1]分成21个区间,theta可以取21个区间内任意一个,加上s的取值可以为-1或者1,共有21*2=42种组合方式。分别对这42种hyphothesis计算h(x),计算他与y的区别,即E_in,选择这42种组合最小E_in,把这个hyphothesis作为最佳理论,通过他计E_out。

(2)分析:由第一题我们知道加噪声后的计算方式是此式子。对于这道题我们加20%噪声,所以lambda = 0.8,我们只要求mu就可以了。mu的定义是h(x)与f(x)的不同,即错误率。f(x)=s(x)=sign(x)已经在给出,h(x)=s*sign(x-theta)在题中也给出了,所以我们需要根据s和theta分类讨论

1.s = 1, theta > 0:错误率为theta/2

2.s=1,theta < 0;错误率为|theta|/2

3.s=-1,theta > 0:错误率为 (2 - theta)/2

4.s=-1,theta <0:错误率为(2- | theta |)/2

综上,s=1 错误率为 |theta|/2;s = -1,错误率为(2-|theta|)/2

利用一个式子写出来: mu = (s+1)/2 * (|theta|/2) -  (s-1)/2 * ((2-|theta|)/2)

最后 E_out = mu * lambda + (1 - lambda) * (1 - mu),lambda = 0.8,mu带入可以得到答案

(3)答案:0.5+0.3*s*(|theta| - 1)

2.第17,18题

(1)题意:

第17题的意思是在[-1,1]种取20个点,分隔为21个区间作为theta的取值区间,每种分类有42个hyphothesis,枚举所有可能情况找到使E_in最小的hyphothesis,记录最小E_in

第18题的意思是在17题得到的最佳hyphothesis的基础上,利用第16题的公式计算E_out.

(2)实现代码

#include<iostream>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<math.h>
using namespace std;

#define DATASIZE 20 //定义[-1,1]的内点的数目

//训练样本结构体
struct record{
	double x;
	int y;
};

//hyphothesis的结构体,s为+1或-1,theta在20个点分隔的21个区间取值
struct hyphothesis{
	int s;
	double theta;
};

//sign函数
int sign(double x){
	if(x <= 0)return -1;
	else return 1;
}

//随机在[-1,1]内生成DATASIZE个点的x,并计算对应的y
void getRandData(vector<record> &trainingData){
	int i;
	for(i = 0; i < DATASIZE; i++){
		record temp;
		temp.x = 2.0 * rand() / double(RAND_MAX) - 1.0;
		temp.y = sign(temp.x);
		trainingData.push_back(temp);
	}
}

//添加噪声,即把20%的点的y值正负号颠倒。这里的20%可以通过随机方法得到[0,1]的数,若小于0.2则认为这个点加噪声
void getNoise(vector<record> &trainingData){
	int i;
	for(i = 0; i < DATASIZE; i++){
		double randnum = rand() / double(RAND_MAX);
		if(randnum < 0.2)
			trainingData[i].y = -1 * trainingData[i].y;
	}
}

//自己定义的比较方法,用于sort
bool myCompare( record &v1, record &v2){
	return v1.x < v2.x;
}

//对MAXSIZE = 20个样本按X进行排序,这里直接调用自带sort函数,第三个参数是自己定义的比较方法(C++并不认识record,不知道怎么比较,我们要定义mycompare告诉他)
void sortTrainingData(vector<record> &trainingData){
	sort(trainingData.begin(),trainingData.end(),myCompare);
}

//给定输入集合和指定的hyphothesis计算对应的错误率
double calculateError(vector<record> &trainingData,hyphothesis &h){
	int i;
	int error = 0;
	for(i = 0; i < DATASIZE; i++){
		int temp = h.s * sign(trainingData[i].x - h.theta);
		if(temp != trainingData[i].y)error++;
	}
	return error/double(DATASIZE);
}

//由于S = 1 or -1,theta取值有21中,共有42中hyphothesis,我们计算得42种中最小的为E_in,并记录此时最小错误和对应的hyphothesis
double E_in(vector<record> &trainingData,hyphothesis &bestH){
	hyphothesis temp;
	double min_errorRate = 1.0;
	int i;
	//s = 1时
	for(i = 0; i < DATASIZE+1; i++){
		temp.s = 1;
		if(i == 0)temp.theta = trainingData[0].x -1.0;//theta取值,theta小于最小
		else if(i == DATASIZE) temp.theta = trainingData[DATASIZE - 1].x + 1.0;//theta取值在两点之间
		else temp.theta = (trainingData[i-1].x + trainingData[i].x) / 2.0;//theta取值大于最大

		double errorRate = calculateError(trainingData,temp);//如果此hyphothesis的错误更小,则替代
		if(errorRate < min_errorRate){
			bestH = temp;
			min_errorRate = errorRate;
		}
	}
	//s = -1时
	for(i = 0; i < DATASIZE+1; i++){
		temp.s = -1;
		if(i == 0)temp.theta = trainingData[0].x -1.0;
		else if(i == DATASIZE) temp.theta = trainingData[DATASIZE - 1].x + 1.0;
		else temp.theta = (trainingData[i-1].x + trainingData[i].x) / 2.0;

		double errorRate = calculateError(trainingData,temp);
		if(errorRate < min_errorRate){
			bestH = temp;
			min_errorRate = errorRate;
		}
	}
	return min_errorRate;
}

//利用16题得到的公式计算E_out,注意,浮点数求绝对值用fabs,而不是abs
double E_out(hyphothesis &bestH){
	return 0.5 + 0.3 * double(bestH.s) * (double)(fabs(bestH.theta) - 1.0);
}

void main(){
	int i;
	double totalE_inRate = 0.0;
	double totalE_outRate = 0.0;

	int seed[5000];//由于要进行5000次求平均,所以要有5000个种子用于求随机数
	int j;
	for( j = 0; j < 5000; j++){
		seed[j] = rand();	//这5000个种子通过一次取随机数产生
	}

	for(i = 0; i < 5000; i ++){
		srand(seed[i]);//每次取一个种子,那么每次产生的随机数序列就不一样了
	    vector<record> trainingData;
	    getRandData(trainingData);//随机生成训练样本
	    getNoise(trainingData);//加噪声
	    sortTrainingData(trainingData);//样本排序
		hyphothesis bestH = {0,0};
        double min_errorRate = E_in(trainingData,bestH);//计算最优hyphothesis并记录最小错误率
	    cout<<"mininum E_in:"<<min_errorRate<<endl;
		totalE_inRate += min_errorRate;
		totalE_outRate += E_out(bestH);
		cout<<"E_out:"<<E_out(bestH)<<endl;//利用这次得到的最优hyphothesis求E_out
	}
	cout<<"average E_in:"<<totalE_inRate / 5000<<endl;//得平均E_in
	cout<<"E_out:"<<totalE_outRate / 5000<<endl;//得平均E_out
}

本文出处:http://blog.csdn.net/a1015553840/article/details/51023193

时间: 2024-10-27 15:51:39

機器學習基石 机器学习基石 (Machine Learining Foundations) 作业2 Q16-18 C++实现的相关文章

機器學習基石 (Machine Learning Foundations) 作业1 Q18-20的C++实现(pocket)

大家好,我是Mac Jiang,今天和大家分享Coursera---台湾大学---機器學習基石 (Machine Learning Foundations)---作业1:Q18-20的C++实现.虽然我的代码得到了较为正确的结果,但是肯定不是最好的,如果各位博友有更好的实现思路,请留言指正,谢谢!希望我的博客能给您带来一些学习上的帮助!Q15-17的实现过程已经在:http://blog.csdn.net/a1015553840/article/details/50979434中给出,有需要的博

機器學習的看法

看了官方的機器學習的介紹文檔,感覺機器學習的發展方向還是有很大的空間的.雖然說現在的方向很好,但是,這不是唯一的途徑. 生命科學的發展還在繼續,硬件產業的技術還在突破提升,雖然速度慢了,但是我相信,那些存在于實驗室里的東西,仍不是這個時代所能接受的. 如果到了未來的某一天,機器學習和人工智能真的發展到了一定的境界,那麽,機器終究會有超越人類的一天. 科學是無限制的,這也是人的欲望的表現. 現在的人類和機器的耦合度越來越高了,未來的某一天(現在也有表現),如果人類發展到終究是得依靠機器才能生存的話

機器學習基石(Machine Learning Foundations) 机器学习基石 作业四 课后习题解答

大家好,我是Mac Jiang,今天和大家分享coursera-NTU-機器學習基石(Machine Learning Foundations)-作业四的习题解答.笔者在做这些题目时遇到很多困难,当我在网上寻找答案时却找不到,而林老师又不提供答案,所以我就想把自己做题时对题目如何思考的写下来,为大家提供一些思路.当然,我对题目的理解不一定是正确的,如果各位博友发现错误请及时留言联系,谢谢!再次提醒:请不要以此博客作为通过考试的用途,还是更好学习.理解课程的途径!希望我的博客对您的学习有所帮助!

機器學習基石(Machine Learning Foundations) 机器学习基石 作业四 Q13-20 MATLAB实现

大家好,我是Mac Jiang,今天和大家分享Coursera-NTU-機器學習基石(Machine Learning Foundations)-作业四 Q13-20的MATLAB实现.以前的代码都是通过C++实现的,但是发现C++实现这些代码太麻烦,这次作业还要频繁更改参数值,所以选择用MATLAB实现了.与C++相比,MATLAB实现显然轻松很多,在数据导入方面也更加方便.我的代码虽然能够得到正确答案,但是其中可能有某些思想或者细节是错误的,如果各位博友发现,请及时留言纠正,谢谢!再次声明,

機器學習基石(Machine Learning Foundations) 机器学习基石 作业三 Q18-20 C++实现

大家好,我是Mac Jiang,今天和大家分享Coursera-NTU-機器學習基石(Machine Learning Foundations)-作业三 Q18-20的C++实现.虽然有很多大神已经在很多博客中给出了Phython的实现,但是给出C++实现的文章明显较少,这里为大家提供一条C++实现的思路!我的代码虽然能够得到正确答案,但是其中可能有某些思想或者细节是错误的,如果各位博友发现,请及时留言纠正,谢谢!再次声明,博主提供实现代码的原因不是为了让各位通过测试,而是为学习有困难的同学提供

機器學習基石(Machine Learning Foundations) 机器学习基石 作业二 课后习题解答

大家好,我是Mac Jiang,首先祝贺大家清明节快乐!作为一名苦逼的程序员,博主只能窝在实验室玩玩游戏,顺便趁着大早上没人发一篇微博.不过还是祝各位出行的兄弟玩的开心! 今天和大家分享coursera-NTU-機器學習基石(Machine Learning Foundations)-作业二的习题解答.笔者在做这些题目时遇到很多困难,当我在网上寻找答案时却找不到,而林老师又不提供答案,所以我就想把自己做题时对题目如何思考的写下来,为大家提供一些思路.当然,我对题目的理解不一定是正确的,如果各位博

機器學習基石 机器学习基石 (Machine Learning Foundations) 作业二 Q19-20 C++实现

大家好,我是Mac Jiang,今天和大家分享Coursera-NTU-機器學習基石(Machine Learning Foundations)-作业2 Q19-20的C++实现.虽然有很多大神已经在很多博客中给出了Phython的实现,但是给出C++实现的文章明显较少,这里为大家提供一条C++实现的思路!我的代码虽然能够得到正确答案,但是其中可能有某些思想或者细节是错误的,如果各位博友发现,请及时留言纠正,谢谢!再次声明,博主提供实现代码的原因不是为了让各位通过测试,而是为学习有困难的同学提供

機器學習基石(Machine Learning Foundations) 机器学习基石 作业三 Q13-15 C++实现

大家好,我是Mac Jiang,今天和大家分享Coursera-NTU-機器學習基石(Machine Learning Foundations)-作业三 Q6-10的C++实现.虽然有很多大神已经在很多博客中给出了Phython的实现,但是给出C++实现的文章明显较少,这里为大家提供一条C++实现的思路!我的代码虽然能够得到正确答案,但是其中可能有某些思想或者细节是错误的,如果各位博友发现,请及时留言纠正,谢谢!再次声明,博主提供实现代码的原因不是为了让各位通过测试,而是为学习有困难的同学提供一

機器學習基石(Machine Learning Foundations) 机器学习基石 作业三 课后习题解答

今天和大家分享coursera-NTU-機器學習基石(Machine Learning Foundations)-作业三的习题解答.笔者在做这些题目时遇到很多困难,当我在网上寻找答案时却找不到,而林老师又不提供答案,所以我就想把自己做题时对题目如何思考的写下来,为大家提供一些思路.当然,我对题目的理解不一定是正确的,如果各位博友发现错误请及时留言联系,谢谢!再次提醒:请不要以此博客作为通过考试的用途,还是更好学习.理解课程的途径!希望我的博客对您的学习有所帮助! 本文出处:http://blog