下边的代码是一个简单的C4.5决策树创建过程,该决策树不含有剪枝的过程,并且针对的属性必须是标量(非连续属性值)
#计算类属性的熵,其中data是一个数据框,它代表着原始数据,class.index是一个类的索引值
entropy <- function(data,class.index){
data[,class.index] = as.factor(data[,class.index])
class.freq.frame = as.data.frame(table(data[,class.index]))
class.freq.vec = class.freq.frame$Freq/sum(class.freq.frame$Freq)
zero.index.vec <- which(0 == class.freq.vec)
class.log.freq.vec[zero.index.vec] = 0;
}
entropy = -sum(class.freq.vec * class.log.freq.vec)
return(entropy)
}
subGain <- function(x,data,attr.index,class.index){
data.sub <- data[which(x == data[,attr.index]),]
entropy.sub <- entropy(data.sub,class.index)
return((dim(data.sub)[1]/dim(data)[1])*entropy.sub)
}
#计算单个属性的信息熵值
gain <- function(data, attr.index, class.index){
attr.val.vec <- unique(data[,attr.index])
attr.entropy.vec<-unlist(lapply(attr.val.vec, subGain,data = data, attr.index = attr.index, class.index = class.index))
return(entropy(data,class.index)-sum(attr.entropy.vec))
}
#calculate split information
splitInfo <- function(data, attr.index, class.index){
attr.val.vec <- unique(data[,attr.index])
split.val.vec <- unlist(lapply(attr.val.vec, function(x,data,attr.index) {split.freq=length(which(x == data[,attr.index]))/dim(data)[1];return(split.freq * log2(split.freq))}, data=data, attr.index=attr.index))
return(-sum(split.val.vec))
}
# calculate gain ratio
gainRation <- function(x, data, class.index){
attr.index = x
splitInfo.attr = splitInfo(data, attr.index, class.index)
#计算类属性的熵,其中data是一个数据框,它代表着原始数据,class.index是一个类的索引值
entropy <- function(data,class.index){
data[,class.index] = as.factor(data[,class.index])
class.freq.frame = as.data.frame(table(data[,class.index]))
class.freq.vec = class.freq.frame$Freq/sum(class.freq.frame$Freq)
class.log.freq.vec = log2(class.freq.vec)
#为了处理log2(0)的情况,人为设定log2(0)=0
if(any(class.freq.vec == 0)){zero.index.vec <- which(0 == class.freq.vec)
class.log.freq.vec[zero.index.vec] = 0;
}
entropy = -sum(class.freq.vec * class.log.freq.vec)
return(entropy)
}
subGain <- function(x,data,attr.index,class.index){
data.sub <- data[which(x == data[,attr.index]),]
entropy.sub <- entropy(data.sub,class.index)
return((dim(data.sub)[1]/dim(data)[1])*entropy.sub)
}
#计算单个属性的信息熵值
gain <- function(data, attr.index, class.index){
attr.val.vec <- unique(data[,attr.index])
attr.entropy.vec<-unlist(lapply(attr.val.vec, subGain,data = data, attr.index = attr.index, class.index = class.index))
return(entropy(data,class.index)-sum(attr.entropy.vec))
}
#calculate split information
splitInfo <- function(data, attr.index, class.index){
attr.val.vec <- unique(data[,attr.index])
split.val.vec <- unlist(lapply(attr.val.vec, function(x,data,attr.index) {split.freq=length(which(x == data[,attr.index]))/dim(data)[1];return(split.freq * log2(split.freq))}, data=data, attr.index=attr.index))
return(-sum(split.val.vec))
}
# calculate gain ratio
gainRation <- function(x, data, class.index){
attr.index = x
splitInfo.attr = splitInfo(data, attr.index, class.index)