機器學習(12)——隨機森林

前言:前面已經(jīng)介紹了的幾種算法凳谦,應該對算法有了一個基本的認識了,本章主要是在前面已經(jīng)學到的基礎上衡未,對前面的算法模型進行整合操作尸执,訓練出效果更好的分類器模型。

集成學習

集成學習的思想是將若干個學習器(分類器&回歸器)組合之后產(chǎn)生一個新學習器缓醋。弱分類器( weak learner)指那些分類準確率只稍微好于隨機猜測的分類器( errorrate<0.5);集成算法的成功在于保證弱分類器的多樣性( Diversity)如失。而且集成不穩(wěn)定的算法也能夠得到一個比較明顯的性能提升。
常見的集成學習思想有:
(1)投票選舉(bagging: 自舉匯聚法 bootstrap aggregating): 是基于數(shù)據(jù)隨機重抽樣分類器構造的方法
(2)再學習(boosting): 是基于所有分類器的加權求和的方法
對于不同的數(shù)據(jù)進行不同的集成算法的構建送粱,大致來說可以分為以下四種情況:
(1)弱分類器間存在一定的差異性,這會導致分類的邊界不同,也就是說可能存在錯誤褪贵。那么將多個弱分類器合并后,就可以得到更加合理的邊界,減少整體的錯率,實現(xiàn)更好的效果;
(2)對于數(shù)據(jù)集過大或者過小,可以分別進行劃分和有放回的操作產(chǎn)生不同的數(shù)據(jù)子集,然后使用數(shù)據(jù)子集訓練不同的分類器,最終再合并成為一個大的分類器抗俄;
(3)如果數(shù)據(jù)的劃分邊界過于復雜,使用線性模型很難描述情況,那么可以訓練多個模型,然后再進行模型的融合脆丁;
(4)對于多個異構的特征集的時候,很難進行融合,那么可以考慮每個數(shù)據(jù)集構建一個分類模型,然后將多個模型融合。
例如下圖动雹,是構建三個不同的分類器槽卫,在做一個合并。


隨機森林

隨機森林是在 Bagging策略的基礎上進行修改后的一種算法洽胶。那隨機森林具體如何構建呢晒夹?,所謂的隨機森林姊氓,重點要理解“隨機”這兩個關鍵字丐怯,表現(xiàn)為以下兩個方面:

(1)數(shù)據(jù)的隨機性化

(2)待選特征的隨機化

使得隨機森林中的決策樹都能夠彼此不同,提升系統(tǒng)的多樣性翔横,從而提升分類性能读跷。數(shù)據(jù)的隨機化:使得隨機森林中的決策樹更普遍化一點,適合更多的場景禾唁。

構建流程

采取有放回的抽樣方式 構造子數(shù)據(jù)集效览,保證不同子集之間的數(shù)量級一樣(不同子集/同一子集 之間的元素可以重復)

利用子數(shù)據(jù)集來構建子決策樹,將這個數(shù)據(jù)放到每個子決策樹中荡短,每個子決策樹輸出一個結果丐枉。

然后統(tǒng)計子決策樹的投票結果,得到最終的分類 就是 隨機森林的輸出結果掘托。

具體構建過程如下:

(1)從樣本集中用 Bootstrap采樣選出n個樣本;

(2)從所有屬性中隨機選擇K個屬性,選擇出最佳分割屬性作為節(jié)點創(chuàng)建決策樹

(3)重復以上兩步m次,即建立m棵決策樹

(4)這m個決策樹形成隨機森林,通過投票表決結果決定數(shù)據(jù)屬于那一類

注意:(有放回的準確率在:70% 以上瘦锹, 無放回的準確率在:60% 以上)

如下圖,假設隨機森林中有3棵子決策樹,2棵子樹的分類結果是A類弯院,1棵子樹的分類結果是B類辱士,那么隨機森林的分類結果就是A類。

image.png

待選特征的隨機化過程

(1)子樹從所有的待選特征中隨機選取一定的特征听绳。

(2)在選取的特征中選取最優(yōu)的特征颂碘。

下圖中,藍色的方塊代表所有可以被選擇的特征椅挣,也就是目前的待選特征头岔;黃色的方塊是分裂特征。 左邊是一棵決策樹的特征選取過程鼠证,通過在待選特征中選取最優(yōu)的分裂特征完成分裂切油。 右邊是一個隨機森林中的子樹的特征選取過程稠集。

image.png

隨機森林推廣算法

算法總結

RF的主要優(yōu)點

1.訓練可以并行化,對于大規(guī)模樣本的訓練具有速度的優(yōu)勢衫冻;

2.由于進行隨機選擇決策樹劃分特征列表,這樣在樣本維度比較高的時候,仍然具有比較高的訓練性能碟摆;

3.給以給出各個特征的重要性列表;

4.由于存在隨機抽樣,訓練出來的模型方差小,泛化能力強娩鹉;

5.RF實現(xiàn)簡單;

6.對于部分特征的缺失不敏感稚伍。

RF的主要缺點:

1..在某些噪音比較大的特征上,RF模型容易陷入過擬弯予;

2.取值比較多的劃分特征對RF的決策會產(chǎn)生更大的影響,從而有可能影響模型的效果;

示例:乳腺癌預測

在現(xiàn)實生活中个曙,機器學習的應用非常廣泛锈嫩,在醫(yī)學方面也發(fā)揮著非常重要的作用,下面就以一個宮頸癌預測的例子來簡要說明一下隨機森林算法的思想垦搬。

比如呼寸,小明的媽媽感覺身體非常不好,醫(yī)生通過詢問和調(diào)查猴贰,收集和小明媽媽的很多數(shù)據(jù)对雪,比如年齡,工作米绕,是否抽煙等等瑟捣,把這些數(shù)據(jù)輸入計算機,計算機就會給一個患有某種病的概率栅干,醫(yī)生則可以根據(jù)這個概率做出疾病的最終結果迈套,例如把這些數(shù)據(jù)輸入一個患有乳腺癌的模型,可如何構建這個模型呢?這是我們應該關注的問題碱鳞。構建此模型的步驟如下:

首先收集數(shù)據(jù)

這是最基礎也是最重要的過程桑李,為了方便,我們直接下載權威結構公開的數(shù)據(jù):

下載的地址如下:http://archive.ics.uci.edu/ml/datasets/Cervical+cancer+(Risk+Factors)

然后觀察目標屬性和特征特征屬性如下:

u'Age', u'Number of sexual partners', u'First sexual intercourse',         u'Num of pregnancies', u'Smokes', u'Smokes (years)',         u'Smokes (packs/year)', u'Hormonal Contraceptives',         u'Hormonal Contraceptives (years)', u'IUD', u'IUD (years)', u'STDs',         u'STDs (number)', u'STDs:condylomatosis',         u'STDs:cervical condylomatosis', u'STDs:vaginal condylomatosis',         u'STDs:vulvo-perineal condylomatosis', u'STDs:syphilis',         u'STDs:pelvic inflammatory disease', u'STDs:genital herpes',         u'STDs:molluscum contagiosum', u'STDs:AIDS', u'STDs:HIV',         u'STDs:Hepatitis B', u'STDs:HPV', u'STDs: Number of diagnosis',         u'STDs: Time since first diagnosis', u'STDs: Time since last diagnosis',         u'Dx:Cancer', u'Dx:CIN', u'Dx:HPV', u'Dx', u'Hinselmann', u'Schiller',         u'Citology', u'Biopsy'

最后就是建立模型,建立模型的步驟如下:

  1. 導入模塊芙扎。
#導入我們要用的包星岗,包括算法數(shù)據(jù)導入模塊,算法評估模塊戒洼,算法模塊俏橘,以及畫圖模塊。

最后要畫roc和auc曲線圖圈浇,因而導入相應的畫圖包寥掐。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from sklearn import tree
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler,Imputer,LabelBinarizer

from sklearn import metrics#參數(shù),roc和auc
from sklearn.preprocessing import label_binarize#二值化
mpl.rcParams['font.sans-serif'] = [u'SimHei']
mpl.rcParams['axes.unicode_minus'] = False
  1. 導入數(shù)據(jù)
#這里的導入數(shù)據(jù)就是導入剛剛下載的數(shù)據(jù)

names = [u'Age', u'Number of sexual partners', u'First sexual intercourse',
       u'Num of pregnancies', u'Smokes', u'Smokes (years)',
       u'Smokes (packs/year)', u'Hormonal Contraceptives',
       u'Hormonal Contraceptives (years)', u'IUD', u'IUD (years)', u'STDs',
       u'STDs (number)', u'STDs:condylomatosis',
       u'STDs:cervical condylomatosis', u'STDs:vaginal condylomatosis',
       u'STDs:vulvo-perineal condylomatosis', u'STDs:syphilis',
       u'STDs:pelvic inflammatory disease', u'STDs:genital herpes',
       u'STDs:molluscum contagiosum', u'STDs:AIDS', u'STDs:HIV',
       u'STDs:Hepatitis B', u'STDs:HPV', u'STDs: Number of diagnosis',
       u'STDs: Time since first diagnosis', u'STDs: Time since last diagnosis',
       u'Dx:Cancer', u'Dx:CIN', u'Dx:HPV', u'Dx', u'Hinselmann', u'Schiller',
       u'Citology', u'Biopsy']#df.columns
path="datas/risk_factors_cervical_cancer.csv"
df = pd.read_csv(path)
print(df.shape)

查看數(shù)據(jù)磷蜀,查看一下總的數(shù)據(jù)

print(df.shape)

 輸出結果如下:

(858, 36)
  1. 建劃分數(shù)據(jù)集
#.劃分測試集合訓練集

x=df.iloc[:,0:-4]
y=df.iloc[:,-4:]

x=x.replace("?", np.NAN)
#通過平局值來替換nan
imputer=Imputer(missing_values="NaN")
x=imputer.fit_transform(x,y)

x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=0)
print("訓練樣本數(shù)量:%d,特征屬性數(shù)目:%d,目標屬性數(shù)目:%d"%(x_train.shape[0],x_train.shape[1],y_train.shape[1]))

輸出的結果如下:

訓練樣本數(shù)量:686,特征屬性數(shù)目:32,目標屬性數(shù)目:4
  1. 模型構建和預測:
ss = MinMaxScaler()
x_train = ss.fit_transform(x_train)
x_test = ss.transform(x_test)

rf = RandomForestClassifier(n_estimators=50,criterion="gini",max_depth=1,random_state=10)
rf.fit(x_train,y_train)

score = rf.score(x_test,y_test)
  1. 模型的評估
print("準確率:%.2f%%"%(score*100))
forest_y_score = rf.predict_proba(x_test)
# print(forest_y_score)
#計算roc和auc
forest_fpr1, forest_tpr1, _ = metrics.roc_curve(label_binarize(y_test[names[-4]],classes=(0,1,2)).T[0:-1].T.ravel(), forest_y_score[0].ravel())
forest_fpr2, forest_tpr2, _ = metrics.roc_curve(label_binarize(y_test[names[-3]],classes=(0,1,2)).T[0:-1].T.ravel(), forest_y_score[1].ravel())
forest_fpr3, forest_tpr3, _ = metrics.roc_curve(label_binarize(y_test[names[-2]],classes=(0,1,2)).T[0:-1].T.ravel(), forest_y_score[2].ravel())
forest_fpr4, forest_tpr4, _ = metrics.roc_curve(label_binarize(y_test[names[-1]],classes=(0,1,2)).T[0:-1].T.ravel(), forest_y_score[3].ravel())
#AUC值
auc1 = metrics.auc(forest_fpr1, forest_tpr1)
auc2 = metrics.auc(forest_fpr2, forest_tpr2)
auc3 = metrics.auc(forest_fpr3, forest_tpr3)
auc4 = metrics.auc(forest_fpr4, forest_tpr4)

print ("Hinselmann目標屬性AUC值:", auc1)
print ("Schiller目標屬性AUC值:", auc2)
print ("Citology目標屬性AUC值:", auc3)
print ("Biopsy目標屬性AUC值:", auc4)

輸出的結果為:

準確率:89.53%

Hinselmann目標屬性AUC值: 0.984586262844781

Schiller目標屬性AUC值: 0.9629867495943752

Citology目標屬性AUC值: 0.9453082747431043

Biopsy目標屬性AUC值: 0.9642712276906437
  1. 畫auc曲線
plt.figure(figsize=(8, 6), facecolor='w')
plt.plot(forest_fpr1,forest_tpr1,c='r',lw=2,label=u'Hinselmann目標屬性,AUC=%.3f' % auc1)
plt.plot(forest_fpr2,forest_tpr2,c='b',lw=2,label=u'Schiller目標屬性,AUC=%.3f' % auc2)
plt.plot(forest_fpr3,forest_tpr3,c='g',lw=2,label=u'Citology目標屬性,AUC=%.3f' % auc3)
plt.plot(forest_fpr4,forest_tpr4,c='y',lw=2,label=u'Biopsy目標屬性,AUC=%.3f' % auc4)
plt.plot((0,1),(0,1),c='#a0a0a0',lw=2,ls='--')
plt.xlim(-0.001, 1.001)
plt.ylim(-0.001, 1.001)
plt.xticks(np.arange(0, 1.1, 0.1))
plt.yticks(np.arange(0, 1.1, 0.1))
plt.xlabel('False Positive Rate(FPR)', fontsize=16)
plt.ylabel('True Positive Rate(TPR)', fontsize=16)
plt.grid(b=True, ls=':')
plt.legend(loc='lower right', fancybox=True, framealpha=0.8, fontsize=12)
plt.title(u'隨機森林多目標屬性分類ROC曲線', fontsize=18)
plt.show()

結果如下圖所示:

image.png

分析:由于目標屬性含有多個召耘,在進行評估的時候應該考慮多個目標屬性的影響,從上圖看出褐隆,模型的整體效果還是挺不錯的污它。

7.比較不同樹的數(shù)量和不同深度下對模型的影響

# 比較不同樹數(shù)目、樹最大深度的情況下隨機森林的正確率
# 一般情況下庶弃,初始的隨機森林樹個數(shù)是100衫贬,深度1,如果需要我們再進行優(yōu)化操作
x_train2, x_test2, y_train2, y_test2 = train_test_split(x,y, test_size=0.5, random_state=0)
print("訓練樣本數(shù)量%d歇攻,測試樣本數(shù)量:%d" % (x_train2.shape[0], x_test2.shape[0]))
## 比較
estimators = [1, 50, 100, 500]
depth = [1, 2, 3, 7, 15]
err_list = []
for es in estimators:
       es_list = []
       for d in depth:
              tf = RandomForestClassifier(n_estimators=es, criterion='gini', max_depth=d, max_features=None,
                                          random_state=0)
              tf.fit(x_train2, y_train2)
              st = tf.score(x_test2, y_test2)
              err = 1 - st
              es_list.append(err)
              print("%d決策樹數(shù)目固惯,%d最大深度,正確率:%.2f%%" % (es, d, st * 100))
       err_list.append(es_list)

## 畫圖
plt.figure(facecolor='w')
i = 0
colors = ['r', 'b', 'g', 'y']
lw = [1, 2, 4, 3]
max_err = 0
min_err = 100
for es, l in zip(estimators, err_list):
       plt.plot(depth, l, c=colors[i], lw=lw[i], label=u'樹數(shù)目:%d' % es)
       max_err = max((max(l), max_err))
       min_err = min((min(l), min_err))
       i += 1
plt.xlabel(u'樹深度', fontsize=16)
plt.ylabel(u'錯誤率', fontsize=16)
plt.legend(loc='upper left', fancybox=True, framealpha=0.8, fontsize=12)
plt.grid(True)
plt.xlim(min(depth), max(depth))
plt.ylim(min_err * 0.99, max_err * 1.01)
plt.title(u'隨機森林中樹數(shù)目缴守、深度和錯誤率的關系圖', fontsize=18)
plt.show()

得到的結果如下:

image.png
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末葬毫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子屡穗,更是在濱河造成了極大的恐慌贴捡,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件村砂,死亡現(xiàn)場離奇詭異栈暇,居然都是意外死亡,警方通過查閱死者的電腦和手機箍镜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門源祈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人色迂,你說我怎么就攤上這事香缺。” “怎么了歇僧?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵图张,是天一觀的道長锋拖。 經(jīng)常有香客問我,道長祸轮,這世上最難降的妖魔是什么兽埃? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮适袜,結果婚禮上柄错,老公的妹妹穿的比我還像新娘。我一直安慰自己苦酱,他們只是感情好售貌,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著疫萤,像睡著了一般颂跨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上扯饶,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天恒削,我揣著相機與錄音,去河邊找鬼尾序。 笑死蔓同,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的蹲诀。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼弃揽,長吁一口氣:“原來是場噩夢啊……” “哼脯爪!你這毒婦竟也來了?” 一聲冷哼從身側響起矿微,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤痕慢,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后涌矢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掖举,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年娜庇,在試婚紗的時候發(fā)現(xiàn)自己被綠了塔次。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡名秀,死狀恐怖励负,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情匕得,我是刑警寧澤继榆,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響略吨,放射性物質(zhì)發(fā)生泄漏集币。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一翠忠、第九天 我趴在偏房一處隱蔽的房頂上張望鞠苟。 院中可真熱鬧,春花似錦负间、人聲如沸偶妖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽趾访。三九已至,卻和暖如春董虱,著一層夾襖步出監(jiān)牢的瞬間扼鞋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工愤诱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留云头,地道東北人。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓淫半,卻偏偏與公主長得像溃槐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子科吭,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容