经过前面对AdaBoost的总结,下面要基于Matlab实现AdaBoost-Stump进行二维平面数据点的分类的实验。

一. 实验原理

参看 http://blog.csdn.net/lg1259156776/article/details/46831191

<boosting:三个臭皮匠赛过诸葛亮,adaptive:逐步(级联)>

二. 实验方法

生成一个可以利用sine线进行分割的数据点样本,然后通过AdaBoost - decision stump对数据点进行学习,最后得出能够将数据点样本进行分类的分割线。如下图所示:

实际上就是将一堆(T个)decision stump进行vote,然后得到一个比较复杂的分界线,实际上就是对实现利用阶跃函数对正弦函数进行逼近的。

<1> 生成training data 和 testing data : GenerateTrainDataSet

随机生成0-2pi之间数作为x1,随机生成0-4之间的数作为x2,设定的最理想的x2 = sin(x1) + 2,通过判定point(x1,x2)在曲线的上下方来给定标记y,如果在上方则为1,如果在下方则为0。

% ========================================================================
% 功能:生成具有正弦分界线的training data set
%
function [TrainData, TestData] = GenerateTrainDataSet(nTrainSize, nTestSize)
TrainData = zeros(nTrainSize,3);
TestData = zeros(nTestSize,3);
figure;
hold on;
%生成training data
title('training data')
for m = 1 : nTrainSize;
TrainData(m,1) =2 * pi * rand(); % 1 对应x1
%TrainData(m,2) = sin(TrainData(m,1)) + rand() - 0.5; % 2 对应x2
TrainData(m,2) = 4 * rand();
if(TrainData(m,2) >= sin(TrainData(m,1)) + 2) % 3 对应y
TrainData(m,3) = 1;
plot(TrainData(m,1),TrainData(m,2),'*b','MarkerSize',10);
hold on;
else
TrainData(m,3) = 0;
plot(TrainData(m,1),TrainData(m,2),'or','MarkerSize',10);
hold on;
end;
end;
%生成testing data
figure;
hold on;
title('testing data')
for m = 1 : nTestSize;
TestData(m,1) =2 * pi * rand(); % 1 对应x1
%TrainData(m,2) = sin(TrainData(m,1)) + rand() - 0.5; % 2 对应x2
TestData(m,2) = 4 * rand();
if(TestData(m,2) >= sin(TestData(m,1)) + 2) % 3 对应y
TestData(m,3) = 1;
plot(TestData(m,1),TestData(m,2),'*b','MarkerSize',10);
hold on;
else
TestData(m,3) = 0;
plot(TestData(m,1),TestData(m,2),'or','MarkerSize',10);
hold on;
end;
end;

下图是生成的训练样本,N = 500

下图是生成的测试数据集,N = 100

<2> 设计演算法对training data进行学习

根据AdaBoost原理,对于learning algorithm A来讲,minimize Error时不用特别的费劲选择Error最小的,只要我们能够选出加权分类error < 0.5 的分类器g(k)就可以了。因此在设计decision stump : Hypothesis h = s * sign(X(i) - theta)时,对于其中的三个参数(feature i, threshold theta, direction s)采用了随机均匀获得的方式,同时满足error比乱猜(丢硬币)要小就行。下面就是decision
stump的详细代码:

%=========================================================================%
% decision stump 模型
% 输入:(X,y, u) (re-weighted error : u),(X,y) data set (supervised)
% u(i)标记X(i)的权重,或者是bootstrap中样本点采样次数的归一化结果
% 输出(feature i, threshold theta, direction s, error, label[n]):
% label[n]标记每个数据点分类是否犯错,犯错了标记为1,正确标记为0
% 构成Hypothesis h = s * sign(X(i) - theta)
% s为direction,s = +1表示xi>theta为输出标记为+1,s = -1 表示xi<theta输出+1
% i表示某个维度,decision stump通常只选择某一维度进行分割,类似水平线和竖直线
% theta代表分割阈值
% 下面秉持一种信念尝试一下:只要找到比随机猜要好的h就可以了
% 算法思路:随机选取 feature_i,direction s和threshold theta,计算加权误差
% 反复迭代直到error < 0.5 (比随机乱猜好一点,weak classifier)即可
%=========================================================================%
function [feature_i, theta, s , error, label] = decison_stump(X, y, u)
while(1)
if(rand()>0.5) feature_i = 1;else feature_i = 2; end; %随机选取feature i
if(rand()>0.5) s = 1;else s = -1; end; %随机选取direction s
theta = ( max(X(:,feature_i)) - min(X(:,feature_i)) ) * rand() + min(X(:,feature_i)); %随机选取direction s error = 0; for n = 1 : length(X(:,feature_i));
if(s == 1) % 大于为1,小于为0
label(n) = 1 - ( (X(n,feature_i) >= theta) == y(n) ); %犯错了标记为1,正确标记为0
error = error + u(n) * label(n);
else
label(n) = 1 - ( (X(n,feature_i) <= theta) == y(n) );
error = error + u(n) * label(n) ;
end; end; if( error < 0.5 )
break;
end; end

之后就是AdaBoost中重要的一环:更新bootstrap中的数据re-sample的权重u,当然是根据实验原理中的步骤进行,将分类错误的点的重采样权重提高,再次训练decision stump,因为这种更新方式一方面从data diversity上保证了g的多样性,另一方面,通过调整犯错的点的采样权重,使得g(k)在采样权重u(k+1)的样本data上的分类错误与随机乱猜一样,从而保证了g(k)与g(k+1)的不同,也是diversity的一种设计。下面是adaboost的详细代码:

%=========================================================================%
% adaboost,实现对u的调节,以及后续的vote(decision stump 的融合)
% 实际上是完成了bootstrap,对数据进行re-sample,得到放大错误分类数据的u
% 输入:u_0(u(k)), error(gk对应的分类误差), label(data是否分类错误的标签)
% 输出:u_1(u(k+1)), alpha(gk对应的融合权重)
% error = 0.5, 则delta = 1,alpha() = 0,随机猜测的g的权重为0
% error = 0,则delta = ∞,alpha() = ∞,有理由让完全分类对的g的权重为∞
%=========================================================================%
function [u_1, alpha] = my_adaboost(u_0, error, label)
N = length(label); %数据大小
delta = sqrt((1-error)/error);
for n = 1 : N
if(label(n) == 1) u_1(n) = u_0(n) * delta; else u_1(n) = u_0(n) / delta; end;
end;
alpha = log(delta);

最后就是设计实验进行训练和测试,具体的解释见代码注释:

%=========================================================================%
% 利用生成的training data和testing data对AdaBoosting decision stump进行学习
% 设置在同一数据集下的演示测试为tTimes: 训练的迭代次数自增100,初始为T = 100
% 观察在同一个数据集下不同迭代次数AdaBoost融合的G在test集上的分类正确率
% 流程:生成数据集,开启循环训练-测试,并输出分类效果 %%
% 生成数据集并初始化参数
nTrainSize = 1000;
nTestSize = 100;
[TrainData, TestData] = GenerateTrainDataSet(nTrainSize, nTestSize);
tTimes = 10;
T = 0;
f = fopen('Testing Results.txt','w');
%%
% 开启tTimes次训练和测试
for times = 1 : tTimes;
T = T + 100;
u0 = 1/nTrainSize * ones(1, nTrainSize); % 初始化bootstrap采样权重为均匀分布
X = TrainData(:,1:2); % 提取输入X
y = TrainData(:,3); % 提取标签y
g_set = zeros(4, T); % 初始化g_set集合:存储decision stump的参数(feature_i,theta,s),再存入一个error性能
label = zeros(1, nTrainSize); % data 分类错误标签
alpha = zeros(1, T); % g_set融合权重
%%
% 主循环迭代训练得到g_set,alpha
for n = 1 : T;
[g_set(1,n) g_set(2,n) g_set(3,n) g_set(4,n) label] = ...
decision_stump(X, y, u0);
[u_1, alpha(n)] = my_adaboost(u0, g_set(4,n), label);
u0 = u_1;
end;
%%
% 如何把这个g的融合边界绘制出来才是问题的关键所在
% 不如直接进行测试算了
% 直接利用训练得到的g_set和alpha对testing data进行测试,求出分类正确率 X = TestData(:,1:2);
y = TestData(:,3);
vote = zeros(1, nTestSize); % X = TrainData(:,1:2);
% y = TrainData(:,3);
% vote = zeros(1, nTrainSize); sucess_rate = 0;
%%
% vote , aggregation, adaboost
for m = 1 : T;
feature_i = g_set(1,m); theta = g_set(2,m); s = g_set(3,m);
for n = 1 : length(X(:,feature_i));
if(s == 1) % 大于为1,小于为0
label(n) = ( (X(n,feature_i) >= theta) ); % 犯错了标记为1,正确标记为0
else
label(n) = ( (X(n,feature_i) <= theta) );
end;
vote(n) = vote(n) + alpha(m) * label(n)/sum(alpha); % 利用归一化的alpha进行加权融合
%vote(n) = vote(n) + 1/T * label(n); % 利用无权重的融合效果经测试不好
if(m == T)
sucess_rate = sucess_rate + ((vote(n)>0.5) == y(n));
end;
end;
end;
fprintf('第%d次训练的g_set集大小为%d,测试数据分类成功率为%f\n',times,T,sucess_rate/nTestSize);
% display('测试数据分类成功率为:');
% display(sucess_rate/nTestSize);
end;
fclose(f);

三. 实验结果



adaboost_decision_stump_test

第1次训练的g_set集大小为100,测试数据分类成功率为0.870000

第2次训练的g_set集大小为200,测试数据分类成功率为0.870000

第3次训练的g_set集大小为300,测试数据分类成功率为0.930000

第4次训练的g_set集大小为400,测试数据分类成功率为0.940000

第5次训练的g_set集大小为500,测试数据分类成功率为0.940000

第6次训练的g_set集大小为600,测试数据分类成功率为0.960000

第7次训练的g_set集大小为700,测试数据分类成功率为0.890000

第8次训练的g_set集大小为800,测试数据分类成功率为0.970000

第9次训练的g_set集大小为900,测试数据分类成功率为0.950000

第10次训练的g_set集大小为1000,测试数据分类成功率为0.930000

四 分析与讨论

从实验结果中可以看出,虽然每一个decision stump单独工作进行分类的误差仅仅比随即乱猜要好一些,但是经过AdaBoost的设计,我们得到一系列的diversity的decision stump: g,通过aggregation将其融合,从而得到一个较强的分类器。(weak classifier -> strong classifier)从而实现了“三个臭皮匠赛过诸葛亮”的预言。

另外,值得进一步去完善的地方是:本次实验程序并没有将构造出来的分类器分割边界绘制出来,所以没能很形象的展示出利用AdaBoost + decision stump能够实现对复杂非线性函数的逼近、拟合的能力。而通过测试结果不难想象出分类边界的模样。

有兴趣的可以进一步编写函数把整个融合后的G的分割边界绘制出来,形成第一幅图进行演示的效果!

*************************************************随时记录,随时分享****************************************************

机器学习技法实现(一):AdaBoost- Decision Stump (AdaBoost - 决策树的基于Matlab的实现)的更多相关文章

  1. 机器学习技法笔记:09 Decision Tree

    Roadmap Decision Tree Hypothesis Decision Tree Algorithm Decision Tree Heuristics in C&RT Decisi ...

  2. 机器学习技法总结(五)Adaptive Boosting, AdaBoost-Stump,决策树

    上一讲主要利用不同模型计算出来的g.採用aggregation来实现更好的g.假设还没有做出来g.我们能够採用bootstrap的方法来做出一系列的"diversity"的data ...

  3. 机器学习技法之Aggregation方法总结:Blending、Learning(Bagging、AdaBoost、Decision Tree)及其aggregation of aggregation

    本文主要基于台大林轩田老师的机器学习技法课程中关于使用融合(aggregation)方法获得更好性能的g的一个总结.包含从静态的融合方法blending(已经有了一堆的g,通过uniform:voti ...

  4. 【机器学习算法-python实现】Adaboost的实现(1)-单层决策树(decision stump)

    (转载请注明出处:http://blog.csdn.net/buptgshengod) 1.背景      上一节学习支持向量机,感觉公式都太难理解了,弄得我有点头大.只是这一章的Adaboost线比 ...

  5. 机器学习技法-AdaBoost元算法

    课程地址:https://class.coursera.org/ntumltwo-002/lecture 重要!重要!重要~ 一.Adaptive Boosting 的动机 通过组合多个弱分类器(hy ...

  6. 机器学习技法总结(六)Decision Tree Hypothesis

    这里先再次提出我们利用aggregation获取更好性能的Hypothesis G所涉及的方法:blending,就是在得到g_set之后进行融合:learning呢?就是在线online的获取g并融 ...

  7. 机器学习基石笔记:Homework #2 decision stump相关习题

    原文地址:http://www.jianshu.com/p/4bc01760ac20 问题描述 程序实现 17-18 # coding: utf-8 import numpy as np import ...

  8. 机器学习技法课之Aggregation模型

    Courses上台湾大学林轩田老师的机器学习技法课之Aggregation 模型学习笔记. 混合(blending) 本笔记是Course上台湾大学林轩田老师的<机器学习技法课>的学习笔记 ...

  9. Coursera台大机器学习技法课程笔记09-Decision Tree

    这是我们已经学到的(除Decision Tree外) 下面是一个典型的decision tree算法,有四个地方需要我们选择: 接着介绍了一个CART算法:通过decision stump分成两类,衡 ...

随机推荐

  1. [转]kafka要等一段时间才能消费到数据

    kafka要等一段时间才能消费到数据  pythonkafka   为什么用python写的kafka客户端脚本,程序一运行就能生产数据,而要等一段时间才能消费到数据(topic里面有数据).(pyk ...

  2. JQuery系列(2) - 事件处理

    JQuery事件绑定 (1)on方法 on方法是jQuery事件绑定的统一接口.后面介绍的事件绑定的那些简便方法,其实都是on方法的简写形式. $('li').on('click', function ...

  3. formData上传文件

    需要将选中的xml传到后台,通过xslt转换为html html: <form id="uploadForm" enctype="multipart/form-da ...

  4. idea常用设置汇总

    https://www.cnblogs.com/wangmingshun/p/6427088.html

  5. java代码实现文件的下载功能

    昨天,根据需求文档的要求,自己要做一个关于文件下载的功能,从学校毕业已经很久了,自己好长时间都没有做过这个了,于是自己上网百度,最终开发出来的代码如下: 哦!对了,我先说一下我的思路,首先需要获取服务 ...

  6. Wiki with Herbal Medicine

    Problem H. Wiki with Herbal MedicineInput file: standard input Time limit: 1 secondOutput file: stan ...

  7. spring boot+Quartz+数据库存储

    SpingBoot+Quartz+数据库存储 1.Spring整合Quartz 2.读取数据库中表达式启动定时任务1(每5s执行) 3.更改定时任务状态(启用/禁用),定时任务1停止 4.读取数据库中 ...

  8. Windows本机调试内部组件

    将详细分析Windows调试的本机接口.希望读者对C和通用NT内核体系结构和语义有一些基本的了解.此外,这并不是介绍什么是调试或如何编写调试器.它可以作为经验丰富的调试器编写人员或好奇的安全专家的参考 ...

  9. WinDbg常用命令系列---内存数据显示和对应符号显示d*s(dds、dps、dqs)

    命令dds, dps,  dqs显示给定范围内的内存内容.假定该内存是符号表中的一系列地址.相应的符号也会显示出来. dds [Options] [Range] dqs [Options] [Rang ...

  10. 【CSP模拟赛】Confess(数学 玄学)

    题目描述 小w隐藏的心绪已经难以再隐藏下去了.小w有n+ 1(保证n为偶数)个心绪,每个都包含了[1,2n]的一个大小为n的子集.现在他要找到隐藏的任意两个心绪,使得他们的交大于等于n/2. 输入描述 ...