决策树实验
实验任务:
实现ID3决策树,并在给定的数据集上进行5折交叉验证。并观测训所得到的决策树在训练集和测试集的准确率,从而判断该决策树是否存在过拟合。在此基础上实现预剪枝和后剪枝,并比较预剪枝树与后剪枝树在训练集和测试集上的准确率。
编程语言:java, matlab, python, C++,C均可
数据集:
鸢尾花卉Iris数据集描述:
iris是鸢尾植物,这里存储了其萼片和花瓣的长宽,共4个属性,鸢尾植物分三类。所以该数据集一共包含4个特征变量,1个类别变量。共有150个样本,鸢尾有三个亚属,分别是山鸢尾 (Iris-setosa),变色鸢尾(Iris-versicolor)和维吉尼亚鸢尾(Iris-virginica)。
也就是说我们的数据集里每个样本含有四个属性,并且我们的任务是个三分类问题。三个类别分别为: Iris Setosa(山鸢尾),Iris Versicolour(杂色鸢尾),Iris Virginica(维吉尼亚鸢尾)。
例如:
样本一: 5.1, 3.5, 1.4, 0.2, Iris-setosa
其中“5.1,3.5,1.4,0.2”代表当前样本的四个属性的取值,“Iris-setosa”代表当前样本的类别。
实验完成要求:
完成上述实验的编码,并把实验流程,算法思想和在给定数据集上得到的指标记录到实验报告里。向助教老师演示所实现代码,并解释核心代码的思想。
实验步骤:
- 导入数据,打乱数据进行分层抽样,方便后续的交叉验证
- 每次对训练集的特征求信息增益Gain,最大的作为划分依据
- 求每个特征不同特征值的Gain(D,a,t),因为属于属于连续的,需要采用书本介绍的用二分值作为求解的值,需要对特征值进行sort
- Gain的求解需要计算信息熵Ent(),通过统计样本集类别数目求得
- 至此,基本工作就准备完成,接下来设计3种决策树算法的实现
- 决策树采用递归实现,每次对当前节点的训练集进行分析,求Gain,保存相应的特征feature和特征值featureValue,左右子集进行再一次训练,直到递归结束返回预测结果。
- 结束标志
- 当前节点包含的样本集合 train_list 为空,应该标记为其父节点集合中样本数最多的类
- 如果D中样本全属于同一类别,return 类别
- 当前属性集合为空(不可能)
- 样本集合中在属性集合的取值完全一样
- 预剪枝算法实现:在原有的基础上,只需比较两种方案的预测准确率,选择准确率高的方案即可。
- 后剪枝算法实现:需要在决策树生成后,自底向上的对每个非叶节点进行剪枝判断,仍以准确率为依据。
- 在生成3种不同的决策树后需要对其准确率进行比较,并实现五则交叉验证
代码:
import copy,math,random,numpy as np
class notLeaf():
def __init__(self):
self.layer = -1
self.feature = -1
self.feature_value = -1.00
self.remain_list = [0, 0, 0]
self.treeindex_list = []
node = [[notLeaf() for i in range(15)] for i in range(5)]
node_value = [-1,-1,-1,-1,-1]
'''实现数据文件读取,随机打乱,分层抽样'''
def inputData():
file_adress = "C:\python\MyCode_py\iris.data"
iris_data = open(file_adress, "r")
data_list = []
for airis in iris_data:
irsi = list(airis.rstrip("\n").split(","))
#print(num)
if irsi[-1] == 'Iris-setosa' : irsi[-1] = '0'
elif irsi[-1] == 'Iris-versicolor' : irsi[-1] = '1'
elif irsi[-1] == 'Iris-virginica' : irsi[-1] = '2'
if irsi.__len__() == 5 : data_list.append(irsi)
iris_data.close()
random.shuffle(data_list)