###### decision tree ##########
install.packages('rpart.plot')
install.packages('rattle')
install.packages('RColorBrewer')
library(rpart)
library(rattle)
library(rpart.plot)
library(RColorBrewer)
###### model #############
model <- rpart(Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width, data = iris, method="class")
plot(model)
text(model)
fancyRpartPlot(model)
Prediction <- predict(model, test, type = "class")
model1 <- rpart(Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width, data = iris, method="class",control=rpart.control(minsplit=2, cp=0))
fancyRpartPlot(model1)
###### C5.0 #############
install.packages('C50')
select<-sample(1:nrow(iris),length(iris)*0.7)
train=iris[-select,]
test=iris[select,]
train<-na.omit(train)
library(C50)
ls('package:C50')
tc<-C5.0Control(subset =F,CF=0.25,winnow=F,noGlobalPruning=F,minCases =20)
model2 <- C5.0(Species ~.,data=train,rules=F,control =tc)
summary( model2 )
plot(model2)
C5imp(model2)
#自己編########
#決策樹的R語言實現如下:
library(plyr)
# 測試數據集 http://archive.ics.uci.edu/ml/datasets/Car+Evaluation
##計算訓練集合D的熵H(D)
##輸入:trainData 訓練集,類型爲數據框
## nClass 指明訓練集中第nClass列爲分類結果
##輸出:訓練集的熵
cal_HD <- function(trainData, nClass){
if ( !(is.data.frame(trainData) & is.numeric(nClass)) )
"input error"
if (length(trainData) < nClass)
"nClass is larger than the length of trainData"
rownum <- nrow(trainData)
#對第nClass列的值統計頻數
calss.freq <- count(trainData,nClass)
#計算每個取值的 概率*log2(概率)
calss.freq <- mutate(calss.freq, freq2 = (freq / rownum)*log2(freq / rownum))
-sum(calss.freq[,"freq2"])
#使用arrange代替order,方便的按照多列對數據框進行排序
#mtcars.new2 <- arrange(mtcars, cyl, vs, gear)
}
#cal_HD(mtcars,11)
##計算訓練集合D對特徵值A的條件熵H(D|A)
##輸入:trainData 訓練集,類型爲數據框
## nClass 指明訓練集中第nClass列爲分類結果
## nA 指明trainData中條件A的列號
##輸出:訓練集trainData對特徵A的條件熵
cal_HDA <- function(trainData, nClass, nA){
rownum <- nrow(trainData)
#對第nA列的特徵A計算頻數
nA.freq <- count(trainData,nA)
i <- 1
sub.hd <- c()
for (nA.value in nA.freq[,1]){
#取特徵值A取值爲na.value的子集
sub.trainData <- trainData[which(trainData[,nA] == nA.value),]
sub.hd[i] <- cal_HD(sub.trainData,nClass)
i <- i+1
}
nA.freq <- mutate(nA.freq, freq2 = (freq / rownum)*sub.hd)
sum(nA.freq[,"freq2"])
}
##計算訓練集合D對特徵值A的信息增益g(D,A)
##輸入:trainData 訓練集,類型爲數據框
## nClass 指明訓練集中第nClass列爲分類結果
## nA 指明trainData中特徵A的列號
##輸出:訓練集trainData對特徵A的信息增益
g_DA <- function(trainData, nClass, nA){
cal_HD(trainData, nClass) - cal_HDA(trainData, nClass, nA)
}
##根據訓練集合生成決策樹
##輸入:trainData 訓練集,類型爲數據框
## strRoot 指明根節點的屬性名稱
## strRootAttri 指明根節點的屬性取值
## nClass 指明訓練集中第nClass列爲分類結果
## cAttri 向量,表示當前可用的特徵集合,用列號表示
## e 如果特徵的最大信息增益小於e,則剩餘作爲一個分類,類頻數最高的最爲分類結果
##輸出:決策樹T
gen_decision_tree <- function(trainData, strRoot, strRootAttri, nClass, cAttri, e){
# 樹的描述,(上級節點名稱、上級節點屬性值、自己節點名稱,自己節點的取值)
decision_tree <- data.frame()
nClass.freq <- count(trainData,nClass) ##類別出現的頻數
nClass.freq <- arrange(nClass.freq, desc(freq)) ##按頻數從低到高排列
col.name <- names(trainData) ##trainData的列名
##1、如果D中所有屬於同一類Ck,則T爲單節點樹
if nrow(nClass.freq) == 1{
rbind(decision_tree, c(strRoot, strRootAttri, nClass.freq[1,1], ''))
return decision_tree
}
##2、如果屬性cAttri爲空,將D中頻數最高的類別返回
if length(cAttri) == 0{
rbind(decision_tree, c(strRoot, strRootAttri, nClass.freq[1,1], ''))
return decision_tree
}
##3、計算cAttri中各特徵值對D的信息增益,選擇信息增益最大的特徵值Ag及其信息增益
maxDA <- 0 #記錄最大的信息增益
maxAttriName <- '' #記錄最大信息增益對應的屬性名稱
maxAttriIndex <- '' #記錄最大信息增益對應的屬性列號
for(i in cAttri){
curDA <- g_DA(trainData,nClass,i)
if (maxDA <= curDA){
maxDA <- curDA
maxAttriName <- col.name[i]
}
}
##4、如果最大信息增益小於閾值e,將D中頻數最高的類別返回
if (maxDA < e){
rbind(decision_tree, c(strRoot, strRootAttri, nClass.freq[1,1], ''))
return decision_tree
}
##5、否則,對Ag的每一可能值ai,依Ag=ai將D分割爲若干非空子集Di
## 將Di中實例數最大的類作爲標記,構建子節點
## 由節點及其子節點構成樹T,返回T
for (oneValue in unique(trainData[,maxAttriName])){
sub.train <- trainData[which(trainData[,maxAttriName] == oneValue),] #Di
#sub.trian.freq <- count(sub.train,nClass) ##類別出現的頻數
#sub.trian.freq <- arrange(sub.trian.freq, desc(freq)) ##按頻數從低到高排列
rbind(decision_tree, c(strRoot, strRootAttri, maxAttriName , oneValue))
##6、遞歸構建下一步
# 剔除已經使用的屬性
next.cAttri <- cAttri[which(cAttri !=maxAttriIndex)]
# 遞歸調用
next.dt <-gen_decision_tree(sub.train, maxAttriName,
oneValue, nClass, next.cAttri, e)
rbind(decision_tree, next.dt)
}
names(decision_tree) <- c('preName','preValue','curName','curValue')
decision_tree
}
決策樹實現(R)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.