小标
2019-03-26
来源 :
阅读 1619
评论 0
摘要:本文主要向大家介绍了机器学习入门之机器学习算法:AdaBoost,通过具体的内容向大家展现,希望对大家学习机器学习入门有所帮助。
本文主要向大家介绍了机器学习入门之机器学习算法:AdaBoost,通过具体的内容向大家展现,希望对大家学习机器学习入门有所帮助。

AdaBoost算法(Adaptive Boost)的核心思想是:如果一个弱分类器的分类效果不好,那么就构建多个弱分类器,综合考虑它们的分类结果和权重来决定最终的分类结果。很多人认为AdaBoost是监督学习中最强大的两种算法之一(另一个是支持向量机SVM)。
AdaBoost的训练过程如下:
为每个训练样本初始化相同的权重;
针对训练样本及权重,找到一个弱分类器;
计算出这个弱分类器的错误率ε与权重α;
对正确分类的样本,降低其权重,对错误分类的样本,提升其权重;
返回2不断迭代,直至弱分类器数量足够;
其中错误率ε定义为分错的样本数除以总样本数。权重α定义为:
权重提升与降低的公式如下:
对未知样本分类时,用每个弱分类器进行分类,将结果乘以这个分类器的权重α,累加到一起得到一个猜测值,根据其正负决定最终输出1还是-1。注意AdaBoost只能解决二分类问题,如果多于2个分类,需要做一定变通。
在AdaBoost中,广泛使用单层决策树(Decision Stump)作为弱分类器。之前研究ID3算法的决策树时,样本特征是离散型数据,这回研究连续型数据,因此之前的方法就不可用了,需要基于边界比较来确定分类。另外需要注意要同时考虑权重D来决定最佳切分方式。基本思路如下:
foreach(每一个维度)
{
在此维度最大最小值之间切出N个边界
foreach(每一个边界)
{
针对"<="与">"两种情况
{
获取此条件下的分类结果(满足记为1,不满足记为-1)
foreach(每一个结果)
{
if(猜测错误)
累加加权错误率
}
保留最小加权错误率的切分方式
}
}
}由于只在一个维度上切分一次,可以想像单层决策树的错误率应该相当高,是典型的弱分类器。但是综合考虑它们的结果及权重,最终的分类错误率可以做到大大低于单个单层决策树。上完整C#版AdaBoost的实现代码:
首先是DataVector,之前Label一直是字符串,这回要出现1和-1了,因此改造一下,使Label的类型可定义:
using System;
namespace MachineLearning
{
/// <summary>
/// 数据向量
/// </summary>
/// <typeparam name="TData">特征类型</typeparam>
/// <typeparam name="TLabel">标签数据</typeparam>
public class DataVector<TData, TLabel>
{
/// <summary>
/// N维数据
/// </summary>
public TData[] Data { get; private set; }
/// <summary>
/// 分类标签
/// </summary>
public TLabel Label { get; set; }
/// <summary>
/// 构造
/// </summary>
/// <param name="dimension">数据维度</param>
public DataVector(int dimension)
{
Data = new TData[dimension];
}
/// <summary>
/// 维度数量
/// </summary>
public int Dimension
{
get { return this.Data.Length; }
}
}
}然后是一个存储单层决策树的结构:
using System;
using System.Collections.Generic;
namespace MachineLearning
{
/// <summary>
/// 单层决策树
/// </summary>
public class DecisionStump
{
/// <summary>
/// 分类器权重
/// </summary>
public double Alpha { get; set; }
/// <summary>
/// 加权错误率
/// </summary>
public double Error { get; set; }
/// <summary>
/// 在哪个维度上切分
/// </summary>
public int Dimension { get; set; }
/// <summary>
/// 切分边界
/// </summary>
public double Boundary { get; set; }
/// <summary>
/// 是否按大于来切分
/// </summary>
public bool GreaterThan { get; set; }
/// <summary>
/// 此分类器在训练数据集上的分类结果
/// </summary>
public List<int> Results { get; set; }
}
}最后是AdaBoost:
using System;
using System.Collections.Generic;
using System.Linq;
namespace MachineLearning
{
/// <summary>
/// AdaBoost(基于单层决策树)
/// </summary>
public class AdaBoost
{
/// <summary>
/// 弱分类器列表
/// </summary>
private List<DecisionStump> m_WeakClassifiers;
/// <summary>
/// 训练
/// </summary>
/// <param name="trainingSet">训练数据集</param>
/// <param name="iterateCount">迭代次数,即弱分类器数量</param>
public void Train(List<DataVector<double, int>> trainingSet, int iterateCount = 50)
{
m_WeakClassifiers = new List<DecisionStump>();
var D = new List<double>();
var gue***esults = new List<double>();
for(int i = 0;i < trainingSet.Count;++i)
{
//权重初始化为1/n
D.Add(1.0 / trainingSet.Count);
//猜测结果初始化为0,后面累加要用
gue***esults.Add(0.0);
}
//迭代指定次数
for(int i = 0;i < iterateCount;++i)
{
//在当前权重下生成一棵错误率最低的单层决策树
var stump = CreateDecisionStump(trainingSet, D);
//计算Alpha(注意stump.Error有可能为0,要防止除0错误)
stump.Alpha = 0.5 * Math.Log((1 - stump.Error) / Math.Max(stump.Error, 1e-16));
//保存这个决策树到弱分类器
m_WeakClassifiers.Add(stump);
//根据猜测结果,重新计算下一轮的权重向量D(暂时未除以Sum(D),下一步再处理)
for(int j = 0;j < trainingSet.Count;++j)
{
if(stump.Results[j] == trainingSet[j].Label)
D[j] = D[j] * Math.Exp(-1.0 * stump.Alpha);
else
D[j] = D[j] * Math.Exp(stump.Alpha);
}
//保证Sum(D)==1
double sum = D.Sum();
for(int j = 0;j < trainingSet.Count;++j)
{
D[j] = D[j] / sum;
gue***esults[j] += stump.Alpha * stump.Results[j];
}
//计算总错误率
int errors = 0;
for(int j = 0;j < trainingSet.Count;++j)
{
if(Math.Sign(gue***esults[j]) != trainingSet[j].Label)
++errors;
}
//如果没有错误,可以提前退出循环,但一般很难达到
if(errors == 0)
break;
}
}
/// <summary>
/// 分类
/// </summary>
/// <param name="vector">待测数据</param>
/// <returns>分类结果,1或-1</returns>
public int Classify(DataVector<double, int> vector)
{
double result = 0.0;
var dataSet = new List<DataVector<double, int>>();
dataSet.Add(vector);
//用每一个弱分类器的结果乘以相应的alpha,累加得到最终的猜测结果
foreach(var c in m_WeakClassifiers)
{
var stumpResults = ClassifyByDecisionStump(dataSet, c.Dimension, c.Boundary, c.GreaterThan);
result += stumpResults[0] * c.Alpha;
}
//根据正负决定输出1还是-1
return Math.Sign(result);
}
/// <summary>
/// 根据单层决策树进行一次分类
/// </summary>
/// <param name="dataSet">数据集</param>
/// <param name="dimension">在哪个维度上分类</param>
/// <param name="boundary">分类边界</param>
/// <param name="greaterThan">是否按大于来划分数据</param>
/// <returns>结果</returns>
private List<int> ClassifyByDecisionStump(List<DataVector<double, int>> dataSet, int dimension, double boundary, bool greaterThan)
{
var result = new List<int>();
foreach(var item in dataSet)
{
if(greaterThan)
result.Add(item.Data[dimension] > boundary ? 1 : -1);
else
result.Add(item.Data[dimension] <= boundary ? 1 : -1);
}
return result;
}
/// <summary>
/// 构建一个单层决策树
/// </summary>
/// <param name="dataSet">数据集</param>
/// <param name="D">权重</param>
/// <returns>此权重下的最佳单层决策树</returns>
private DecisionStump CreateDecisionStump(List<DataVector<<span class="token keyword 本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标人工智能机器学习频道!
喜欢 | 0
不喜欢 | 0
您输入的评论内容中包含违禁敏感词
我知道了

请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号