python 决策树

决策树是一种基本的分类与回归方法。这两天根据李航的《统计学习方法》里讲的决策树算法,
用python手撸了一遍决策树代码,写此博客作为记录。

DataSet.py:用于读数据集

import numpy
import re
def readData(filename, reg="\\s+"):
    if(filename.strip() == ''):
        print("文件名不能为空!")
        return
    file = open(filename)
    arraylines = file.readlines()

    alllist = []
    for line in arraylines:
        line = line.strip()
        listfromline = re.split(reg,line)
        print(listfromline)
        alllist.append(listfromline)
    returnmat = numpy.array(alllist)
    return returnmat

DecisionTree.py

import numpy
import DataSet
#计算集合D的经验熵H(D)
def EE(D):
    #D为矩阵,D中最后一列为类别,其余每列为一种特征
    C = dict.fromkeys(D[:,-1],0)
    for i in range(len(D)):
        C[D[i][-1]] = C[D[i][-1]]+1
    H = 0
    lenD = len(D)
    for key in C:
        t = -(C[key]/lenD)*numpy.log2(C[key]/lenD)
        H += t
    return H

#计算第A个特征对数据集D的经验条件熵,A(从0开始)为第几个特征
def ECE(D,Ai):
    H_DA = 0
    #得到第A个特征的分类
    dictA = dict.fromkeys(D[:, Ai], [])
    Di = numpy.array([])
    #将D中按照第A个特征分类
    lenD = len(D)
    for key in dictA:
        dictA[key] = list(numpy.where(D[:, Ai] == key)[0])
        Di = D[dictA[key]]
        H_DA += (len(dictA[key])/lenD)*EE(Di)
    return H_DA

#计算信息增益
def IG(D,Ai):
    G_DA = EE(D) - ECE(D,Ai)
    return G_DA

#得到最大信息增益
def getMostIG(D,A):
    GDAlist = []
    for Ai in range(len(A)):
        G_DA = IG(D, Ai)
        GDAlist.append([A[Ai],G_DA])
    best = sorted(GDAlist, key=lambda GDAlist: GDAlist[-1], reverse=True)
    return best[0][0],best[0][1]
def isSameType(D):
    for i in range(len(D)-1):
        if D[i,-1] != D[i+1,-1]:
            return False
    return True

def getMostLabel(D):
    dictlabel = dict.fromkeys(D[:,-1],0)
    for i in range(len(D)):
        dictlabel[D[i,-1]] = dictlabel[D[i,-1]]+1
    mostlabel = sorted(dictlabel.items(), key=lambda dictlabel: dictlabel[1], reverse=True)
    return mostlabel[0][0] #返回标签
def createTree(D,A,delta):
    #判断D中所有实例是否属于同一类Ck,若是就返回Ck作为该节点的类标记:
    if isSameType(D):
        return D[0,-1]
    #如果A为空,那么返回D中实例数最多的类作为该节点的类标记
    if len(A)==0:
        mostlabel = getMostLabel(D)
        return mostlabel
    #找到A中特征使得该特征对D有最大信息增益
    bestlabel,bestIG = getMostIG(D,A)
    if bestIG < delta:
        mostlabel = getMostLabel(D)
        return mostlabel
    #对bestlabel中每一个可能值,分割D,得到Di,使得Di重复以上步骤,同时将A-bestlabel作为新A输入
    index = A.index(bestlabel)
    del A[index]
    dictA = dict.fromkeys(D[:, index], [])
    myTree = {bestlabel:{}}
    for key in dictA:
        dictA[key] = list(numpy.where(D[:, index] == key)[0])
        Di = D[dictA[key]]
        Di = numpy.delete(Di,index,axis=1)
        myTree[bestlabel][key] = createTree(Di,A,delta)
    return myTree

#D为数据集矩阵,A为特征list,delta为阈值
def ID3(D,A,delta):
    dicisiontree = createTree(D,A,delta)
    return dicisiontree

D = DataSet.readData("d://dataset.txt")
A = ['年龄','有工作','有自己的房子','信贷情况']
delta = 0.01
dicisiontree = ID3(D,A,delta)
print(dicisiontree)

dataset.txt:数据集:

青年 否 否 一般 否
青年 否 否 好   否
青年 是 否 好   是
青年 是 是 一般 是
青年 否 否 一般 否
中年 否 否 一般 否
中年 否 否 好   否
中年 是 是 好   是
中年 否 是 非常好 是
中年 否 是 非常好 是
老年 否 是 非常好 是
老年 否 是 好 是
老年 是 否 好 是
老年 是 否 非常好 是
老年 否 否 一般 否

运行结果:

{'有自己的房子': {'否': {'有工作': {'否': '否', '是': '是'}}, '是': '是'}}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值