转载请注明原载地址:http://blog.csdn.net/xinhanggebuguake/article/details/8743185
把mallet中Bagging算法与Boosting放在一起,其一是因为两者都是很著名的集成学习算法,并且有很大的相似性,对比着分析能加深对两者的理解;其二两者的实现确实很简单。
算法
Bagging算法:
For t = 1, 2, …, T Do
从数据集S中取样(放回选样)
训练得到模型Ht
对未知样本X分类时,每个模型Ht都得出一个分类,得票最高的即为未知样本X的分类
Boosting算法:
初始化样本(假设共n个)权重为1/n
For t = 1, 2, …, T Do
根据权重,从数据集S中取样
训练得到模型Ht
加大分类错误的样本权重,使得下一次的迭代更加关注这些样本。
区别
训练集:
Bagging:随机选择,各轮训练集相互独立
Boosting:各轮训练集并不独立,它的选择与前轮的学习结果有关
预测函数:
Bagging:没有权重;可以并行生成
Boosting:有权重;只能顺序生成
下面分析两个算法的训练过程在mallet中的实现。其中Boosting算法以AdaBoost.M2为例分析。由于两集成算法在分类过程中都是使用投票法,只不过Boosting算法每个弱分类的分类结果会乘以其权重,所以分类过程不作介绍。
Bagging算法实现
算法过程:
BaggingTrainer.train()
Classifier[] classifiers = new Classifier[numBags];
for (int round = 0; round < numBags; round++)
//放回取样
InstanceList bag = trainingList.sampleWithReplacement();
//训练产生一个分类器
classifiers[round] = new Trainer().train (bag);
classifier = new BaggingClassifier (classifiers);
主要过程如上,创建含有numBags个的弱分类器的Bagging,然后进行numBags轮迭代。每次迭代首先从总数据集中进行可放回的取样(随机索引选取即可咯),然后对取样进行训练。最后构建一个classifier,classifier使用投票法在分类过程中进行分类。简单吧:)
AdaBoost.M2算法实现
算法过程:
AdaBoostM2.train()
InstanceList trainingInsts = new InstanceList();
double[] weights = new double[numInstances * (numClasses - 1)];
int[] classIndices = new int[weights.length];
初始化trainingInsts、weights、classIndices
Classifier[] weakLearners = new Classifier[numRounds];
double[] classifierWeights = new double[numRounds];
double[] exponents = new double[weights.length];
for (int round = 0; round < numRounds; round++)
//当达到最大次数或伪损失epsilon接近零时迭代终止。
do{
//根据权重随即取样
roundTrainingInsts = new InstanceList()
weakLearners[round] = weakLearner.train(roundTrainingInsts);
对训练集分类,并计算伪损失epsilon
} while (Maths.almostEquals(epsilon, 0)
&&resamplingIterations<MAX_NUM_RESAMPLING_ITERATIONS);
//计算此轮迭代产生分类器的权重
double beta = epsilon / (1 - epsilon);
classifierWeights[round] = Math.log(1.0 / beta);
//调整训练集中数据的权重
weights[i] *= Math.pow(beta, 0.5 * exponents[i]);
//归一化上述权重
MatrixOps.timesEquals(weights, 1.0 / sum);
}//end for
classifier = new AdaBoostM2(weakLearners,classifierWeights);
在训练开始,建立一个训练集trainingInsts,大小为(numInstances * (numClasses - 1))。在列表中的每个instance将会拥有一个与该instance不属于的classes关联的权重,存储在weights。在开始时每个instance的权重均相同,被初始化为1/(numInstances * (numClasses - 1))。classIndices表示trainingInsts中相同位置的Instance的标签。然后,开始numRounds轮循环,训练弱分类器。每个弱分类器的训练通过至多MAX_NUM_RESAMPLING_ITERATIONS次的迭代完成(因为还有epsilon)。在每轮迭代开始,首先从trainingInsts根据Instance的权重随即选择样例,训练得到模型Ht。使用Ht对训练集分类,根据Ht对Instance分类的最优标签的score和实际标签的score计算epsilon。迭代完成后记录该弱分类器的投票的权重,并使用分类得到的exponents更新每个Instance的权重。当numRounds完成,弱分类器构造完成,使用弱分类器和弱分类器的权重构造AdaBoost.M2的强分类器。
关于AdaBoost.M2的理论依据,详见:
Boosting家族AdaBoost系列代表算法 涂承胜,刁力力,鲁明羽,陆玉昌