python实现决策树算法

  

python实现决策树算法?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

& # 39; & # 39; & # 39;   数据集:Mnist   训练集数量:60000   测试集数量:10000   ------------------------------   运行结果:ID3(未剪枝)   正确率:85.9%   运行时长:356年代   & # 39;& # 39;& # 39;      导入的时间   进口numpy np         def loadData(文件名):   & # 39;& # 39;& # 39;   加载文件   :param文件名:要加载的文件路径   返回:数据集和标签集   & # 39;& # 39;& # 39;   #存放数据及标记   dataArr=[];   labelArr=[]   #读取文件   fr=开放(文件名)   #遍历文件中的每一行   线的fr.readlines ():   #获取当前行,并按”、“切割成字段放入列表中   #地带:去掉每行字符串首尾指定的字符(默认空格或换行符)   #分裂:按照指定的字符将字符串切割成每个字段,返回列表形式   curLine=line.strip () .split (& # 39; & # 39;)   #将每行中除标记外的数据放入数据集中(curLine[0]为标记信息)   #在放入的同时将原先字符串形式的数据转换为整型   #此外将数据进行了二值化处理,大于128的转换成1,小于的转换成0,方便后续计算   dataArr.append ([int (int (num)比;128)的num curLine [1:]])   #将标记信息放入标记集中   #放入的同时将标记转换为整型   labelArr.append (int (curLine [0]))   #返回数据集和标记   返回dataArr labelArr         def majorClass (labelArr):   & # 39;& # 39;& # 39;   找到当前标签集中占数目最大的标签   :param labelArr:标签集   返回:最大的标签   & # 39;& # 39;& # 39;   #建立字典,用于不同类别的标签技术   classDict={}   #遍历所有标签   因为我在范围(len (labelArr)):   #当第一次遇到一个标签时,字典内还没有一个标签,这时候直接幅值加1是错误的,   #所以需要判断字典中是否有该键,没有则创建,有就直接自增   如果labelArr[我]classDict.keys ():   #若在字典中存在该标签,则直接加1   classDict [labelArr[我]]+=1   其他:   #若无该标签,设初值为1,表示出现了1次了   classDict [labelArr[我]]=1   #对字典依据值进行降序排序   classSort=排序(classDict.items(),关键=λx: x[1],反向=True)   #返回最大一项的标签,即占数目最多的标签   返回classSort [0] [0]         def calc_H_D (trainLabelArr):   & # 39;& # 39;& # 39;   计算数据集D的经验熵,参考公式5.7经验熵的计算   :param trainLabelArr:当前数据集的标签集   返回:经验熵   & # 39;& # 39;& # 39;   #初始化为0   H_D=0   #将当前所有标签放入集合中,这样只要有的标签都会在集合中出现,且出现一次。   #遍历该集合就可以遍历所有出现过的标记并计算其Ck   #这么做有一个很重要的原因:首先假设一个背景,当前标签集中有一些标记已经没有了,比如说标签集中   #没有0(这是很正常的,说明当前分支不存在这个标签),式5.7中有一项Ck,那按照式中的针对不同标签k   #计算Cl和D并求和时,由于没有0,那么C0=0,此时C0/D0=0, log2 (C0/D0)=log2(0),事实上0并不在日志的   #定义区间内,出现了问题   #所以使用集合的方式先知道当前标签中都出现了那些标签,随后对每个标签进行计算,如果没出现的标签那一项就   #不在经验熵中出现(未参与,对经验熵无影响),保证日志的计算能一直有定义   trainLabelSet=集([标签,标签在trainLabelArr])   #遍历每一个出现过的标签   因为我在trainLabelSet:   #计算| Ck/| | |   # trainLabelArr==我:当前标签集中为该标签的的位置   #例如a=[1, 0, 0, 1], c=(==1): c==(真的,假的,假的,真的)   # trainLabelArr [trainLabelArr==我]:获得为指定标签的样本   # trainLabelArr [trainLabelArr==我].size:获得为指定标签的样本的大小,即标签为我的样本   #数量,就是| Ck |   # trainLabelArr.size:整个标签集的数量(也就是样本集的数量),即| |   p=trainLabelArr [trainLabelArr==我]。尺寸/trainLabelArr.size   #对经验熵的每一项累加求和   H_D +=1 * p * np.log2 (p)      #返回经验熵   返回H_D         def calcH_D_A (trainDataArr_DevFeature trainLabelArr):   & # 39;& # 39;& # 39;   计算经验条件熵   :param trainDataArr_DevFeature:切割后只有功能那列数据的数组   :param trainLabelArr:标签集数组   返回:经验条件熵   & # 39;& # 39;& # 39;   #初始为0   H_D_A=0   #在featue那列放入集合中,是为了根据集合中的数目知道该特性目前可取值数目是多是少   trainDataSet=集([标签,标签在trainDataArr_DevFeature])      #对于每一个特征取值遍历计算条件经验熵的每一项   因为我在trainDataSet:   #计算H (D |)   # trainDataArr_DevFeature [trainDataArr_DevFeature==我]。尺寸/trainDataArr_DevFeature。大小:Di/D | | | |   # calc_H_D (trainLabelArr [trainDataArr_DevFeature==我]):H (Di)   H_D_A +=trainDataArr_DevFeature [trainDataArr_DevFeature==我]。尺寸/trainDataArr_DevFeature。大小\   * calc_H_D (trainLabelArr [trainDataArr_DevFeature==我])   #返回得出的条件经验熵   返回H_D_A         def calcBestFeature (trainDataList trainLabelList):   & # 39;& # 39;& # 39;   计算信息增益最大的特征   :param trainDataList:当前数据集   :param trainLabelList:当前标签集   返回:信息增益最大的特征及最大信息增益值   & # 39;& # 39;& # 39;   #将数据集和标签集转换为数组形式   # trainLabelArr转换后需要转置,这样在取数时方便   #例如=np。数组([1,2,3]);b=np。阵列([1,2,3]).T   #若不转置,[0]=[1,2,3],转置后b [0]=1, b [1]=2   #对于标签集来说,能够很方便地取到每一位是很重要的   trainDataArr=np.array (trainDataList)   trainLabelArr=np.array .T (trainLabelList)      #获取当前特征数目,也就是数据集的横轴大小   featureNum=trainDataArr.shape [1]      #初始化最大信息增益   maxG_D_A=1   #初始化最大信息增益的特征   maxFeature=1   #对每一个特征进行遍历计算   的功能范围(featureNum):   #“5.2.2信息增益”中“算法5.1(信息增益的算法)”第一步:   # 1。计算数据集D的经验熵H (D)   H_D=calc_H_D (trainLabelArr)   # 2。计算条件经验熵H (D |)   #由于条件经验熵的计算过程中只涉及到标签以及当前特征,为了提高运算速度(全部样本   #做成的矩阵运算速度太慢,需要剔除不需要的部分),将数据集矩阵进行切割   #数据集在初始时刻是一个Arr=60000 * 784的矩阵,针对当前要计算的特性,在训练集中切割下   # Arr(:,特性)这么一条来,因为后续计算中数据集中只用到这个(没明白的跟着算一遍例5.2)   # trainDataArr(:,特性):在数据集中切割下这么一条   # trainDataArr[:,特性].flat:将这么一条转换成竖着的列的表   # np。阵列(trainDataArr[:,特性].flat):再转换成一条竖着的矩阵,大小为60000 * 1(只是初始是   #这么大,运行过程中是依据当前数据集大小动态变的)   trainDataArr_DevideByFeature=np。阵列(trainDataArr[:,特性].flat)   # 3。计算信息增益G (D |) G (D |)=H (D) - H (D |)   G_D_A=H_D - calcH_D_A (trainDataArr_DevideByFeature trainLabelArr)   #不断更新最大的信息增益以及对应的特性   如果G_D_A比;maxG_D_A:   maxG_D_A=G_D_A   maxFeature=功能   返回maxFeature maxG_D_A         def getSubDataArr (trainDataArr trainLabelArr,,):   & # 39;& # 39;& # 39;   更新数据集和标签集   :param trainDataArr:要更新的数据集   :param trainLabelArr:要更新的标签集   :param答:要去除的特征索引   :param答:当数据(一)==时,说明该行样本时要保留的   返回:新的数据集和标签集   & # 39;& # 39;& # 39;   #返回的数据集   retDataArr=[]   #返回的标签集   retLabelArr=[]   #对当前数据的每一个样本进行遍历   因为我在范围(len (trainDataArr)):   #如果当前样本的特征为指定特征值   如果trainDataArr[我][一]==:   #那么将该样本的第一个特征切割掉,放入返回的数据集中   retDataArr。追加(trainDataArr[我][0:]+ trainDataArr[我][+ 1:])   #将该样本的标签放入返回标签集中   retLabelArr.append (trainLabelArr[我])   #返回新的数据集和标签集   返回retDataArr retLabelArr         def createTree数据集(*):   & # 39;& # 39;& # 39;   递归创建决策树   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

python实现决策树算法