博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【机器学习】决策树01
阅读量:4982 次
发布时间:2019-06-12

本文共 4791 字,大约阅读时间需要 15 分钟。

什么是决策树 - 从一个实际生活的例子入手

如何判断一个人是否胜任机器学习算法工程师?

解决一个实际问题的决策树

这里的决策树的每一个节点的判断都是一个是否问题

使用scikit-learn库实现的决策树

import numpy as npimport matplotlib.pyplot as pltfrom sklearn import datasetsiris = datasets.load_iris()X = iris.data[:, 2:]y = iris.targetplt.scatter(X[y==0, 0], X[y==0,1])plt.scatter(X[y==1, 0], X[y==1,1])plt.scatter(X[y==2, 0], X[y==2,1])plt.show()from sklearn.tree import DecisionTreeClassifier# max_depth表示决策树的最大深度# criterion表示决策树节点分支的标准,entropy表示利用信息熵作为判断的标准dt_clf = DecisionTreeClassifier(max_depth=2, criterion="entropy")dt_clf.fit(X, y)def plot_decision_boundary(model, axis):    x0,x1=np.meshgrid(        np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(1,-1),        np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(1,-1)    )    X_new=np.c_[x0. ravel(),x1. ravel()]        y_predict=model.predict(X_new)    zz=y_predict. reshape(x0. shape)    from matplotlib. colors import ListedColormap    custom_cmap=ListedColormap(['#EF9A9A','#FFE59D','#90CAF9'])                                   plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)plot_decision_boundary(dt_clf, axis=[0.5, 7.5, 0, 3])plt.scatter(X[y==0, 0], X[y==0,1])plt.scatter(X[y==1, 0], X[y==1,1])plt.scatter(X[y==2, 0], X[y==2,1])plt.show()

数据展示如下:

原始数据

决策树分类的决策边界

对上述这个决策树分类的解释

决策树分类的一个直观解释

决策树的一些特征

  • 非参数学习算法
  • 可以解决分类问题,尤其是天然支持多分类问题
  • 也可以解决回归问题
  • 具有良好的可解释性

决策树的划分依据

决策树的核心问题是:

  1. 每个节点在哪个维度做划分
  2. 每个维度在哪个值上做划分

信息熵

信息熵表示数据的不确定性

嫡越大,数据的不确定性越高

嫡越小,数据的不确定性越低

信息熵的计算公式:

$

H=-\sum_{i=1}^{k} p_{i} \log \left(p_{i}\right)
$

\(p_{i}\)表示每种可能的取值的概率

对于一个二分类问题,信息熵公式可以表示为

$

H=-x \log (x)-(1-x) \log (1-x)
$

其中,\(x\)表示一个“1”类别的概率

使用信息熵的决策树的划分思想

使用信息熵的决策树的划分思想是划分之后使得信息熵降低

使用遍历的方法,对每个维度的每个阈值都进行信息熵运算,找到最佳划分

使用信息熵寻找最优划分

模拟使用信息熵进行划分

import numpy as npimport matplotlib.pyplot as pltfrom sklearn import datasetsiris = datasets.load_iris()X = iris.data[:, 2:]y = iris.targetdef split(X, y, d, value):    index_a = (X[:, d] <= value)    index_b = (X[:, d] > value)    return X[index_a], X[index_b], y[index_a], y[index_b]from collections import Counterfrom math import logdef entropy(y):    counter = Counter(y)    res = 0.0    for num in counter.values():        p = num / len(y)        res += -p * log(p)    return resdef try_split(X, y):    best_entropy = float('inf')    best_d, best_v = -1, -1    for d in range(X.shape[1]):  # 遍历每一个特征值,找到最佳划分所在的维度        sorted_index = np.argsort(X[:, d])  # 对所有样本按照一个维度的值进行排序        for i in range(1, len(X)):  # 遍历每一个相邻样本对,尝试在这里进行划分            if X[sorted_index[i - 1], d] != X[sorted_index[i], d]:                v = (X[sorted_index[i - 1], d] + X[sorted_index[i], d]) / 2  # v表示相邻样本对的该维度特征值的平均值                X_l, X_r, y_l, y_r = split(X, y, d, v)  # 使用该平均值对样本进行分割                e = entropy(y_l) + entropy(y_r)  # 对y(分类值0,1,2)分别计算信息熵                if e < best_entropy:                    best_entropy = e                    best_d = d                    best_v = v    return best_entropy, best_d, best_vbest_entropy, best_d, best_v = try_split(X, y)print("best_entropy=", best_entropy)  # best_entropy= 0.6931471805599453print("best_d=", best_d)  # best_d= 0print("best_v=", best_v)  # best_v= 2.45

通过上述代码就模拟了第一次进行划分的过程,可以看到,与之前调用sklearn库的结果相近。

基尼系数

$

G=1-\sum_{i=1}^{k} p_{i}^{2}
$

基尼系数(英语:Gini coefficient),是20世纪初意大利学者科拉多·基尼(另一说赫希曼)根据劳伦茨曲线所定义的判断年收入分配公平程度的指标,是比例数值,在0和1之间。在民众收入中,基尼系数最大为“1”,最小为“0”。前者表示居民之间的年收入分配绝对不平均(即该年所有收入都集中在一个人手里,其余的国民没有收入),而后者则表示居民之间的该年收入分配绝对平均,即人与人之间收入绝对平等。

使用scikit-learn库中提供的决策树

from sklearn.tree import DecisionTreeClassifierimport numpy as npimport matplotlib.pyplot as pltfrom sklearn import datasetsiris = datasets.load_iris()X = iris.data[:, 2:]y = iris.targetplt.scatter(X[y == 0, 0], X[y == 0, 1])plt.scatter(X[y == 1, 0], X[y == 1, 1])plt.scatter(X[y == 2, 0], X[y == 2, 1])plt.show()# max_depth表示决策树的最大深度;# criterion表示决策树节点分支的标准,gini表示使用基尼系数dt_clf = DecisionTreeClassifier(max_depth=2, criterion="gini")dt_clf.fit(X, y)def plot_decision_boundary(model, axis):    x0, x1 = np.meshgrid(        np.linspace(axis[0], axis[1], int(            (axis[1] - axis[0]) * 100)).reshape(1, -1),        np.linspace(axis[2], axis[3], int(            (axis[3] - axis[2]) * 100)).reshape(1, -1))    X_new = np.c_[x0.ravel(), x1.ravel()]    y_predict = model.predict(X_new)    zz = y_predict.reshape(x0.shape)    from matplotlib.colors import ListedColormap    custom_cmap = ListedColormap(['#EF9A9A', '#FFE59D', '#90CAF9'])    plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)plot_decision_boundary(dt_clf, axis=[0.5, 7.5, 0, 3])plt.scatter(X[y == 0, 0], X[y == 0, 1])plt.scatter(X[y == 1, 0], X[y == 1, 1])plt.scatter(X[y == 2, 0], X[y == 2, 1])plt.show()

使用基尼系数训练的决策树的决策边界

信息熵 vs. 基尼系数

信息熵的计算比基尼系数稍慢

scikit-learn中默认为基尼系数

大多数时候两者没有特别的效果优劣

CART(Classification And Regression Tree)

根据某一个维度d和某一阈值v进行二分

scikit-learn中的决策树实现:CART

其他的决策树:ID3, C4.5, C5.0

转载于:https://www.cnblogs.com/yux1a0/p/10781176.html

你可能感兴趣的文章
Spring Controller RequestMapping
查看>>
socket
查看>>
小程序 跳转问题 (来源见注明)
查看>>
JBPM4入门——9.自动节点单线执行
查看>>
//停止关联的进程
查看>>
SQL 生成公曆和農曆對照數據,公曆查找農曆和農曆查找公曆函數
查看>>
为何场效应管要用UGD与UGS(off)来比较判断夹断情况?
查看>>
.pem证书转xml格式字符串(.net)
查看>>
js构建ui的统一异常处理方案(二)
查看>>
三线程连续打印ABC
查看>>
ECharts
查看>>
初识网络爬虫
查看>>
git push 时不用每次都输入密码的方法
查看>>
54点提高PHP编程效率 引入缓存机制提升性能
查看>>
编解码-marshalling
查看>>
CDN原理
查看>>
java.lang.outofmemoryerror android
查看>>
coding
查看>>
省市联级(DataReader绑定)
查看>>
20165219 课上内容补做
查看>>