有監(jiān)督學(xué)習(xí)基于一組包含預(yù)測變量和輸出變量的樣本單元慕匠。將全部數(shù)據(jù)分為一個(gè)訓(xùn)練數(shù)據(jù)集和一個(gè)驗(yàn)證數(shù)據(jù)集帆调,其中訓(xùn)練集用于建立預(yù)測模型闪萄,驗(yàn)證集用于測試模型的準(zhǔn)確性业栅。
這部分通過rpart
玫膀、rpart.plot
和party
包來實(shí)現(xiàn)決策樹模型及其可視化胳泉,通過randomForest
包擬合隨機(jī)森林颗胡,通過e1071
包構(gòu)造支持向量機(jī)八回,通過R中的基本函數(shù)glm()
實(shí)現(xiàn)邏輯回歸酷愧。在探索之前驾诈,先安裝好相應(yīng)的包。
pkgs <- c("rpart", "rpart.plot", "party",
"randomForest", "e1071")
install.packages(pkgs, dependencies = TRUE)
這里的例子來源于UCI機(jī)器學(xué)習(xí)數(shù)據(jù)庫中的威斯康星州乳腺癌數(shù)據(jù)溶浴。數(shù)據(jù)分析的目的是根據(jù)細(xì)胞組織細(xì)針抽吸活檢所反應(yīng)的特征乍迄,來判斷被撿者是否患有乳腺癌。
數(shù)據(jù)準(zhǔn)備
該數(shù)據(jù)集是逗號分隔的txt文件士败,包含699個(gè)樣本蛋白闯两,其中458個(gè)良性,241個(gè)為惡性拱烁。數(shù)據(jù)集中有11個(gè)變量生蚁,表中未標(biāo)明變量名。其中16個(gè)樣本單元中有缺失數(shù)據(jù)并用問號(?)表示戏自。
變量為
- ID
- 腫塊厚度
- 細(xì)胞大小的均勻性
- 細(xì)胞形狀的均勻性
- 邊際附著力
- 單個(gè)上皮細(xì)胞的大小
- 裸核
- 乏味染色體
- 正常核
- 有絲分裂
- 類別
ID不納入數(shù)據(jù)分析邦投,最后一個(gè)變量是輸出變量(良性=2,惡性=4)擅笔。
對于每一個(gè)樣本來說志衣,另外九個(gè)變量是與判別惡性腫瘤相關(guān)的細(xì)胞特征,并加以記錄猛们。這些細(xì)胞特征得分為1(最接近良性)到10(最接近病變)之間的整數(shù)念脯。任一變量都不能單獨(dú)作為判別良性或惡性的標(biāo)準(zhǔn),建模的目的是找到九個(gè)細(xì)胞特征的某種組合弯淘,從而實(shí)現(xiàn)對惡性腫瘤的準(zhǔn)確預(yù)測绿店。
## Data preparation
loc <- "http://archive.ics.uci.edu/ml/machine-learning-databases/"
ds <- "breast-cancer-wisconsin/breast-cancer-wisconsin.data"
url <- paste(loc, ds, sep="")
breast <- read.table(url, sep = ",", header = FALSE, na.strings = "?")
names(breast) <- c("ID", "clumpThickness", "sizeUniformity", "shapeUniformity",
"maginalAdhesion", "singleEpithelialCellSize", "bareNuclei",
"blandChromatin", "normalNucleoli", "mitosis", "class")
df <- breast[-1]
df$class <- factor(df$class, levels = c(2,4),
labels = c("benign", "malignant"))
set.seed(1234)
train <- sample(nrow(df), 0.7*nrow(df))
df.train <- df[train,]
df.validate <- df[-train,]
table(df.train$class)
table(df.validate$class)
邏輯回歸
邏輯回歸是廣義線性模型的一種,它根據(jù)一組數(shù)值變量預(yù)測二元輸出(之前在廣義模型中有介紹)庐橙〖傥穑基本函數(shù)glm()
可以用于擬合邏輯回歸模型。
## logistic regression
fit.logit <- glm(class ~ ., data=df.train, family=binomial()) # 擬合邏輯回歸
summary(fit.logit) # 檢查模型
Call:
glm(formula = class ~ ., family = binomial(), data = df.train)
Deviance Residuals:
Min 1Q Median 3Q Max
-2.75813 -0.10602 -0.05679 0.01237 2.64317
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -10.42758 1.47602 -7.065 1.61e-12 ***
clumpThickness 0.52434 0.15950 3.287 0.00101 **
sizeUniformity -0.04805 0.25706 -0.187 0.85171
shapeUniformity 0.42309 0.26775 1.580 0.11407
maginalAdhesion 0.29245 0.14690 1.991 0.04650 *
singleEpithelialCellSize 0.11053 0.17980 0.615 0.53871
bareNuclei 0.33570 0.10715 3.133 0.00173 **
blandChromatin 0.42353 0.20673 2.049 0.04049 *
normalNucleoli 0.28888 0.13995 2.064 0.03900 *
mitosis 0.69057 0.39829 1.734 0.08295 .
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
prob <- predict(fit.logit, df.validate, type="response") # 建立預(yù)測模型,對訓(xùn)練集集外樣本單元分類
logit.pred <- factor(prob > .5, levels=c(FALSE, TRUE),
labels = c("benign", "malignant"))
logit.perf <- table(df.validate$class, logit.pred,
dnn=c("Actual", "Predicted")) # 評估預(yù)測準(zhǔn)確性
logit.perf
Predicted
Actual benign malignant
benign 118 2
malignant 4 76
predict()
函數(shù)默認(rèn)輸出腫瘤為惡性的對數(shù)概率态鳖,指定參數(shù)type="response"
即可以得到預(yù)測腫瘤為惡性的概率转培。在樣本單元中,概率大于.5的被分為惡性腫瘤類浆竭,概率小于等于.5的被分為良性腫瘤類浸须。
最后給出預(yù)測與實(shí)際情況對比的交叉表(混淆矩陣,confusion matrix)邦泄。數(shù)據(jù)集中有10個(gè)單元包含缺失數(shù)據(jù)而無法判別删窒。
在驗(yàn)證集上,正確分類的模型(準(zhǔn)確率顺囊,accuracy)為(76+118)/200=97%肌索。看起來還是非常準(zhǔn)確的哈~
值得注意的是包蓝,模型中有三個(gè)預(yù)測變量的系數(shù)未能通過顯著性檢驗(yàn)驶社,一般而言可以將它們?nèi)コ龔亩喣P汀?/p>
當(dāng)然企量,可以用逐步邏輯回歸生成一個(gè)包含更少解釋變量的模型,其目的是通過增加或移除變量來得到一個(gè)更小的AIC值亡电。例如本例可以用
logit.fit.reduced <- step(fit.logit)
來得到一個(gè)更為精簡的模型届巩。
決策樹
決策樹是數(shù)據(jù)挖掘領(lǐng)域中常用模型。其基本思想是對預(yù)測變量進(jìn)行二元分離份乒,從而構(gòu)造一顆可以預(yù)測新樣本單元所屬類別的樹恕汇。這里介紹兩類決策樹:經(jīng)典樹和條件推斷樹。
這里講的基本思想有點(diǎn)精悍或辖,似懂非懂的樣子瘾英。我們具體來看看它們究竟是什么吧。
經(jīng)典決策樹
經(jīng)典決策樹以一個(gè)二元輸出變量和一組預(yù)測變量為基礎(chǔ)颂暇。其具體算法如下:
- 選定一個(gè)最佳預(yù)測變量將全部樣本單元分為兩類缺谴,實(shí)現(xiàn)兩類中的純度最大化(即一類中良性樣本單元盡可能多,另一類惡性樣本單元盡可能多)耳鸯。如果預(yù)測變量連續(xù)湿蛔,則選定一個(gè)分割點(diǎn)進(jìn)行分類,使得兩類純度最大化县爬;如果預(yù)測變量為分類變量阳啥,則對各類別進(jìn)行合并再分類。
- 對每個(gè)子類別繼續(xù)執(zhí)行步驟1财喳。
- 重復(fù)步驟1~2察迟,直到子類別中所含的樣本單元樹過少,或者沒有分類能將不純度下降到一個(gè)給定閾值以下耳高。最終集中的子類別即終端節(jié)點(diǎn)扎瓶。根據(jù)每一個(gè)終端節(jié)點(diǎn)中樣本單元的類別數(shù)眾數(shù)來判別這一終端節(jié)點(diǎn)的所屬類別。
- 對任一樣本單元執(zhí)行決策樹祝高,得到其終端節(jié)點(diǎn)栗弟,即可以根據(jù)步驟3得到模型預(yù)測的所屬類別污筷。
這一過程就類似一棵樹生長不斷形成分支工闺,這些分支的生成是依賴具體的算法要求(這里就是讓它們純度最大化)。
上述算法構(gòu)建的樹過大瓣蛀,容易出現(xiàn)過度擬合現(xiàn)象陆蟆。可采用10折交叉驗(yàn)證法預(yù)測誤差最小的樹惋增,然后用它進(jìn)行預(yù)測叠殷。
R中的rpart
包支持rpart()
函數(shù)構(gòu)造決策樹,prune()
函數(shù)對決策樹進(jìn)行剪枝诈皿。下面給出針對數(shù)據(jù)集的算法實(shí)現(xiàn)林束。
library(rpart)
set.seed(1234)
dtree <- rpart(class ~ ., data=df.train, method="class",
parms=list(split="information")) # 生成樹
dtree$cptable
CP nsplit rel error xerror xstd
1 0.800000 0 1.00000 1.0000 0.06484605
2 0.046875 1 0.20000 0.2750 0.03954867
3 0.012500 3 0.10625 0.1500 0.02985779
4 0.010000 4 0.09375 0.1625 0.03101007
plotcp(dtree)
dtree.pruned <- prune(dtree, cp=.0125) # 剪枝
library(rpart.plot)
prp(dtree.pruned, type=2, extra=104,
fallen.leaves = TRUE, main="Decision Tree")
dtree.pred <- predict(dtree.pruned, df.validate, type="class") # 對訓(xùn)練集外樣本單元分類
dtree.perf <- table(df.validate$class, dtree.pred,
dnn=c("Actual", "Predicted"))
dtree.perf
Predicted
Actual benign malignant
benign 122 7
malignant 2 79
rpart()
返回的cptable
值中包括不同大小的樹對應(yīng)的預(yù)測誤差像棘,因此可以用于輔助設(shè)定最終的樹的大小。其中壶冒,復(fù)雜度參數(shù)cp
用于懲罰過大的樹缕题;樹的大小即分支數(shù)nsplit
,有n個(gè)分支的樹將有n+1個(gè)終端節(jié)點(diǎn)胖腾;rel error
欄即各種訓(xùn)練集中各種樹對應(yīng)的誤差烟零;交叉驗(yàn)證誤差xerror
即基于訓(xùn)練樣本所得的10折交叉驗(yàn)證誤差;xstd
欄為交叉驗(yàn)證誤差的標(biāo)準(zhǔn)差咸作。
借助plotcp()
函數(shù)可畫出交叉驗(yàn)證誤差與復(fù)雜度參數(shù)的關(guān)系圖(上圖)锨阿。對于所有交叉驗(yàn)證誤差在最小交叉驗(yàn)證誤差一個(gè)標(biāo)準(zhǔn)差范圍內(nèi)的樹,最小的樹即最優(yōu)的樹记罚。
由代碼中的cptable
表可以知道墅诡,四個(gè)終端節(jié)點(diǎn)(三次分割)的樹滿足要求。
在完整樹的基礎(chǔ)上桐智,prune()
函數(shù)根據(jù)復(fù)雜度參數(shù)減掉最不重要的枝书斜,從而將樹的大小控制在理想范圍內(nèi)。從代碼中的cptable
內(nèi)容中可以看到酵使,三次分割對應(yīng)的復(fù)雜度參數(shù)是0.0125荐吉,從而prune(dtree, cp=0.0125)
可得到一個(gè)理想大小的樹。
rpart.plo
包中的prp()
函數(shù)可用于畫出最終的決策樹口渔,它有很多的可供選擇參數(shù)样屠,如type=2
可畫出每個(gè)節(jié)點(diǎn)下分割的標(biāo)簽,extra=104
可畫出每一類的概率以及每個(gè)節(jié)點(diǎn)處的樣本占比缺脉,fallen.leaves=TRUE
可在圖的底端顯示終端節(jié)點(diǎn)痪欲。
對觀測點(diǎn)分類時(shí),從樹的頂端開始攻礼,若滿足條件則從左枝往下业踢,否則右枝往下,重復(fù)這個(gè)過程知道碰到一個(gè)終端節(jié)點(diǎn)為止礁扮。該終端節(jié)點(diǎn)即為這一觀測點(diǎn)的所屬類別知举。
最后predict()
函數(shù)用來對驗(yàn)證集中的觀測點(diǎn)分類。代碼內(nèi)容中給出了實(shí)際類別與預(yù)測類別的交叉表太伊。整體來看雇锡,準(zhǔn)確率還是非常高的。
條件推斷樹
條件推斷樹與傳統(tǒng)決策樹類似僚焦,但變量和分割的選取是基于顯著性檢驗(yàn)的锰提,而不是純凈度或同質(zhì)性一類的度量。顯著性檢驗(yàn)是置換檢驗(yàn)。
條件推斷的算法如下:
- 對輸出變量與每個(gè)預(yù)測變量間的關(guān)系計(jì)算p值立肘。
- 選取p值最小的變量边坤。
- 在因變量與被選中的變量間嘗試所有可能的二元分割(通過排列檢驗(yàn)),并選取最顯著的分割谅年。
- 將數(shù)據(jù)集分成兩群惩嘉,并對每個(gè)子群重復(fù)上述步驟。
- 重復(fù)直至所有分割都不顯著或已經(jīng)達(dá)到最小節(jié)點(diǎn)為止踢故。
條件推斷樹可由party
包中的ctree()
函數(shù)獲得文黎。
library(party)
fit.ctree <- ctree(class ~ ., data=df.train)
plot(fit.ctree, main="Conditional Inference Tree")
ctree.pred <- predict(fit.ctree, df.validate, type="response")
ctree.perf <- table(df.validate$class, ctree.pred,
dnn=c("Actual", "Predicted"))
ctree.perf
值得注意的是,對于條件推斷樹來說殿较,剪枝不是必需的耸峭,其生成過程相對更自動(dòng)化一些。另外淋纲,party
包也提供了許多圖像參數(shù)劳闹。
隨機(jī)森林
隨機(jī)森林是一種組成式的有監(jiān)督學(xué)習(xí)方法。在隨機(jī)森林中洽瞬,我們同時(shí)生成多個(gè)預(yù)測模型本涕,并將模型的結(jié)果匯總以提升分類準(zhǔn)確率。http://mng.bz/7Nul上有關(guān)于隨機(jī)森林的詳盡介紹伙窃。
隨機(jī)森林的算法涉及對樣本單元和變量的抽樣菩颖,從而生成大量決策樹。對每個(gè)樣本單元來說为障,所有的決策樹依次對其進(jìn)行分類晦闰。所有決策樹預(yù)測類別中的眾數(shù)類別即為隨機(jī)森林所預(yù)測的這一樣本的類別。
假設(shè)訓(xùn)練集中共有N個(gè)樣本單元鳍怨,M個(gè)變量呻右,則隨機(jī)森林算法如下:
- 從訓(xùn)練集中隨機(jī)有放回地抽取N個(gè)樣本單元,生成大量決策樹鞋喇。
- 在每一個(gè)節(jié)點(diǎn)隨機(jī)地抽取m<M個(gè)變量声滥,將其作為分割節(jié)點(diǎn)的候選變量。每一個(gè)節(jié)點(diǎn)處的變量數(shù)應(yīng)一致侦香。
- 完整生成所有決策樹落塑,無需剪枝。
- 終端節(jié)點(diǎn)的所屬類別由節(jié)點(diǎn)對應(yīng)的眾數(shù)類別決定鄙皇。
- 對于新的觀測點(diǎn)芜赌,用所有的樹對其進(jìn)行分類仰挣,其類別由多數(shù)決定原則生成伴逸。
生成樹時(shí)沒有用到的樣本點(diǎn)所對應(yīng)的類別可以由生成的樹估計(jì),與其真實(shí)類別比較即可得到袋外預(yù)測(out-of-bag, OOB)誤差膘壶。無法獲得驗(yàn)證集時(shí)错蝴,這是隨機(jī)森林的一大優(yōu)勢洲愤。隨機(jī)森林算法可以計(jì)算變量的相對重要程度。
randomForest
包中的randomForest()
函數(shù)可以用于生成隨機(jī)森林顷锰。函數(shù)默認(rèn)生成500棵樹柬赐,并且默認(rèn)在每個(gè)節(jié)點(diǎn)處抽取sqrt(M)
個(gè)變量,最小節(jié)點(diǎn)為1官紫。
library(randomForest)
set.seed(1234)
fit.forest <- randomForest(class ~ ., data=df.train,
na.action = na.roughfix,
importance = TRUE) # 生成森林
fit.forest
importance(fit.forest, type=2) # 給出變量重要性
forest.pred <- predict(fit.forest, df.validate) # 對訓(xùn)練集外樣本進(jìn)行分類
forest.perf <- table(df.validate$class, forest.pred,
dnn = c("Actual", "Predicted"))
forest.perf
幾個(gè)輸出結(jié)果
> fit.forest
Call:
randomForest(formula = class ~ ., data = df.train, importance = TRUE, na.action = na.roughfix)
Type of random forest: classification
Number of trees: 500
No. of variables tried at each split: 3
OOB estimate of error rate: 3.68%
Confusion matrix:
benign malignant class.error
benign 319 10 0.03039514
malignant 8 152 0.05000000
> importance(fit.forest, type=2)
MeanDecreaseGini
clumpThickness 12.504484
sizeUniformity 54.770143
shapeUniformity 48.662325
maginalAdhesion 5.969580
singleEpithelialCellSize 14.297239
bareNuclei 34.017599
blandChromatin 16.243253
normalNucleoli 26.337646
mitosis 1.814502
> forest.perf
Predicted
Actual benign malignant
benign 117 3
malignant 1 79
randomForest()
函數(shù)從訓(xùn)練集中有放回地隨機(jī)抽取489個(gè)觀測點(diǎn)肛宋,在每棵樹的每一個(gè)節(jié)點(diǎn)隨機(jī)抽取3個(gè)變量,從而生成了500棵傳統(tǒng)決策樹束世。na.action=na.roughfix
參數(shù)可將數(shù)值變量中的缺失值替換成對應(yīng)列的中位數(shù)酝陈,類別變量中的缺失值替換成對應(yīng)列的眾數(shù)類(若有多個(gè)眾數(shù)則隨機(jī)選一個(gè))。
隨機(jī)森林可度量變量重要性毁涉,通過設(shè)置information=TRUE
參數(shù)得到沉帮,并通過importance()
函數(shù)輸出。由type=2
參數(shù)得到的變量相對重要性就是分割該變量時(shí)節(jié)點(diǎn)不純度(異質(zhì)性)的下降總量對所有樹取平均贫堰。節(jié)點(diǎn)不純度由Gini系數(shù)定義穆壕。本例中,sizeUniformity
是最重要的變量其屏,mitosis
是最不重要的變量喇勋。
randomForest
包根據(jù)傳統(tǒng)決策樹生成隨機(jī)森林,而party
包中的cforest()
函數(shù)可以基于條件推斷樹生成隨機(jī)森林偎行。當(dāng)預(yù)測變量間高度相關(guān)時(shí)茄蚯,基于條件推斷樹的隨機(jī)森林可能效果更好。
相比較于其他分類方法睦优,隨機(jī)森林的分類準(zhǔn)確率通常更高渗常。另外,隨機(jī)森林算法可處理大規(guī)模問題(即多樣本單元汗盘、多變量)皱碘,可處理訓(xùn)練集中有大量缺失值的數(shù)據(jù),也可以應(yīng)對變量多于樣本單元的數(shù)據(jù)隐孽“┐唬可計(jì)算袋外預(yù)測誤差、度量變量重要性也是隨機(jī)森林的兩個(gè)明顯優(yōu)勢菱阵。
隨機(jī)森林的一個(gè)明顯缺點(diǎn)是分類方法較難理解和表達(dá)踢俄。
(關(guān)于這一章節(jié)的解釋比較細(xì)致,我也難以精簡晴及,保持原文能盡量幫助自己和大家理解都办。里面確實(shí)又涉及到了一些之前沒有接觸過的概念,因?yàn)槲視簳r(shí)也用不到,暫做粗淺理解琳钉。大家如果有興趣势木,查查查。現(xiàn)在百度看解釋和博文已經(jīng)成為一種習(xí)慣了~)
關(guān)于后續(xù)內(nèi)容歌懒,新知識點(diǎn)比較多啦桌,下次整理說明吧。
整理自R實(shí)戰(zhàn)