开局一张图(网图,随便找的)。

对这种类型的图很熟悉的小伙伴应该马上就看出来了,这是一颗决策树,没错今天我们的主题就是理解和实现决策树。

决策树和我们以前学过的算法稍微有点不一样,它是个树形结构。决策树的决策流程就是从所有输入特征中选择一个特征做为决策的依据,找出一个阈值来决定将其划分到哪一类。

也就是说,创建一个决策树的主要问题在于:

1.决策树中每个节点在哪个维度的特征上面进行划分?

2.被选中的维度的特征具体在哪个值上进行划分?

为了解决这两个问题我们引入信息熵的概念。

信息熵的概念本身是信息论中的一个重要概念,因为我们的重点是决策树,所以就不多涉及信息论的知识,我们只需要知道信息熵是什么。

信息熵简单的来说就是表示随机变量不确定度的度量。

熵越大,数据的不确定性就越大。

熵越小,数据的不确定性就越小,也就是越确定。

信息熵的计算公式

其中

是指,数据中一共有n类信息,
就是指第i类数据所占的比例。

举个例子,假设我们的数据中一共有三类。每一类所占比例为

,那么信息熵就是

假设我们数据一共有三类,每类所占比例是0,0,1,那么信息熵就是

(注:实际上log(0)是不能计算的,定义上不允许,真实场景会做其他处理解决这个问题)

很显然第二组数据比第一组数据信息熵小,也就是不确定性要少,换句话讲就是更为确定。

根据这两个例子,应该就能理解信息熵是随机变量不确定度的度量了。

如果我们的数据偏向于某一个类别,随机变量的不确定性就降低了,会变的更为确定。

现在来回答关于决策树的两个问题:

1.决策树中每个节点在哪个维度的特征上面进行划分?

2.被选中的维度的特征具体在哪个值上进行划分?

我们希望决策树每次划分数据都能让信息熵降低,当划分到最后一个叶子节点里面只有一类数据的时候,信息熵就自然的降为了0,所属的类别就完全确定了。

那么问题来了,我们怎样找到一个这样的划分使得划分后的信息熵会降低?答案是对着所有维度的特征来一次搜索就行了。

我们来模拟一下这个过程。

导入数据和包

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import numpy as np
import matplotlib.pyplot as plt
from collections import Counter
from math import logiris = load_iris()
x = iris.data
y = iris.target
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=666666)

计算熵

def entropy(y_label):counter = Counter(y_label)ent = 0.0for num in counter.values():p = num / len(y_label)ent += -p * log(p)return ent

划分数据集

def split(x_data, y_label, dimension, value):"""x_data:输入特征y_label:输入标签类别dimension:选取输入特征的维度索引value:划分特征的数值return 左子树特征,右子树特征,左子树标签,右子树标签"""index_left = (x_data[:,dimension] <= value)index_right = (x_data[:,dimension] > value)return x_data[index_left], x_data[index_right], y_label[index_left], y_label[index_right]

划分一次数据集

遍历所有维度的特征,不断寻找一个合适的划分数值,找到能把熵降到最低的那个特征和数值

def one_split(x_data, y_label):best_entropy = float('inf')best_dimension = -1best_value = -1for d in range(x_data.shape[1]):sorted_index = np.argsort(x_data[:, d])for i in range(1,len(x_data)):if x_data[sorted_index[i], d] != x_data[sorted_index[i - 1], d]:value = (x_data[sorted_index[i], d] + x_data[sorted_index[i-1], d]) / 2x_left, x_right, y_left, y_right = split(x_data, y_label, d, value)p_left = len(x_left) / len(x_data)p_right = len(x_right) / len(x_data)ent = p_left * entropy(y_left) + p_right * entropy(y_right)if ent < best_entropy:best_entropy = entbest_dimension = dbest_value = valuereturn best_entropy, best_dimension, best_value

第一次模拟划分

找出最好的划分维度和对应的数值

best_entropy, best_dimension, best_value = one_split(x_train, y_train)
print(best_entropy)
print(best_dimension) #第二个维度的特征
print(best_value) #划分的数值

获取左子树特征,右子树特征,左子树标签,右子树标签

x_left, x_right, y_left, y_right = split(x_train, y_train, best_dimension, best_value)

再来一轮划分

  • 左子树的熵已经是0了,没必要划分了
best_entropy, best_dimension, best_value = one_split(x_left, y_left)
print(best_entropy)
print(best_dimension) #第0个维度的特征
print(best_value) #划分的数值

我们继续划分右子树

best_entropy, best_dimension, best_value = one_split(x_right, y_right)
print(best_entropy)
print(best_dimension)
print(best_value)

x_left2, x_right2, y_left2, y_right2 = split(x_right,y_right,best_dimension,best_value)

经过了两轮划分,基本上决策树已经划分的差不多了,根据对应维度的特征和阈值决策就行了。如果你熟悉数据结构中的二叉树结构的话自己就能将决策树给建起来。

下面给出封装好的代码,可以像调用sklearn的决策树一样调用它。

class Node:def __init__(self,x_data, y_label, dimension, value):self.x_data = x_dataself.y_label = y_labelself.dimension = dimensionself.value = valueself.left = Noneself.right = Noneclass DTree:def __init__(self):self.root = Nonedef fit(self,x_train, y_train):def entropy(y_label):counter = Counter(y_label)ent = 0.0for num in counter.values():p = num / len(y_label)ent += -p * log(p)return entdef one_split(x_data, y_label):best_entropy = float('inf')best_dimension = -1best_value = -1for d in range(x_data.shape[1]):sorted_index = np.argsort(x_data[:, d])for i in range(1,len(x_data)):if x_data[sorted_index[i], d] != x_data[sorted_index[i - 1], d]:value = (x_data[sorted_index[i], d] + x_data[sorted_index[i-1], d]) / 2x_left, x_right, y_left, y_right = split(x_data, y_label, d, value)p_left = len(x_left) / len(x_data)p_right = len(x_right) / len(x_data)ent = p_left * entropy(y_left) + p_right * entropy(y_right)if ent < best_entropy:best_entropy = entbest_dimension = dbest_value = valuereturn best_entropy, best_dimension, best_valuedef split(x_data, y_label, dimension, value):"""x_data:输入特征y_label:输入标签类别dimension:选取输入特征的维度索引value:划分特征的数值return 左子树特征,右子树特征,左子树标签,右子树标签"""index_left = (x_data[:,dimension] <= value)index_right = (x_data[:,dimension] > value)return x_data[index_left], x_data[index_right], y_label[index_left], y_label[index_right]def create_tree(x_data, y_label):ent, dim, value = one_split(x_data, y_label)x_left, x_right, y_left, y_right = split(x_data, y_label, dim, value)node = Node(x_data, y_label, dim, value)if ent < 0.000000001:return nodenode.left = create_tree(x_left, y_left)node.right = create_tree(x_right, y_right)return nodeself.root = create_tree(x_train, y_train)return selfdef predict(self,x_predict):def travel(x_data, node):p = nodeif x_data[p.dimension] <= p.value and p.left:pred = travel(x_data, p.left)elif x_data[p.dimension] > p.value and p.right:pred = travel(x_data, p.right)else:counter = Counter(p.y_label)pred = counter.most_common(1)[0][0]return predy_predict = []for data in x_predict:y_pred = travel(data, self.root)y_predict.append(y_pred)return np.array(y_predict)def score(self,x_test,y_test):y_predict = self.predict(x_test)return np.sum(y_predict == y_test) / len(y_predict)def __repr__(self):return "DTree(criterion='entropy')"

测试一下我们的决策树

dt = DTree()
dt.fit(x_train, y_train)
dt.score(x_test,y_test)

sklearn的决策树

dt_clf = DecisionTreeClassifier()
dt_clf.fit(x_train, y_train)
dt_clf.score(x_test, y_test)

结果一模一样,完美!

sklearn 决策树例子_决策树DecisionTree(附代码实现)相关推荐

  1. sklearn 决策树例子_决策树--规则挖掘应用

    本次主要简单介绍下决策树在风控规则中的简单应用,让读者快速入门.在后续的文章中,会逐一介绍决策树的各种算法原理,如信息增益.ID3算法.C4.5算法.C5.0算法等, 希望感兴趣的朋友可以关注下. 前 ...

  2. sklearn 决策树例子_机器学习|决策树的生成过程是怎样?(一)

    本文笔者将用具体例子讲述决策树的构建过程,分析:决策树生成过程中有什么样的问题? 一.基本概念 决策树的定义: 首先,决策树是一种有监督的分类算法--即给定X,Y值,构建X,Y的映射关系. 不同于线性 ...

  3. 导入训练好的决策树文件_决策树在sklearn中的实现

    小伙伴们大家好~o( ̄▽ ̄)ブ,今天做一下如何使用sklearn实现决策树,首先声明一下,我的开发环境是Jupyter lab,所用的库和版本大家参考: Python 3.7.1(你的版本至少要3.4 ...

  4. mysql可以做决策树吗_决策树 - stream886 - 博客园

    参考资料 决策树 决策树是一种运用概率与图论中的树对决策中的不同方案进行比较,从而获得最优方案的风险型决策方法. 决策树学习三步骤: 特征选择 决策树的生成 决策树的剪枝 常用的决策树算法有ID3,C ...

  5. sklearn 决策树例子_使用 sklearn 构建决策树并使用 Graphviz 绘制树结构

    决策树最大的优点是我们可以查看最终的树结构,上一篇日志中,我们通过 matplotlib 展示了我们自己的树结构 但是 matplotlib 绘制树结构较为复杂,我们这里来了解一个更为易用的绘图工具  ...

  6. python决策树剪枝_决策树剪枝问题python代码

    决策树在生长过程中有可能长得过于茂盛,对训练集学习的很好,但对新的数据集的预测效果不好,即过拟合,此时生成的模型泛化能力较差.因此,我们需要对决策树进行剪枝,使得生成的模型具有较强的泛化能力. 为了检 ...

  7. python决策树剪枝_决策树剪枝算法的python实现方法详解

    python 决策树怎样修剪枝 剪枝是决策树停止分支的方法之一,剪枝有分预先剪枝和后剪枝两种.预先剪枝是在树的生长过程中设定一个指标,当达到该指标时就停止生长,这样做容易产生"爱已不在,却还 ...

  8. 决策树 结构_决策树模型是什么?5步了解好看模型图

    在复杂的决策情况中,企业完成一个决策后,后面可能面临n种可能状态的发生,而决策树模型是基础的数学定律,它通过已知信息,通过逻辑推理,将问题中的策略,概率,风险,收益用类似于树状的形式呈现.决策出各个可 ...

  9. python决策树预测_决策树案例:基于python的商品购买能力预测系统

    数据分析入门与实战  公众号: weic2c http://www.cnblogs.com/baiboy/p/ml3.html 目录 1 决策树/判定树(decision tree) 2 构造决策树的 ...

最新文章

  1. Redis事务和watch
  2. python3 字符串填充 清除
  3. java 反射 工厂_JAVA反射机制、工厂模式与SPRING IOC
  4. Asp.net 序列化应用实例(转载)
  5. 【数理知识】拉格朗日乘数 Lagrange multipliers
  6. Django web框架-----Django连接本地现有mysql数据库
  7. ffdshow 源代码分析1 : 整体结构
  8. gg修改器偏移量修改_gg修改器偏移量什么意思 | 手游网游页游攻略大全
  9. 简单粗暴卸载Oracle RAC
  10. 【mfc】解决鼠标钩子被占用焦点后不响应的问题
  11. Proteus仿真51单片机
  12. USB Server应于银企直连
  13. RBAC模型整合数据权限
  14. 刽子手c语言,古代神秘职业:刽子手的祖师爷
  15. 计算机上无线网络开关在哪里,联想笔记本无线网络开关,教您联想笔记本无线网络开关在哪...
  16. sourceTree 问题解决
  17. 国外android内存清理工具,给大家推荐一个安卓清理神器哈,确实好用
  18. obj文件转gltf文件
  19. 使用Larave5.6l提交POST请求出现The page has expired due to inactivity错误
  20. UESTC 1635 最大最小生成树

热门文章

  1. python中用turtle绘制时钟_python使用turtle库绘制时钟
  2. 短时傅里叶分析:spectrogram函数
  3. 声明 struct x1 { ...}; 和 typedef struct { ...} x2; 有什么不同?
  4. C/C++中Static的作用详述 在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条。
  5. 23种设计模式C++源码与UML实现--责任链模式
  6. bash-shell高级编程--条件判断
  7. 汇编中数据处理的基本问题
  8. 怎么样尽可能多的学习
  9. 几种存储器的主要应用
  10. 参数匹配顺序——Python学习之参数(三)