一、使用包party創建決策樹dom
這一節學習使用包party裏面的函數ctree()爲數據集iris創建一個決策樹。屬性Sepal.Length(萼片長度)、Sepal.Width(萼片寬度)、Petal.Length(花瓣長度)以及Petal.Width(花瓣寬度)被用來預測鳶尾花的Species(種類)。在這個包裏面,函數ctree()創建了一個決策樹,predict()預測另一個數據集。
在創建模型以前,iris(鳶尾花)數據集被分爲兩個子集:訓練集(70%)和測試集(30%)。使用隨機種子設置固定的隨機數,可使得隨機選取的數據是可重複利用的。函數
str(iris)學習
set.seed(1234)測試
ind <- sample(2, nrow(iris), replace=TRUE, prob=c(0.7, 0.3))優化
trainData <- iris[ind==1,]3d
testData <- iris[ind==2,]
加載包party創建一個決策樹,並檢測預測見過。函數ctree()提供一些參數例如MinSplit, MinBusket, MaxSurrogate 和 MaxDepth用來控制決策樹的訓練。下面咱們將會使用默認的參數設置去創建決策樹,至於具體的參數設置能夠經過?party查看函數文檔。下面的代碼中,myFormula公式中的Species(種類)是目標變量,其餘變量是獨立變量。
library(party)rest
myFormula <- Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Widthorm
iris_ctree <- ctree(myFormula, data=trainData)blog
table(predict(iris_ctree), trainData$Species)
顯示結果以下:
ip
由上圖可知,setosa(山鳶尾)40觀測值所有正確預測,而versicolor(變色鳶尾)有一個觀測值被誤判爲virginica(維吉尼亞鳶尾),virginica(維吉尼亞鳶尾)有3個觀測值被誤判爲versicolor(變色鳶尾)。
print(iris_ctree)
plot(iris_ctree)
plot(iris_ctree, type="simple")
在圖1中,每個葉子的節點的條形圖都顯示了觀測值落入三個品種的機率。在圖2中,這些機率以每一個葉子結點中的y值表示。例如:結點2裏面的標籤是「n=40 y=(1,0,0)」,指的是這一類中一共有40個觀測值,而且全部的觀測值的類別都屬於第一類setosa(山鳶尾)。
接下來,須要使用測試集測試決策樹。
testPred <- predict(iris_ctree, newdata = testData)
table(testPred, testData$Species)
結果以下:
從上圖的結果可知,決策樹對變色鳶尾和維吉尼亞鳶尾的識別仍然有誤判。所以ctree()如今的版本並不能很好的處理部分屬性不明確的值,在實例中既有可能被判到左子樹,有時候也會被判到右子樹上。
二、使用包rpart創建決策樹
rpart這個包在本節中被用來在'bodyfat'這個數據集的基礎上創建決策樹。函數raprt()能夠創建一個決策樹,而且能夠選擇最小偏差的預測。而後利用該決策樹使用predict()預測另一個數據集。
首先,加載bodyfat這個數據集,並查看它的一些屬性。
data("bodyfat", package = "TH.data")
dim(bodyfat)
attributes(bodyfat)
bodyfat[1:5,]
跟第1節同樣,將數據集分爲訓練集和測試集,並根據訓練集創建決策樹。
set.seed(1234)
ind <- sample(2, nrow(bodyfat), replace=TRUE, prob=c(0.7, 0.3))
bodyfat.train <- bodyfat[ind==1,]
bodyfat.test <- bodyfat[ind==2,]
library(rpart)
myFormula <- DEXfat ~ age + waistcirc + hipcirc + elbowbreadth + kneebreadth
bodyfat_rpart <- rpart(myFormula, data = bodyfat.train,
control = rpart.control(minsplit = 10))
plot(bodyfat_rpart)
text(bodyfat_rpart, use.n=T)
結果以下圖所示:
選擇預測偏差最小值的預測樹,從而優化模型。
opt <- which.min(bodyfat_rpart$cptable[,"xerror"])
cp <- bodyfat_rpart$cptable[opt, "CP"]
bodyfat_prune <- prune(bodyfat_rpart, cp = cp)
plot(bodyfat_rpart)
text(bodyfat_rpart, use.n=T)
優化後的決策樹以下:
對比結果就會發現,優化模型後,就是將hipcirc<99.5這個分層給去掉了,也許是由於這個分層沒有必要,那麼你們能夠思考一下選擇預測偏差最小的結果的決策樹的分層反而沒有那麼細。
以後,優化後的決策樹將會用來預測,預測的結果會與實際的值進行對比。下面的代碼中,使用函數abline()繪製一條斜線。一個好的模型的預測值應該是約接近真實值越好,也就是說大部分的點應該落在斜線上面或者在斜線附近。
DEXfat_pred <- predict(bodyfat_prune, newdata=bodyfat.test)
xlim <- range(bodyfat$DEXfat)
plot(DEXfat_pred ~ DEXfat, data=bodyfat.test, xlab="Observed",
ylab="Predicted", ylim=xlim, xlim=xlim)
abline(a=0, b=1)
繪製結果以下:
三、隨機森林
咱們使用包randomForest並利用鳶尾花數據創建一個預測模型。包裏面的randomForest()函數有兩點不足:第一,它不能處理缺失值,使得用戶必須在使用該函數以前填補這些缺失值;第二,每一個分類屬性的最大數量不能超過32個,若是屬性超過32個,那麼在使用randomForest()以前那些屬性必須被轉化。
也能夠經過另一個包'cforest'創建隨機森林,而且這個包裏面的函數並不受屬性的最大數量約束,儘管如此,高維的分類屬性會使得它在創建隨機森林的時候消耗大量的內存和時間。
ind <- sample(2, nrow(iris), replace=TRUE, prob=c(0.7, 0.3))
trainData <- iris[ind==1,]
testData <- iris[ind==2,]
library(randomForest)
rf <- randomForest(Species ~ ., data=trainData, ntree=100, proximity=TRUE)
table(predict(rf), trainData$Species)
結果以下:
由上圖的結果可知,即便在決策樹中,仍然有偏差,第二類和第三類話仍然會被誤判,能夠經過輸入print(rf)知道誤判率爲2.88%,也能夠經過輸入plot(rf)繪製每一棵樹的誤判率的圖。
最後,在測試集上測試訓練集上創建的隨機森林,並使用table()和margin()函數檢測預測結果。
irisPred <- predict(rf, newdata=testData)
table(irisPred, testData$Species)
plot(margin(rf, testData$Species))
顯示結果以下: