1. 什么是决策树/判定树(decision tree)?
判定树是一个类似于流程图的树结构:其中,每个内部结点表示在一个属性上的测试,每个分支代表一个属性输出,而每个树叶结点代表类或类分布。树的最顶层是根结点。
本次构建决策树的使用的算法是ID3算法,主要思想是利用不同特征值的信息熵来作为最优划分属性
csv文件
代码语言:javascript复制RID,age,income,student,credit_rating,class_buys_computer
1,youth,high,no,fair,no
2,youth,high,no,excellent,no
3,middle_aged,high,no,fair,yes
4,senior,medium,no,fair,yes
5,senior,low,yes,fair,yes
6,senior,low,yes,excellent,no
7,middle_aged,low,yes,excellent,yes
8,youth,medium,no,fair,no
9,youth,low,yes,fair,yes
10,senior,medium,yes,fair,yes
11,youth,medium,yes,excellent,yes
12,middle_aged,medium,no,excellent,yes
13,middle_aged,high,yes,fair,yes
14,senior,medium,no,excellent,no
步骤:
1、将以上列表存为.csv格式文件,读取特征值列表和Class列表 2、将特征值列表和Class列表转换为(0,1)形式 3、运用决策树分类 4、使模型可视化 5、利用测试集进行预测测试
- 数据分析
# Read in the csv file and put features into list of dict and list of class label
#注意使用csv.reader时,open参数如设置为’rb’会报错
allElectronicsData = open(r'./AllElectronics.csv', 'r')
reader = csv.reader(allElectronicsData)
headers = next(reader)#读取文件第一行
print(headers)
featureList = []
labelList = []
for row in reader:#继续读取后续内容
labelList.append(row[len(row)-1])#读取类别,即每一行的最后一个数据
rowDict = {}
for i in range(1, len(row)-1):
rowDict[headers[i]] = row[i]
featureList.append(rowDict)
注释1:注意使用csv.reader时,open参数如设置为’rb’会报错,具体见http://blog.csdn.net/darlingwood2013/article/details/70858086 注释2:版本3.2以前写法为reader.next()。next后reader指向下一行,因此后续的for循环中,row依次为第二行至最后一行,labelList的赋值中不会再出现第一行的内容。可用allElectronicsData.seek(0)返回文件开始位置
seek() 方法 用于移动文件读取指针到指定位置。 语法如下: fileObject.seek(offset[, whence]) 参数: offset – 开始的偏移量,也就是代表需要移动偏移的字节数 whence:可选,默认值为 0。给offset参数一个定义,表示要从哪个位置开始偏移;0代表从文件开头开始算起,1代表从当前位置开始算起,2代表从文件末尾算起。 该函数没有返回值。
next() 方法 Python 3 中的 File 对象不支持 next() 方法。 Python 3 的内置函数 next() 通过迭代器调用 next() 方法返回下一项。 在循环中,next()方法会在每次循环中调用,该方法返回文件的下一行,如果到达结尾(EOF),则触发 StopIteration语法 语法如下: next(iterator[,default]) 参数:无 返回值:返回文件下一行。
更多file方法 http://www.runoob.com/python3/python3-file-methods.html
- 源码:
# -*- coding:utf-8 -*-
from sklearn.feature_extraction import DictVectorizer
import csv
from sklearn import tree
from sklearn import preprocessing
from sklearn.externals.six import StringIO
# Read in the csv file and put features into list of dict and list of class label
allElectronicsData = open(r'./AllElectronics.csv', 'r')
reader = csv.reader(allElectronicsData)
headers = next(reader)
print(headers)
featureList = []
labelList = []
for row in reader:
labelList.append(row[len(row)-1])
rowDict = {}
for i in range(1, len(row)-1):
rowDict[headers[i]] = row[i]
featureList.append(rowDict)
print(featureList)
# Vetorize features 将特征列表转化为字符型的dummy v
vec = DictVectorizer()#实例化
dummyX = vec.fit_transform(featureList) .toarray()
print("dummyX: " str(dummyX))
print(vec.get_feature_names())
print("labelList: " str(labelList))
# vectorize class labels 将Class转化为dummyY
lb = preprocessing.LabelBinarizer()#实例化
dummyY = lb.fit_transform(labelList)
print("dummyY: " str(dummyY))
# Using decision tree for classification (运用决策树分类)
# clf = tree.DecisionTreeClassifier()
clf = tree.DecisionTreeClassifier(criterion='entropy')
clf = clf.fit(dummyX, dummyY)# 用训练数据拟合分类器模型
print("clf: " str(clf))
# Visualize model 使模型可视化
with open("./allElectronicInformationGainOri.dot", 'w') as f:
f = tree.export_graphviz(clf, feature_names=vec.get_feature_names(), out_file=f)
#测试集
oneRowX = dummyX[0, :]
print("oneRowX: " str(oneRowX))
newRowX = oneRowX
newRowX[0] = 1
newRowX[2] = 0
print("newRowX: " str(newRowX))
predictedY = clf.predict([newRowX])# 用训练好的分类器去预测
print("predictedY: " str(predictedY))
运行结果:
代码语言:javascript复制['RID', 'age', 'income', 'student', 'credit_rating', 'class_buys_computer']
[{'age': 'youth', 'income': 'high', 'student': 'no', 'credit_rating': 'fair'}, {'age': 'youth', 'income': 'high', 'student': 'no', 'credit_rating': 'excellent'}, {'age': 'middle_aged', 'income': 'high', 'student': 'no', 'credit_rating': 'fair'}, {'age': 'senior', 'income': 'medium', 'student': 'no', 'credit_rating': 'fair'}, {'age': 'senior', 'income': 'low', 'student': 'yes', 'credit_rating': 'fair'}, {'age': 'senior', 'income': 'low', 'student': 'yes', 'credit_rating': 'excellent'}, {'age': 'middle_aged', 'income': 'low', 'student': 'yes', 'credit_rating': 'excellent'}, {'age': 'youth', 'income': 'medium', 'student': 'no', 'credit_rating': 'fair'}, {'age': 'youth', 'income': 'low', 'student': 'yes', 'credit_rating': 'fair'}, {'age': 'senior', 'income': 'medium', 'student': 'yes', 'credit_rating': 'fair'}, {'age': 'youth', 'income': 'medium', 'student': 'yes', 'credit_rating': 'excellent'}, {'age': 'middle_aged', 'income': 'medium', 'student': 'no', 'credit_rating': 'excellent'}, {'age': 'middle_aged', 'income': 'high', 'student': 'yes', 'credit_rating': 'fair'}, {'age': 'senior', 'income': 'medium', 'student': 'no', 'credit_rating': 'excellent'}]
dummyX: [[0. 0. 1. 0. 1. 1. 0. 0. 1. 0.]
[0. 0. 1. 1. 0. 1. 0. 0. 1. 0.]
[1. 0. 0. 0. 1. 1. 0. 0. 1. 0.]
[0. 1. 0. 0. 1. 0. 0. 1. 1. 0.]
[0. 1. 0. 0. 1. 0. 1. 0. 0. 1.]
[0. 1. 0. 1. 0. 0. 1. 0. 0. 1.]
[1. 0. 0. 1. 0. 0. 1. 0. 0. 1.]
[0. 0. 1. 0. 1. 0. 0. 1. 1. 0.]
[0. 0. 1. 0. 1. 0. 1. 0. 0. 1.]
[0. 1. 0. 0. 1. 0. 0. 1. 0. 1.]
[0. 0. 1. 1. 0. 0. 0. 1. 0. 1.]
[1. 0. 0. 1. 0. 0. 0. 1. 1. 0.]
[1. 0. 0. 0. 1. 1. 0. 0. 0. 1.]
[0. 1. 0. 1. 0. 0. 0. 1. 1. 0.]]
['age=middle_aged', 'age=senior', 'age=youth', 'credit_rating=excellent', 'credit_rating=fair', 'income=high', 'income=low', 'income=medium', 'student=no', 'student=yes']
labelList: ['no', 'no', 'yes', 'yes', 'yes', 'no', 'yes', 'no', 'yes', 'yes', 'yes', 'yes', 'yes', 'no']
dummyY: [[0]
[0]
[1]
[1]
[1]
[0]
[1]
[0]
[1]
[1]
[1]
[1]
[1]
[0]]
clf: DecisionTreeClassifier(class_weight=None, criterion='entropy', max_depth=None,
max_features=None, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, presort=False, random_state=None,
splitter='best')
oneRowX: [0. 0. 1. 0. 1. 1. 0. 0. 1. 0.]
newRowX: [1. 0. 0. 0. 1. 1. 0. 0. 1. 0.]
predictedY: [1]
可以看到对于一个输入数据,成功的进行了预测。
此外,利用graphviz还可以很方便的将程序过程中生成的.dot文件转化为pdf文件进行显示决策树的样子,具体方法是在终端下输入:dot -Tpdf name.dot -o name1.pdf
,在这个程序中生成的决策树如下图所示:
安装 Graphviz: http://www.graphviz.org/
配置环境变量
转化dot文件至pdf可视化决策树:dot -Tpdf iris.dot -o outpu.pdf
决策树归纳算法 (ID3)
1970-1980, J.Ross. Quinlan, ID3算法
选择属性判断结点
信息获取量(Information Gain):Gain(A) = Info(D) - Infor_A(D)
通过A来作为节点分类获取了多少信息
类似,Gain(income) = 0.029, Gain(student) = 0.151, Gain(credit_rating)=0.048
所以,选择age作为第一个根节点
二、遇到的问题及解决办法
1、打开.csv文件出错的情况及解决办法 如果出现下图情况,第一列数据乱码,那就是你存为.csv文件时候的选择错了
应该选择如图所示:
下图所示选择会出现乱码:
2、如果出现这样的错误提示:AttributeError: ‘_csv.reader’ object has no attribute ‘next’
需要更改headers = reader.next() 为headers = next(reader)即可,这应该是Python3和Python2的区别
3、模型可视化时.dot文件转化为graphviz注意的问题 在cmd命令中输入dot -Tpdf iris.dot -o output.pdf (1) 注意iris.dot为你的.dot文件所在路径 (2)输出文件路径为cmd命令行前面的路径
4、测试集预测出现的问题: array=[ 1. 0. 0. 0. 1. 1. 0. 0. 1. 0.]. Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample. 如图所示:
解决办法:这是因为数据集newRowX数组矩阵需要加个中括号[ ]如图所示:
参考:https://blog.csdn.net/fengyueshengqi/article/details/79169550