當前位置:
首頁 > 知識 > 隨機之美,隨機森林

隨機之美,隨機森林

(點擊

上方藍字

,快速關注我們)




來源:伯樂在線 - 雲戒


如有好文章投稿,請點擊 → 這裡了解詳情




摘要:隨機森林和決策樹相比,能更好的防止過擬合。雖然每個基分類器很弱,但最後組合的結果通常很強,這也類似於:「三個臭皮匠頂個諸葛亮」的思想。對比發現Random Forest(隨機森林)和SVM(支持向量機)名列第一、第二名。




01 樹與森林




在構建決策樹的時候,可以讓樹進行完全生長,也可以通過參數控制樹的深度或者葉子節點的數量,通常完全生長的樹會帶來過擬合問題。過擬合一般由數據中的雜訊和離群點導致,一種解決過擬合的方法是進行剪枝,去除樹的一些雜亂的枝葉。




註:你可能需要參考前面的文章:《0x0B 菩提決策樹,姻緣演算法求》




實際應用中,一般可用隨機森林來代替,隨機森林在決策樹的基礎上,會有更好的表現,尤其是防止過擬合。




在機器學習演算法中,有一類演算法比較特別,叫組合演算法(Ensemble),即將多個基演算法(Base)組合起來使用。每個基演算法單獨預測,最後的結論由全部基演算法進行投票(用於分類問題)或者求平均(包括加權平均,用於回歸問題)。



組合演算法中,一類是Bagging(裝袋),另一類是Boosting(提升),隨機森林便是Bagging中的代表。使用多顆樹進行單獨預測,最後的結論由這些樹預測結果的組合共同來決定,這也是「森林」名字的來源。每個基分類器可以很弱,但最後組合的結果通常能很強,這也類似於:「三個臭皮匠頂個諸葛亮」的思想。




《統計學習方法》作者李航博士的文章:http://blog.sina.com.cn/s/blog_7ad48fee0102vb9c.html 有說明:「來自JMLR(Journal of Machine Learning Research,機器學習頂級期刊)雜誌的文章,有人讓179種不同的分類學習演算法在UCI 121個數據集上進行了「大比武」(UCI是機器學習公用數據集,每個數據集的規模都不大)。結果發現Random Forest(隨機森林)和SVM(支持向量機)名列第一、第二名,但兩者差異不大」。英文的原文在這兒http://jmlr.org/papers/v15/delgado14a.html, 感興趣的可以參考。




上面文章換一種理解,即為:掌握了隨機森林,基本上可以處理很多常見的機器學習問題。由此可見,組合演算法在很多時候,其預測的性能都會優於單獨的演算法,這也正是隨機森林的魅力所在。




02 處處隨機




多個人組成的團隊,是不是一定就強於一個人呢?團隊的產出並不能把每個人的力量相加,並非和「眾人拾柴火焰高」的道理一樣。要讓團隊的總產出高於單個人的產出,那必須是每個人都有其它人不具備的知識或者能力,如果大家都是完全相同的知識或者能力,在解決難題上並沒有幫助。假設對一個數據的預測,大家的結論都是1,最後組合結論依然是1,沒有任何改變。對預測準確率,沒有任何提升。



這也是「森林」前面還有「隨機」這個修飾詞的原因,隨機就是讓每個顆樹不一樣,如果都一樣,組合後的效果不會有任何提升。假設每顆樹不一樣,單獨預測錯誤率大概都是40%(夠弱了吧,很多時候都會犯錯),但三顆樹組合的後的錯誤率就變成了35.2%(至少一半以上(兩顆樹)同時犯錯結果才會犯錯),其計算方法為:





3個全錯(一種情況) + 2個錯1個對(3種組合):


1 0.4^3 + 3 0.4^2 * (1-0.4)^1 = 0.352




因此,隨機森林演算法中,「隨機」是其核心靈魂,「森林」只是一種簡單的組合方式而已。隨機森林在構建每顆樹的時候,為了保證各樹之間的獨立性,通常會採用兩到三層的隨機性。



從數據抽樣開始,每顆樹都隨機地在原有數據的基礎上進行有放回的抽樣。假定訓練數據有1萬條,隨機抽取8千條數據,因為是有放回的抽樣,可能原數據中有500條被抽了兩次,即最後的8千條中有500條是重複的數據。每顆樹都進行獨立的隨機抽樣,這樣保證了每顆樹學習到的數據側重點不一樣,保證了樹之間的獨立性。




抽取了數據,就可以開始構建決策分支了,在每次決策分支時,也需要加入隨機性,假設數據有20個特徵(屬性),每次只隨機取其中的幾個來判斷決策條件。假設取4個屬性,從這4個特徵中來決定當前的決策條件,即忽略其它的特徵。取特徵的個數,通常不能太小,太小了使得單顆樹的精度太低,太大了樹之間的相關性會加強,獨立性會減弱。通常取總特徵的平方根,或者log2(特徵數)+1,在scikit-learn的實現中,支持sqrt與log2,而spark還支持onethird(1/3)。




在結點進行分裂的時候,除了先隨機取固定個特徵,然後選擇最好的分裂屬性這種方式,還有一種方式,就是在最好的幾個(依然可以指定sqrt與log2)分裂屬性中隨機選擇一個來進行分裂。scikit-learn中實現了兩種隨機森林演算法,一種是RandomForest,另外一種是ExtraTrees,ExtraTrees就是用這種方式。在某些情況下,會比RandomForest精度略高。




總結起來,使用隨機性的三個地方:






  • 隨機有放回的抽取數據,數量可以和原數據相同,也可以略小;



  • 隨機選取N個特徵,選擇最好的屬性進行分裂;



  • 在N個最好的分裂特徵中,隨機選擇一個進行分裂;




因此,理解了這幾個地方的隨機性,以及隨機性是為了保證各個基演算法模型之間的相互獨立,從而提升組合後的精度。當然,還需要保證每個基分類演算法不至於太弱,至少要強於隨機猜測,即錯誤率不能高於0.5。




03 sklearn與mllib




scikit-learn和spark中都實現了隨機森林,但各自有些細小的區別。



在scikit-learn中,同樣只是簡單幾行代碼即可:





# sklearn_rf.py


import

pandas

as

pd


from

sklearn

.

ensemble

import

RandomForestClassifier


 


df

=

pd

.

read_csv

(

"sklearn_data.csv"

)


train

,

test

=

df

.

query

(

"is_date != -1"

),

df

.

query

(

"is_date == -1"

)


y_train

,

X_train

=

train

[

"is_date"

],

train

.

drop

([

"is_date"

],

axis

=

1

)


X_test

=

test

.

drop

([

"is_date"

],

axis

=

1

)


 


model

=

RandomForestClassifier

(

n_estimators

=

50

,


                              

criterion

=

"gini"

,


                              

max_features

=

"sqrt"

,


                              

min_samples_leaf

=

1

,


                              

n_jobs

=

4

,


                          

)


model

.

fit

(

X_train

,

y_train

)


print

model

.

predict

(

X_test

)


print

zip

(

X_train

.

columns

,

model

.

feature_importances_

)




調用RandomForestClassifier時的參數說明:






  • n_estimators:指定森林中樹的顆數,越多越好,只是不要超過內存;



  • criterion:指定在分裂使用的決策演算法;



  • max_features:指定了在分裂時,隨機選取的特徵數目,sqrt即為全部特徵的平均根;



  • min_samples_leaf:指定每顆決策樹完全生成,即葉子只包含單一的樣本;



  • n_jobs:指定並行使用的進程數;




從前面的隨機森林構建過程來看,隨機森林的每顆樹之間是獨立構建的,而且盡量往獨立的方向靠,不依賴其它樹的構建,這一特點,在當前的大數據環境下,尤其被人喜愛,因為它能並行,並行,並行……。




能完全並行的演算法,一定會被人們追捧,在資源夠的情況下,可以同時並行構建大量的決策樹。scikit-learn雖然是單機版本,不能做分散式,但也可以利用單機的多枋來並行。




spark中,更是能發揮分散式的特點了:





from

pprint

import

pprint


from

pyspark

import

SparkContext


from

pyspark

.

mllib

.

tree

import

RandomForest


from

pyspark

.

mllib

.

regression

import

LabeledPoint


 


sc

=

SparkContext

()


data

=

sc

.

textFile

(

"spark_data.csv"

).

map

(

lambda

x

:

x

.

split

(

","

)).

map

(

lambda

x

:

(

float

(

x

[

0

]),

int

(

x

[

1

]),

int

(

x

[

2

]),

float

(

x

[

3

]),

int

(

x

[

4

]),

int

(

x

[

5

])))


train

=

data

.

filter

(

lambda

x

:

x

[

5

]

!=-

1

).

map

(

lambda

v

:

LabeledPoint

(

v

[

-

1

],

v

[

:-

1

]))


test

=

data

.

filter

(

lambda

x

:

x

[

5

]

==-

1

)

#.map(lambda v: LabeledPoint(v[-1], v[:-1]))


 


model

=

RandomForest

.

trainClassifier

(

train

,


                                    

numClasses

=

2

,


                                    

numTrees

=

50

,


                                    

categoricalFeaturesInfo

=

{

1

:

2

,

2

:

2

,

4

:

3

},


                                    

impurity

=

"gini"

,


                                    

maxDepth

=

5

,


                                

)


 


print

"The predict is:"

,

model

.

predict

(

test

).

collect

()


print

"The Decision tree is:"

,

model

.

toDebugString

()




和決策樹版本相比,唯一的變化,就是將DecistionTree換成了RandomForest,另外增加了一個指定樹顆數的參數:numTrees=50。




而和scikit-learn版本相比,spark中會通過categoricalFeaturesInfo={1:2, 2:2, 4:3}參數指定第5個屬性(工作屬性)具有3種不同的類別,因此spark在劃分的時候,是按類別變數進行處理。而scikit-learn中,依然當成連續的變數處理,所以在條件判斷的時候,才會有house




當有多個最優分割的時候,spark與scikit-learn在選擇上也有區別,spark會按屬性順序進行選擇,而scikit-learn會隨機選擇一個。這也是導致scikit-learn在多次運行中會輸出0和1的問題。




scikit-learn中,還可以輸出參數重要性,這也是決策樹和隨機森林的優點之一(目前pyspark還不支持輸入參數重要性):





# scikit-learn中


print

zip

(

X_train

.

columns

,

model

.

feature_importances_

)





[(『height』, 0.25), (『house』,』car』, 0.0), (『handsome』, 0.60), (『job』, 0.0)]




04 特點與應用




隨機森林基本上繼承決策樹的全部優點,只需做很少的數據準備,其他演算法往往需要數據歸一化。決策樹能處理連續變數,還能處理離散變數,當然也能處理多分類問題,多分類問題依然還是二叉樹。決策樹就是if-else語句,區別只是哪些條件寫在if,哪些寫在else,因此易於理解和解釋。




決策樹的可解釋性強 ,你可以列印出整個樹出來,從哪個因素開始決策,一目了然。但隨機森林的可解釋性就不強了。所謂可解釋性,就是當你通過各種調參進行訓練,得出一個結論,你老大來問你,這個結論是怎麼得出來的?你說是模型自己訓練出來的,老大又問了,比如舉一條具體的數據,你說一說得出結論的過程呢?因為隨機森林引入了隨機取特徵,而且是由多顆樹共同決定,樹一旦多了,很難說清楚得出結論的具體過程。雖然可以列印每顆樹的結構,但很難分析。




雖然不好解釋,但它解決了決策樹的過擬合問題,使模型的穩定性增加,對雜訊更加魯棒,從而使得整體預測精度得以提升。




因為隨機森林能計算參數的重要性,因此也可用於對數據的降維,只選取少量幾維重要的特徵來近似表示原數據。同理,在數據有眾多的特徵時,也可以用於特徵選擇,選擇關鍵的特徵用於演算法中。




隨機森林還有天生的並行性,可以很好的處理大規模數據,也可以很容易的在分散式環境中使用。




最後,在大數據環境下,隨著森林中樹的增加,最後生成的模型可能過大,因為每顆樹都是完全生長,存儲了用於決策的全部數據,導致模型可能達到幾G甚至幾十G。如果用於在線的預測,光把模型載入到內存就需要很長時間,因此比較適合離線處理。




看完本文有收穫?請轉發分享給更多人


關注「大數據與機器學習文摘」,成為Top 1%


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python開發者 的精彩文章:

Django 使用 Celery 實現非同步任務
用 Python 做股市數據分析(二)
Python 爬蟲實戰:股票數據定向爬蟲
Python: 受限制的 "函數調用"
玩轉面試演算法,帶你佔領BAT!

TAG:Python開發者 |

您可能感興趣

宇宙充滿了隨機性,真隨機與偽隨機,微觀隨機與宏觀隨機
極端隨機森林
真正隨機的隨機數
契機、隨機與天機
隨機森林預測
殺手古德之隨機
什麼是「隨機」?教你分清「偽隨機」和「真隨機」
隨機殺人
集成演算法與隨機森林
決策樹進階版之隨機森林
攝影人必備相機包,一機多鏡隨機組合,帶上你的相機說走就走!
大腦的隨機漫步
教育是隨機的
巧於因借 得景隨機
偷閑——隨機欄目
祖師勸誡,守己之誠,隨機化導
某市將雙隨機抽查葯企
隨機世界裡的傻瓜
從《雲頂之弈》探討競技遊戲中的隨機因素
漫畫:給女朋友解釋為什麼隨機播放歌曲並不隨機