zoukankan      html  css  js  c++  java
  • 機器學習基石 机器学习基石 (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

    其它解答看汇总帖:http://blog.csdn.net/a1015553840/article/details/51085129


    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
    }






  • 相关阅读:
    PHP开发APP接口(九)
    C#深入理解类型
    C#从委托、lambda表达式到linq总结
    C# ==和Equals()
    C# 泛型
    C# Reflection
    原声JS网络请求
    JavaScript预编译
    泛型初探
    C#内存分配
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7231246.html
Copyright © 2011-2022 走看看