AdaBoost对实际数据分类的Julia实现
写在前面
AdaBoost是机器学习领域一个很重要很流行的算法,而Julia是一门新兴的发展迅速的科学计算语言。本文将从一个实际例子出发,展示如何用Julia语言实现AdaBoost算法。
什么是AdaBoost
这方面的资料有很多,我将基于Hastie和Tibshirani的ESL(The Elements of Statistical Learning)有关章节的内容,从统计学习的角度简单介绍一下。另外,我一直在进行ESL的翻译工作,并试图实现书中有关算法,欢迎访问ESL-CN项目主页,本节的相关翻译内容参见这里。
给定预报向量\(X\),分类器\(G(X)\)在二值\(\\{-1,1\\}\)中取一个值得到一个预测。在训练样本上的误差率是
\]
在未来预测值上的期望误差率为\(E_{XY}I(Y\neq G(X))\)
弱分类器是误差率仅仅比随机猜测要好一点的分类器。boosting的目的是依次对反复修改的数据应用弱分类器算法,因此得到弱分类器序列\(G_m(x),m=1,2,\ldots,M\) 根据它们得到的预测再通过一个加权来得到最终的预测
\]
用一个概念图(图来自ESL原书)表示如下:

具体来说,对每步boosting的数据修改是对每个训练观测\((x_i,y_i),i=1,2,\ldots,N\)赋予权重\(w_1,w_2,\ldots,w_N\)。初始化所有的权重设为\(w_i=1/N\),使得第一步以通常的方式对数据进行训练分类器。对每个接下来的迭代\(m=2,3,\ldots,M\),单独修改观测的权重,然后将分类算法重新应用到加权观测值上。在第\(m\)步,上一步中被分类器\(G_{m-1}(x)\)的误分类的观测值增大了权重,而正确分类的观测值权重降低了。因此当迭代继续,很难正确分类的观测受到越来越大的影响。每个相继的分类器因此被强制集中在上一步误分类的训练数据上。
算法10.1显示了AdaBoost.M1算法的详细细节。当前的分类器\(G_m(x)\)由第2(a)行的加权观测值得到。在第2(b)行计算加权误差率。第2(c)行计算赋予\(G_m(x)\)的权重\(\alpha_m\)来得到最终的分类器\(G(x)\)(第3行)。每个观测的个体权重在第2(d)行进行更新。在导出序列中下一个分类器\(G_{m+1}(x)\)时,被分类器\(G(x)\)错误分类的观测值的权重被因子\(exp(\alpha_m)\)进行缩放以提高它们的相对影响。

例子
特征\(X_1,\ldots,X_{10}\)是标准独立高斯分布,目标\(Y\)定义如下
\left\{
\begin{array}{ll}
1&\text{if } \sum_{j=1}^{10}X_j^2>\chi_{10}^2(0.5)\\
-1 & \text{otherwise}
\end{array}
\right.
\qquad (10.2)
\]
这里\(\chi_{10}^2(0.5)=9.34\)是自由度为10的卡方随机变量的中位数(10个标准的高斯分布的平方和)。有2000个训练情形,每个类别大概有1000个情形,以及10000个测试观测值。这里我们取称为“stump”的弱分类器:含两个终止结点的分类树。
实现
Julia的具体细节参见官方manual。
首先我们定义模型的结构,我们需要两个参数,弱分类器的个数n_clf和存储n_clf个弱分类器的n_clf\(\times 4\)的矩阵。因为对于每个弱分类器——两个终止结点的stump,我们需要三个参数确定,分割变量的编号idx,该分割变量对应的cutpoint值val,以及分类的方向flag(当flag取1时则所有比cutpoint大的观测值分到树的右结点,而flag取0时分到左结点),另外算法中需要确定的alpha参数,所以一个stump需要四个参数。下面代码默认弱分类器个数为10。
struct Adaboost
n_clf::Int64
clf::Matrix
end
function Adaboost(;n_clf::Int64 = 10)
clf = zeros(n_clf, 4)
return Adaboost(n_clf, clf)
end
训练模型
function train!(model::Adaboost, X::Matrix, y::Vector)
n_sample, n_feature = size(X)
## initialize weight
w = ones(n_sample) / n_sample
threshold = 0
## indicate the classification direction
## consider observation obs which is larger than cutpoint.val
## if flag = 1, then classify obs as 1
## else if flag = -1, classify obs as -1
flag = 0
feature_index = 0
alpha = 0
for i = 1:model.n_clf
## step 2(a): stump
err_max = 1e10
for feature_ind = 1:n_feature
for threshold_ind = 1:n_sample
flag_ = 1
err = 0
threshold_ = X[threshold_ind, feature_ind]
for sample_ind = 1:n_sample
pred = 1
x = X[sample_ind, feature_ind]
if x < threshold_
pred = -1
end
err += w[sample_ind] * (y[sample_ind] != pred)
end
err = err / sum(w)
if err > 0.5
err = 1 - err
flag_ = -1
end
if err < err_max
err_max = err
threshold = threshold_
flag = flag_
feature_index = feature_ind
end
end
end
## step 2(c)
#alpha = 1/2 * log((1-err_max)/(err_max))
alpha = 1/2 * log((1.000001-err_max)/(err_max+0.000001))
## step 2(d)
for j = 1:n_sample
pred = 1
x = X[j, feature_index]
if flag * x < flag * threshold
pred = -1
end
w[j] = w[j] * exp(-alpha * y[j] * pred)
end
model.clf[i, :] = [feature_index, threshold, flag, alpha]
end
end
预测模型
function predict(model::Adaboost,
x::Matrix)
n = size(x,1)
res = zeros(n)
for i = 1:n
res[i] = predict(model, x[i,:])
end
return res
end
function predict(model::Adaboost,
x::Vector)
s = 0
for i = 1:model.n_clf
pred = 1
feature_index = trunc(Int64,model.clf[i, 1])
threshold = model.clf[i, 2]
flag = model.clf[i, 3]
alpha = model.clf[i, 4]
x_temp = x[feature_index]
if flag * x_temp < flag * threshold
pred = -1
end
s += alpha * pred
end
return sign(s)
end
接下来应用到模拟例子中
function generate_data(N)
p = 10
x = randn(N, p)
x2 = x.*x
c = 9.341818 #qchisq(0.5, 10)
y = zeros(Int64,N)
for i=1:N
tmp = sum(x2[i,:])
if tmp > c
y[i] = 1
else
y[i] = -1
end
end
return x,y
end
function test_Adaboost()
x_train, y_train = generate_data(2000)
x_test, y_test = generate_data(10000)
m = 1:20:400
res = zeros(size(m, 1))
for i=1:size(m, 1)
model = Adaboost(n_clf=m[i])
train!(model, x_train, y_train)
predictions = predict(model, x_test)
println("The number of week classifiers ", m[i])
res[i] = classification_error(y_test, predictions)
println("classification error: ", res[i])
end
return hcat(m, res)
end
作出误差随迭代次数的图象如下

完整代码参见这里觉得项目很好的话记得star鼓励一下哦
AdaBoost对实际数据分类的Julia实现的更多相关文章
- Adaboost提升算法从原理到实践
1.基本思想: 综合某些专家的判断,往往要比一个专家单独的判断要好.在"强可学习"和"弱科学习"的概念上来说就是我们通过对多个弱可学习的算法进行"组合 ...
- 如何用OpenCV自带的adaboost程序训练并检测目标
参考博文: 1.http://blog.csdn.net/wuxiaoyao12/article/details/39227189 2.http://www.cnblogs.com/easymind2 ...
- aggregation(2):adaptive Boosting (AdaBoost)
给你这些水果图片,告诉你哪些是苹果.那么现在,让你总结一下哪些是苹果? 1)苹果都是圆的.我们发现,有些苹果不是圆的.有些水果是圆的但不是苹果, 2)其中到这些违反"苹果都是圆的" ...
- 统计学习方法c++实现之七 提升方法--AdaBoost
提升方法--AdaBoost 前言 AdaBoost是最经典的提升方法,所谓的提升方法就是一系列弱分类器(分类效果只比随机预测好一点)经过组合提升最后的预测效果.而AdaBoost提升方法是在每次训练 ...
- [机器学习]-Adaboost提升算法从原理到实践
1.基本思想: 综合某些专家的判断,往往要比一个专家单独的判断要好.在”强可学习”和”弱可学习”的概念上来说就是我们通过对多个弱可学习的算法进行”组合提升或者说是强化”得到一个性能赶超强可学习算法的算 ...
- 【机器学习实战】第7章 集成方法(随机森林和 AdaBoost)
第7章 集成方法 ensemble method 集成方法: ensemble method(元算法: meta algorithm) 概述 概念:是对其他算法进行组合的一种形式. 通俗来说: 当做重 ...
- 04-02 AdaBoost算法
目录 AdaBoost算法 一.AdaBoost算法学习目标 二.AdaBoost算法详解 2.1 Boosting算法回顾 2.2 AdaBoost算法 2.3 AdaBoost算法目标函数优化 三 ...
- 机器学习技法实现(一):AdaBoost- Decision Stump (AdaBoost - 决策树的基于Matlab的实现)
经过前面对AdaBoost的总结,下面要基于Matlab实现AdaBoost-Stump进行二维平面数据点的分类的实验. 一. 实验原理 参看 http://blog.csdn.net/lg12591 ...
- 人脸检测之Haar-like,Adaboost,级联(cascade)
最新版本整理完毕,见: http://face2ai.com/MachineLearning-Haar-like-Adaboost-cascade 0:写在前面的话 写在前面的牢骚 ...
随机推荐
- apache编译安装 httpd 2.2 httpd 2.4
#apache编译安装#httpd 2.2 , httpd 2.4 #!/bin/sh #apache编译安装 #httpd 2.2 , httpd 2.4 #centos #rpm -e httpd ...
- 数据结构与算法(C/C++版)【绪论/线性表】
声明:数据结构与算法系列博文参考了<天勤高分笔记>.<王道复习指导>.C语言中文网.非商业用途,仅为学习笔记总结! 第一章<绪论> 一.基本概念及入门常识 /// ...
- 【java提高】---HashMap解析(一)
HashMap解析(一) 平时一直再用hashmap并没有稍微深入的去了解它,自己花点时间想往里面在深入一点,发现它比arraylist难理解很多,好多东西目前还不太能理解等以后自己知识更加丰富在过来 ...
- mysql--二进制日志(bin-log)三种格式介绍及分析
一.Mysql binlog日志有三种格式,分别为ROW.Statement以及MiXED.Row LevelBinary Log会记录成[每一行数据被修改的形式],然后在Slave端再对相同的数据进 ...
- spring mvc 复杂参数注入
过了这么久,又重新把博客拾起来了 来上海工作也已经有将近两周的时间了, 今天在整理项目的时候,遇到了一个关于参数注入的问题 背景: 我的开发前台用的是extjs4,在对后台spring mvc提交表单 ...
- Java调用C# DLL
由于项目需要,利用了短信猫,但是一个短信猫会加载多个串口,而只需要其AT口,通过java代码,获取其AT口对应的串口号比较困难,于是通过C#获取,这里直接调用C#生成的DLL,但java不能直接调用C ...
- linux下yum安装redis以及使用
1.yum install redis --查看是否有redis yum 源 2.yum install epel-release --下载fedora的epel仓库 3. yum ...
- 我的csdn博客搬家了
把csdn上的文章都给搬到我的新博客去了, 将会在新的博客上继续写相关的技术文章 欢迎訪问: http://www.kai-zhou.com
- Creational模式之Builder模式
1.意图 将一个复杂对象的构建与它表示分离,使得相同的构建过程能够创建不同的表示. 查看很多其它请点击 2.别名 无 3.动机 一个RTF(Rich Text Format)文档交换格式的阅读器应能将 ...
- SharePoint Patterns and Practices 简介
作者:陈希章 发表于 2017年12月22日 SharePoint Patterns and Practices,以下简称PnP,是由微软的SharePoint产品组发起并主持的一个有关SharePo ...