spark.mllib:bagging方法
在訓(xùn)練集成分類器時(shí),關(guān)鍵的一步在于如何從全訓(xùn)練樣本集中構(gòu)建子樣本集提供給子分類器進(jìn)行訓(xùn)練。目前主流的兩種子樣本集構(gòu)造方式是bagging方法和boosting方法。bagging方法的思想是從全樣本集中有放回的進(jìn)行抽樣來構(gòu)造多個(gè)子樣本集,每個(gè)子樣本集中可以包含重復(fù)的樣本。對每個(gè)子樣本集訓(xùn)練一個(gè)模型,然后取平均得到最后的集成結(jié)果。
bagging
bagging方法的主要目的是為了降低模型的variance,由于子樣本集的相似性以及使用的是同種模型,因此各模型有近似相等的bias和variance(事實(shí)上,各模型的分布也近似相同,但不獨(dú)立)。由于
所以bagging后的bias和單個(gè)子模型的接近,一般來說不能顯著降低bias。另一方面,若各子模型獨(dú)立,則有
此時(shí)可以顯著降低variance。若各子模型完全相同,則
此時(shí)不會降低variance。bagging方法得到的各子模型是有一定相關(guān)性的,屬于上面兩個(gè)極端狀況的中間態(tài),因此可以一定程度降低variance。(摘自知乎)。
如需要進(jìn)一步的降低模型的variance,則需要降低各個(gè)子模型之間的相關(guān)性,Random forest通過隨機(jī)選取特征集子集來做到這一點(diǎn)。因此,在需要降低模型variance時(shí),一方面可以通過bagging方法來選取子樣本集構(gòu)造子模型,另外一方面,每個(gè)子模型之間的特征相關(guān)性需要盡量小。
boosting
boosting方法是各個(gè)子模型在迭代中串行地產(chǎn)生的。訓(xùn)練時(shí)著重關(guān)注訓(xùn)練集中那些不容易區(qū)分的樣本。AdaBoost是一種典型的boosting方法,其算法思想是:給訓(xùn)練集中的元組重新分配權(quán)重,權(quán)重影響抽樣,權(quán)重越大,越可能被抽取。迭代訓(xùn)練若干個(gè)分類器,在前一個(gè)分類器中被錯(cuò)誤分類的元組被提高權(quán)重;最后由所有分類器一起投票(投票權(quán)重取決于分類器的準(zhǔn)確率),決定分類。由于boosting方法在子模型的訓(xùn)練過程中關(guān)注那些被上一個(gè)子模型損失較大的樣本(在分類問題中是誤分的樣本,在回歸問題中是殘差較大的樣本),在逐輪的迭代過程中,整個(gè)模型的輸出會逐漸收斂至目標(biāo)值,因此,boosting方法會降低模型的bias。
????目前,bagging方法和boosting方法方法在Spark中都有實(shí)現(xiàn),其中bagging方法的抽樣過程是由BaggedPoint類實(shí)現(xiàn)的,而boosting方法則主要提現(xiàn)在模型迭代的過程中,目前僅對決策樹實(shí)現(xiàn)了boosting方法即GradientBoostedTrees類。
????????在這一篇博客中將主要介紹bagging方法的Spark實(shí)現(xiàn),boosting方法留待后續(xù)分析GBDT時(shí)介紹。BaggedPoint是Spark實(shí)現(xiàn)樣本抽樣來構(gòu)造子樣本集的類,BaggedPoint進(jìn)行樣本抽樣,分為有放回抽樣和無放回抽樣兩種。
有放回抽樣,使用柏松分布根據(jù)輸入的抽樣比率,抽樣份數(shù)進(jìn)行抽樣。
/**
?* 使用PoissonDistribution模擬抽樣,有放回抽樣
?* @param input
?* @param subsample
?* @param numSubsamples
?* @param seed
?* @tparam Datum
?* @return
?* p(x=k)=theta^^k / k! ?* e^^(-theta)
?* 樣本均值的期望為p,此處為抽樣率subsample。因此抽樣樣本數(shù)的期望為 subsample*樣本總數(shù)
?*/
private def convertToBaggedRDDSamplingWithReplacement[Datum] (
? ? input: RDD[Datum],
? ? subsample: Double,
? ? numSubsamples: Int,
? ? seed: Long): RDD[BaggedPoint[Datum]] = {
? input.mapPartitionsWithIndex { (partitionIndex, instances) => //partitionIndex:分區(qū)ID, instances:分區(qū)數(shù)據(jù)的迭代器
? ? // Use random seed = seed + partitionIndex + 1 to make generation reproducible.
? ? val poisson = new PoissonDistribution(subsample)//設(shè)定抽樣比率
? ? poisson.reseedRandomGenerator(seed + partitionIndex + 1)
? ? instances.map { instance => //
? ? ? val subsampleWeights = new Array[Double](numSubsamples)
? ? ? var subsampleIndex = 0
? ? ? while (subsampleIndex < numSubsamples) {//在每個(gè)分區(qū)抽樣numSubsamples次,BaggedPoint保存的是<數(shù)據(jù)實(shí)例,<2,0,3...>>
? ? ? ? subsampleWeights(subsampleIndex) = poisson.sample()
? ? ? ? subsampleIndex += 1
? ? ? }
? ? ? new BaggedPoint(instance, subsampleWeights)
? ? }
? }
}
無放回抽樣,使用XORShiftRandom隨機(jī)數(shù)生成算法進(jìn)行抽樣。
//無放回抽樣,每個(gè)子樣本集只包含一次該樣本
private def convertToBaggedRDDSamplingWithoutReplacement[Datum] (
? ? input: RDD[Datum],
? ? subsamplingRate: Double,
? ? numSubsamples: Int,
? ? seed: Long): RDD[BaggedPoint[Datum]] = {
? input.mapPartitionsWithIndex { (partitionIndex, instances) =>
? ? // Use random seed = seed + partitionIndex + 1 to make generation reproducible.
? ? val rng = new XORShiftRandom
? ? rng.setSeed(seed + partitionIndex + 1)
? ? instances.map { instance =>
? ? ? val subsampleWeights = new Array[Double](numSubsamples)
? ? ? var subsampleIndex = 0
? ? ? while (subsampleIndex < numSubsamples) {
? ? ? ? val x = rng.nextDouble()
? ? ? ? subsampleWeights(subsampleIndex) = {
? ? ? ? ? if (x < subsamplingRate) 1.0 else 0.0
? ? ? ? }
? ? ? ? subsampleIndex += 1
? ? ? }
? ? ? new BaggedPoint(instance, subsampleWeights)
? ? }
? }
}
????????
????????抽樣方法返回的是一個(gè)BaggedRDD<BaggedPoint>,BaggedPoint(datainstance, subsampleWeights),其中data instance 即為一個(gè)樣本實(shí)例,subsampleWeights是一個(gè)形式為[1, 0, 4]的數(shù)組,表示抽樣份數(shù)為3份,數(shù)組中的數(shù)字表示該樣本在對應(yīng)抽樣樣本集中出現(xiàn)的次數(shù)。這樣的好處是只保留了一份原始樣本集,構(gòu)建了多個(gè)不同的"視圖"即抽樣樣本集,一定程度上節(jié)省了內(nèi)存。
????????另外,目前業(yè)界對bagging方法的實(shí)現(xiàn)主要是Randomforest,其它的諸如邏輯斯蒂回歸、SVM等等算法上并沒有采用這一方法,個(gè)人認(rèn)為,其主要原因決策樹具有良好的特征自選擇性,而不會去使用全部的特征,一定程度上降低了各個(gè)子模型的相關(guān)性。當(dāng)然,我們也可以人工的為各個(gè)子模型選擇特征子集,這樣就可以適用于其它算法上了。
————————————————
版權(quán)聲明:本文為CSDN博主「大愚若智_」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/zbc1090549839/article/details/69329584
總結(jié)
以上是生活随笔為你收集整理的spark.mllib:bagging方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 复方栀子止痛膏_功效作用注意事项用药禁忌
- 下一篇: spark.mllib:Optimize