机器学习日志——决策树算法详解

算法原理

决策树是一种类似于流程图的树结构。其中,每个内部结点表示在一个属性上的测试,每个分支代表一个属性输出,而每个树叶结点代表类或类分布。树的最顶层是根结点,典型决策树如下:


这个例子是根据天气决定当天是否游玩。

最上面的节点我们称为根节点,即为OUTLOOK,其中OUTLOOK代表天气,这里有三种情况,sunny,overcast与rain,我们需要判断今天的OUTLOOK怎么样,所以这个根节点代表了属性上的测试(我们判断天气怎么样),在这个根节点下,我们有14个实例,其中9个是没有出去玩,5个是出去玩。

第二层的三个节点代表了属性的输出,天气分别为这三种情况下的输出,其中,sunny这种属性下,有两个人实例选择出去玩,3个实例没有出去玩。

第三层是在第二层的基础上细分,例如sunny的湿度,大于70,选择出去玩的实例为0个,小于等于70,选择出去玩的实例为2个

下面举个例子


根据以上信息,我们需要构建一个决策树,但是,怎么决定节点的层数和顺序呢

所以我们需要一个归纳算法,这里我们使用常用的ID3算法,这里不做介绍,只做说明简介

这里我们提出几个指标,

信息熵(用来衡量信息的多少)



其中,P(x)代表事件x发生的概率,事件x的不确定性越大,熵h(x)越大


信息获取量:


通过A来作为节点分类获取了多少信息,Info(A)表示有A的信息量,Infor_A(D)表示没有A时的信息量


这是是否购买电脑这一特征的信息熵,一个14个样本,9个购买,5个没有购买,9/14为bug中yes的概率,5/14为bug中no的概率



对于age来说,针对bug这属性下的信息熵为,一共14个样本,young占5个,minage为4个,senior为5个,这时第一层系数5/14,4/14,5/14的意义,而第二层是这对应个数样本中,例如young有5个样本,其中两个是buy_yes,3个是buy_no,这样我们可以计算出有age的信息熵


所以没age的信息熵减去有age的信息熵,得到age的信息获取量


所以我们可以算出所有属性的信息获取量,发现age最大,因此选择age作为根节点。


类似的,我们可以同理获取以下的节点信息获取量,选择出节点的位置


#决策树(ID3)根据信息熵来
# _*_ coding: utf-8 _*_
from sklearn.feature_extraction import DictVectorizer #将dict类型的list数据,转换成numpy array
import csv#读取CSV文件
from sklearn import preprocessing  #数据预处理
from sklearn import tree#导入决策树算法
from sklearn.externals.six import StringIO

# 读入数据 "rU"
allData = open(r'D:\Machine_learning\1.csv', "rU")
reader=csv.reader(allData)#用reader来代表所有数据
headers=next(reader) #header是指数据的第一行,就是数据的特征
#print(headers)
#因为SK包的数据输入是有一定的要求的,他的输入不能是类别。只能是 0,scrapy。所以要先将数据转化成DICT类型
#然后用DictVextorizer的函数进行转换
featurelist=[]#定义一个存放特征的列表 自变量
labelList=[]#定义一个存放标签的列表 因变量
for row in reader:#以行遍历所有数据
    labelList.append(row[len(row) - 1])#取每一行最后一个值,即Bug值#取出最后一个值,这个值是每条数据的标签
    rowDic = {}#创建一个字典,用于存放特征值
    for i in range(1, len(row) - 1):
        rowDic[headers[i]] = row[i]#把每条数据的 特征:属性 插入字典
    featurelist.append(rowDic)#把字典插入列表
#print("featureList:" + str(featureList))
#print("lablelist:" + str(lableList))
#将字符型特征值转化为1/0
vec = DictVectorizer()#实例化
dummyX = vec.fit_transform(featurelist).toarray()#使用实例内的方法对数据进行转换
#print("dummyX:" + str(dummyX))#打印出转换后的数据的表值
#print("get_feature_names():" + str(vec.get_feature_names()))#打印出转换后的数据的表头
#建立决策树
lb = preprocessing.LabelBinarizer()#实例化
dummyY = lb.fit_transform(labelList)#数据的转换
#print("dummyY:" + str(dummyY))
#上面的过程就是把数据都转换成符合格式的数据了
#可以调用sk包中的决策树算法进行分类

clf = tree.DecisionTreeClassifier(criterion="entropy")#使用信息增益的方法
clf = clf.fit(dummyX, dummyY)#构建决策树
#print("clf:" + str(clf))
#输出到DOT文件中
with open("DecisionTree_BuyCompute.dot", "w") as f:
    f = tree.export_graphviz(clf, feature_names=vec.get_feature_names(), out_file=f)#要安装可视化工具graphviz
#dot -Tpdf D:\Machine_learning/DecisionTree_BuyCompute.dot -o output.pdf
# 转化dot文件至pdf可视化决策树(cmd):dot -Tpdf 路径文件.dot -o =路径文字.pdf

#预测数据
oneRowX = dummyX[0, :]
print("oneRowX:" + str(oneRowX))
newRowX = oneRowX
newRowX[0] = 1
newRowX[2] = 0

print("newRowx:" + str(newRowX))
predictedY = clf.predict(newRowX.reshape(1, -1))
print("predictedY" + str(predictedY))



猜你喜欢

转载自blog.csdn.net/qq_41686130/article/details/79853617