决策树的Python实现demo(一天一个小demo!)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @createTime    : 18-5-22 下午4:44
# @author  : nn
import numpy as np
import math

data=[[0,1,0],[1,0,0],[0,1,0],[1,1,1]]
print(type(data))
data = np.array(data)
print(type(data))
for each_data in data:
    print each_data
**(1)计算给定数据集的信息熵的代码如下**:
def calcshan(data):
    lendata = len(data)
    p={}
    H=0
    for each_data in data:
        current_label = each_data[-1]
        if current_label not in p.keys():
            p[current_label] = 0  #此处初始化很重要,否则p[current_label] = p[current_label]+1会出现keyerror错误;
        p[current_label] += 1
    for keys in p.keys():
        px = float(p[keys])/float(lendata)
        H_1 = - px * math.log(px,2)
        H=H+H_1
    return H
H=calcshan(data)
print(H)
**(2)划分数据集,计算完信息熵后,我们便可以得到数据集的无序程度。我们将对每个特征划分数据集的结果计算一次信息熵,然后判断哪个特征划分数据集是最好的划分方式(根据信息熵判断,信息熵越小,说明划分效果越好)。**:
def splitData(data,axis,value):
    subDataSet = []
    for each_data in data:
        subData = []
        if each_data[axis] == value:
            subData = list(each_data[:axis])
            print subData
            subData.extend(each_data[axis+1:])
            print subData
            subDataSet.append(subData)
    return subDataSet
# subDataSet=splitData(data,0,1)
# print subDataSet
# subDataSet=splitData(data,0,0)
# print subDataSet

**(3)选择最好的数据集划分方式,代码如下:**
def chooseBestFeature(data):
    lenFeature = len(data[0])-1 #随便取一个样本的长度即为维度;
    shanInit = calcshan(data)
    feature = []
    inValue = 0
    bestFeature = 0
    for i in range(lenFeature):#以所有特征维度数遍历,逐步遍历以当前特征维度划分数据
        shanCarry = 0
        feature = [example[i] for example in data]
        feature = set(feature)
        for feat in feature :#遍历每一个特征的取值情况,第i个维度上取值为feat(遍历所有可能的取值)的数量
            subData = splitData(data,i,feat)  #遍历每一个特征的,splitData(data,i,feat),第i个维度上取值为feat的数量
            prob = float(len(subData)/float(len(data)))  #len(data)有多少行,即有多少个样本
            shanCarry += prob * calcshan(subData)

        outValue = shanInit - shanCarry #遍历当前划分属性得到的增益
        if (outValue > inValue):
            inValue = outValue
            bestFeature = i
    return bestFeature
feature = chooseBestFeature(data)
print(feature)
**(4)创建决策树。选择好最好的划分特征后,接下来,可以开始创建决策树了。其工作原理如下:得到原始数据集,然后基于最好的属性值划分数据集,由于特征值可能多于两个,因此可能存在大于两个分支的数据集划分。第一次划分后,数据将被向下传递到树分支的下一个节点,在这个节点上,我们可以再次划分数据。因此我们可以使用递归的原则处理数据集。递归结束的条件是:程序遍历完所有划分数据集的属性,或者每个分支下的所有实例都具有相同的分类。**
def createTree(data,label):
    classList = [example[-1] for example in data]
    if classList.count(classList[0]) == len(classList):
        return classList[0]
    featBest = chooseBestFeature(data)
    feature = [example[featBest] for example in data]
    featValue = set(feature)
    newLabel = label[featBest]
    del(label[featBest])
    Tree= {newLabel:{}}
    for value in featValue:
        subLabel = label[:]
        Tree[newLabel][value] = createTree(splitData(data,featBest,value),subLabel)
    return Tree
Tree = createTree(data,[0,1])
print(Tree)
**(5)验证数据集分类结果。依靠训练数据构造了决策树之后,我们可以将它用于实际数据的分类。在执行数据分类时,需要使用决策树以及用于构造树的标签向量。然后,程序比较测试数据与决策树上的数值,递归执行该过程直到进入叶子节点;最后将测试数据定义为叶子节点所属的类型。**
def classify(tree,label,testVec):
    firstFeat =tree.keys()[0]
    secondDict = tree[firstFeat]
    labelIndex = label.index(firstFeat)
    for key in secondDict.keys():
        if testVec[labelIndex] == key:
            if type(secondDict[key]).__name__ == 'dict':  #如果是字典-相当于如果当前不是叶节点,还是一棵树,需进一步区分
                classLabel = classify(secondDict[key],label,testVec)
            else:#当前节点是叶节点;
                classLabel = secondDict[key]
    return classLabel
print classify(Tree,[0,1],[0,1])
print classify(Tree,[0,1],[1,0])
print classify(Tree,[0,1],[0,0])
print classify(Tree,[0,1],[1,1])

参考:[决策树原理及Python代码实现](https://blog.csdn.net/flying_sfeng/article/details/62424225)

猜你喜欢

转载自blog.csdn.net/sinat_26566137/article/details/80410711
今日推荐