决策树与随机森林相关概念及其Python实现
2016-07-20 11:24
411 查看
决策树
所谓的决策树, 就是一种树形结构。其内部每个节点代表一个特征的测试,每个一个分支代表测试的输出,而每个叶子节点则代表一种类别。而随机森林,就是指的一群决策树所组成的一个森林。当一个新的样本需要归类,它的结果不是仅仅取决于某一刻决策树的结果,而是让森林里所有的决策树进行投票,选出结果最多的那类作为输出。
决策树形式如下:
构建决策树
构建决策树的基本思想是以信息熵为度量,构造一棵熵值下降最快的树(就是先判断对结果影响大的),到叶子节点处时熵值将为零(熵值大小即代表事物的不确定性度)。建立决策树有三种算法:
- ID3 : 以信息增益大小来建立。
- C4.5 : 以信息增益率大小来建立。
- CART : 以基尼系数大小来建立。
首先看看随机变量熵的定义:
信息增益:
信息增益率:
基尼指数:
其中,D表示数据集,|D|表示样本个数,A表示特征,|Ck|表示在有K个类的情况下属于类Ck的 样本个数(明显,∑|Ck|=|Dk|)。
关于熵的复习,参照以前写的笔记。
注:一个属性的信息增益越大,表明属性对样本的熵的减少能力更强,这个属性使得数据由不确定性变成确定性的能力更强。
代码如下:
#构造数据集及特征标签集 dataset = [ ['youth', 'no', 'no', 'just so-so', 'no'], ['youth', 'no', 'no', 'good', 'no'], ['youth', 'yes', 'no', 'good', 'yes'], ['youth', 'yes', 'yes', 'just so-so', 'yes'], ['youth', 'no', 'no', 'just so-so', 'no'], ['midlife', 'no', 'no', 'just so-so', 'no'], ['midlife', 'no', 'no', 'good', 'no'], ['midlife', 'yes', 'yes', 'good', 'yes'], ['midlife', 'no', 'yes', 'great', 'yes'], ['midlife', 'no', 'yes', 'great', 'yes'], ['geriatric', 'no', 'yes', 'great', 'yes'], ['geriatric', 'no', 'yes', 'good', 'yes'], ['geriatric', 'yes', 'no', 'good', 'yes'], ['geriatric', 'yes', 'no', 'great', 'yes'], ['geriatric', 'no', 'no', 'just so-so', 'no']] fea_labels = ['age', 'work', 'house', 'credit'] #计算数据集的经验熵 from math import log from collections import Counter def calEntropy(labels): newdic = {} Entropy=0.0 for item in labels: newdic[item]=newdic.get(item,0)+1 for itemN in newdic: prob=newdic[itemN]/len(labels) Entropy-=(prob*log(prob,2)) return Entropy #计算特征X对数据集D的经验条件熵H(D|X) def feaX_condi_Entropy(dataset,i): #提取第i项特征所有值及其对应的label feaX_label=[[x[i],x[-1]] for x in dataset] #去掉重复 feaX=[x[i] for x in dataset] feaX_diff=list(set(feaX)) feaX_Entropy=0.0 for diff_item in feaX_diff: labels=[] count=0 for item in feaX_label: if diff_item==item[0]: count+=1 labels.append(item[1]) feaX_Entropy+=count/len(feaX)*calEntropy(labels) return feaX_Entropy #计算信息增益 def cal_InfoGain(dataset,i): info_gain=0.0 label=[x[-1] for x in dataset] info_gain=calEntropy(label)-feaX_condi_Entropy(dataset,i) return info_gain #寻找当前数据集最大信息增益对应特征标号 def find_max_InfoGain(dataset): fea_num=len(dataset[1])-1 infogain=[] for i in range(fea_num): infogain.append(cal_InfoGain(dataset,i)) return infogain.index(max(infogain)),max(infogain) #构建决策树 def CreateDecesionTree(dataset,delta): #如果所有label均为同一类,则为单节点,并将其作为类标记 label=[x[- d0a2 1] for x in dataset] if len(set(label))==1: return label[0] #寻找当前数据集特征最大信息增益 max_feainfo_index,max_feainfo_val=find_max_InfoGain(dataset) #判断增益是否大于阈值,如果小于,则为单节点树,节点为D中最多的类作为类标记 if max_feainfo_val<delta: label_count=Counter(label) return max(label_count.items(), key=lambda x: x[1])[0] #以上都不满足,说明树可以继续生长,使用递归的方式继续建立树 #以字典方式来构建决策树,第一个存特征的标签,第二个存特征取的不同值,每一层决策树都由这两个字典共同构建 fea_dic={} fea_val_dic={} #首先找出最大信息增益的特征的标签 max_fea=[x[max_feainfo_index] for x in dataset] max_fea_diff=list(set(max_fea)) fea_label=fea_labels[max_feainfo_index] #根据选出的特征先划分数据集,然后递归生成决策树 for diff_val in max_fea_diff: dataset_new=[] for val in dataset: if diff_val==val[max_feainfo_index]: dataset_new.append(val[:max_feainfo_index]+val[max_feainfo_index+1:]) fea_val_dic[diff_val]=fea_val_dic.get(diff_val,CreateDecesionTree(dataset_new,delta)) fea_dic[fea_label]=fea_dic.get(fea_label,fea_val_dic) return fea_dic #最后可以直接用以下方式生成决策树: CreateDecesionTree(dataset,0.001)
生成的决策树如下:
{‘house’: {‘no’: {‘work’: {‘no’: ‘no’, ‘yes’: ‘yes’}}, ‘yes’: ‘yes’}}
这里决策树的每一层都用了两级字典来表示,第一级是特征标签,第二级是特征取值。
构建随机森林
构建随机森林实质就是构建多颗决策树。里面的每一颗决策树都是没有关联的。在构建决策树的过程中,有两点改进。
第一,对于训练数据是通过采样得到的。例如,训练集有N个样本,那么我们每次构建决策树时,都会又放回地对这个训练集采样N次,得到N个数据作为真正的训练集,这样做会出现的问题就是样本数据集里有很多重复的(一个通常说法是只有60%多的非重复数据)。这样,每一棵树的样本都不是全部样本,这就有效避免了过拟合问题。
第二,对于特征,也是通过采样得到的。例如,原来有M个特征,现在我们采样m个,使得m<=M。
通过以上两点,就能建立随机森林了。最后,当一个新样本进来时,森林里每一颗决策树都会产生一个结果,看看哪一类得到结果多,就认为样本属于那一类了。
对于随机森林的本质的一个比喻,引用如下:
按这种算法得到的随机森林中的每一棵都是很弱的,但是大家组合起来就很厉害了。我觉得可以这样比喻随机森林算法:每一棵决策树就是一个精通于某一个窄领域 的专家(因为我们从M个feature中选择m让每一棵决策树进行学习),这样在随机森林中就有了很多个精通不同领域的专家,对一个新的问题(新的输入数 据),可以用不同的角度去看待它,最终由各个专家,投票得到结果。
相关文章推荐
- 用Python从零实现贝叶斯分类器的机器学习的教程
- My Machine Learning
- 机器学习---学习首页 3ff0
- Spark机器学习(一) -- Machine Learning Library (MLlib)
- 反向传播(Backpropagation)算法的数学原理
- 关于SVM的那点破事
- 也谈 机器学习到底有没有用 ?
- #ML-SDN
- TensorFlow人工智能引擎入门教程之九 RNN/LSTM循环神经网络长短期记忆网络使用
- TensorFlow人工智能引擎入门教程之十 最强网络 RSNN深度残差网络 平均准确率96-99%
- TensorFlow人工智能引擎入门教程所有目录
- Tensorflow 杂记
- 如何用70行代码实现深度神经网络算法
- 验证码识别技术 一
- 量子计算机编程原理简介 和 机器学习
- 近200篇机器学习&深度学习资料分享(含各种文档,视频,源码等)
- 已经证实提高机器学习模型准确率的八大方法
- 初识机器学习算法有哪些?
- 机器学习相关的库和工具
- 10个关于人工智能和机器学习的有趣开源项目