专栏首页python前行者[机器学习]python3构建决策树

[机器学习]python3构建决策树

1. 什么是决策树/判定树(decision tree)?

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

本次构建决策树的使用的算法是ID3算法,主要思想是利用不同特征值的信息熵来作为最优划分属性

csv文件

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))

运行结果:

['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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • sklearn-preprocessing使用

    将数据按期属性(按列进行)减去其均值,并处以其方差。得到的结果是,对于每个属性/每列来说所有数据都聚集在0附近,方差为1。

    周小董
  • python根据文章标题内容自动生成摘要

    周小董
  • Python操作HBase之happybase

    Hbase自带有线程安全的连接池,踏允许多个线程共享和重用已经打开的连接。这对于多线程的应用是非常有用的。当一个线程申请一个连接,它将获得一个租赁凭证,在此期间...

    周小董
  • keras分类模型中的输入数据与标签的维度实例

    参数 num_words=10000 的意思是仅保留训练数据中前 10 000 个最常出现的单词。

    砸漏
  • python读取文件——python读取和保存mat文件

        首先我们谈谈MarkDown编辑器,我感觉些倒是挺方便的,因为用惯了LaTeX,对于MarkDown还是比较容易上手的,但是我发现,MarkDown中有...

    zhaozhiyong
  • python机器学习速成|1|数据导入

    主要任务: ①完成常见的数据导入操作,包括数据导入,缺失值填充 ②完成常见的机器学习数据准备,包括特征二值化和训练集测试集的划分等

    用户1359560
  • 【python实现卷积神经网络】开始训练

    代码来源:https://github.com/eriklindernoren/ML-From-Scratch

    绝命生
  • [scikit-learn 机器学习] 4. 特征提取

    通常使用 one-hot 编码,产生2进制的编码,会扩展数据,当数据值种类多时,不宜使用

    Michael阿明
  • 【SOT】siameseFC论文和代码解析

    SOT的思想是,在视频中的某一帧中框出你需要跟踪目标的bounding box,在后续的视频帧中,无需你再检测出物体的bounding box进行匹配,而是通过...

    马上科普尚尚
  • 人工智能_1_初识_机器学习介绍_特征工程和文本特征提取

    Dean0731

扫码关注云+社区

领取腾讯云代金券