机器学习实现决策树Decision Tree

第一部分:决策树核心思想和原理

分而治之,逐个击破,民主决策思想

决策树是一种常用的分类和回归模型,主要通过构建一棵树状结构来实现数据的分类或回归。

决策树是一种监督学习算法

可以用于实现分类也可以回归

决策树的深度:也就是决策树的层数

决策树需要研究的三个基本问题:

①特征选择(谁作为根节点呢)

②节点分裂(应该作为二分类还是多分类呢)

③阈值确定(判断标准的这个范围取值,大于小于多少分为yes或者no)

决策树属于一个“白盒”模型,可解释性很强,不像神经网络一样,神经网络是一个“黑盒模型”

第二部分:信息熵

详细讲解内容见我博客:

机器学习之损失函数大汇总~MSE+MAE+对数损失函数+交叉熵损失函数-CSDN博客

第三部分:决策树二分类问题代码实现

(1)第一部分:导包

#第一部分:导包
import numpy as np
import matplotlib.pyplot as plt

(2)第二部分:创建二分类问题熵变化图像

#第二部分:创建二分类问题熵变化图像
def entropy(p):
    return -(p*np.log2(p)+(1-p)*np.log2(1-p))
plot_x = np.linspace(0.001,0.999,200)
plt.plot(plot_x, entropy(plot_x))
plt.show()#绘制出熵的变化情况

(3)第三部分:创建数据集并绘制所有样本点

#第三部分:创建数据集并绘制所有样本点
from sklearn.datasets import load_iris
iris = load_iris()
x=iris.data[:,1:3]#我们只用第一列和第二列的数据即可
y=iris.target
plt.scatter(x[:,0],x[:,1],c=y)#横轴为第一列,纵轴为第二列
plt.show()

(4)第四部分:sklearn中的决策树

#第四部分:sklearn中的决策树
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier(max_depth=2, criterion='entropy')  # 设置树的深度为2层,并设置按照熵进行划分标准
clf.fit(x, y)

(5)第五部分:使用决策边界来绘制样本点分类散布情况

#第五部分:使用决策边界来绘制样本点分类散布情况
def decision_boundary_plot(X, y, clf):
    axis_x1_min, axis_x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    axis_x2_min, axis_x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    x1, x2 = np.meshgrid(np.arange(axis_x1_min, axis_x1_max, 0.01),
                         np.arange(axis_x2_min, axis_x2_max, 0.01))
    z = clf.predict(np.c_[x1.ravel(), x2.ravel()])
    z = z.reshape(x1.shape)
    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#F5B9EF', '#BBFFBB', '#F9F9CB'])
    plt.contourf(x1, x2, z, cmap=custom_cmap)
    plt.scatter(X[:, 0], X[:, 1], c=y)
    plt.show()
decision_boundary_plot(x,y,clf)

(6)第六部分:可视化分类结构图

#第六部分:可视化分类结构图
from sklearn.tree import plot_tree
import matplotlib.pyplot as plt
# 绘制决策树
plt.figure(figsize=(10, 6))  # 设置图像大小
plot_tree(clf, filled=True)  # `filled=True` 会为不同的类别填充颜色
plt.show()

(7)完整pycharm代码实现

#第一部分:导包
import numpy as np
import matplotlib.pyplot as plt
#第二部分:创建二分类问题熵变化图像
def entropy(p):
    return -(p*np.log2(p)+(1-p)*np.log2(1-p))
plot_x = np.linspace(0.001,0.999,200)
plt.plot(plot_x, entropy(plot_x))
plt.show()#绘制出熵的变化情况
#第三部分:创建数据集并绘制所有样本点
from sklearn.datasets import load_iris
iris = load_iris()
x=iris.data[:,1:3]#我们只用第一列和第二列的数据即可
y=iris.target
plt.scatter(x[:,0],x[:,1],c=y)#横轴为第一列,纵轴为第二列
plt.show()
#第四部分:sklearn中的决策树
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier(max_depth=2, criterion='entropy')  # 设置树的深度为2层,并设置按照熵进行划分标准
clf.fit(x, y)
#第五部分:使用决策边界来绘制样本点分类散布情况
def decision_boundary_plot(X, y, clf):
    axis_x1_min, axis_x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    axis_x2_min, axis_x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    x1, x2 = np.meshgrid(np.arange(axis_x1_min, axis_x1_max, 0.01),
                         np.arange(axis_x2_min, axis_x2_max, 0.01))
    z = clf.predict(np.c_[x1.ravel(), x2.ravel()])
    z = z.reshape(x1.shape)
    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#F5B9EF', '#BBFFBB', '#F9F9CB'])
    plt.contourf(x1, x2, z, cmap=custom_cmap)
    plt.scatter(X[:, 0], X[:, 1], c=y)
    plt.show()
decision_boundary_plot(x,y,clf)
#第六部分:可视化分类结构图
from sklearn.tree import plot_tree
import matplotlib.pyplot as plt
# 绘制决策树
plt.figure(figsize=(10, 6))  # 设置图像大小
plot_tree(clf, filled=True)  # `filled=True` 会为不同的类别填充颜色
plt.show()

(8)对第六部分详细阐述七内部原理

①计算熵的函数

from collections import Counter
import numpy as np
# 计算熵的函数
def calc_entropy(y):
    counter = Counter(y)  # 统计每个类别的数量
    sum_ent = 0
    for i in counter:
        p = counter[i] / len(y)
        sum_ent += -(p * np.log2(p))
    return sum_ent

②划分数据集的函数

# 划分数据集的函数,dim 代表维度,value 代表划分阈值
def split_dataset(x, y, dim, value):
    index_left = (x[:, dim] <= value)
    index_right = (x[:, dim] > value)
    return x[index_left], y[index_left], x[index_right], y[index_right]

③寻找最优划分条件的函数

# 寻找最优划分条件的函数
def find_best_split(x, y):
    best_dim = -1
    best_value = -1
    best_entropy = np.inf
    best_entropy_left, best_entropy_right = -1, -1
    for dim in range(x.shape[1]):
        sorted_index = np.argsort(x[:, dim])
        for i in range(x.shape[0] - 1):
            value_left, value_right = x[sorted_index[i], dim], x[sorted_index[i + 1], dim]
            if value_left != value_right:
                value = (value_left + value_right) / 2  # 候选阈值
                x_left, y_left, x_right, y_right = split_dataset(x, y, dim, value)
                entropy_left, entropy_right = calc_entropy(y_left), calc_entropy(y_right)
                entropy = (len(x_left) * entropy_left + len(x_right) * entropy_right) / x.shape[0]
                if entropy < best_entropy:
                    best_dim = dim
                    best_value = value
                    best_entropy = entropy
                    best_entropy_left, best_entropy_right = entropy_left, entropy_right
    return best_dim, best_value, best_entropy, best_entropy_left, best_entropy_right
print(find_best_split(x,y))

④完整pycharm汇总

#第一部分:导包
import numpy as np
import matplotlib.pyplot as plt
#第二部分:创建二分类问题熵变化图像
def entropy(p):
    return -(p*np.log2(p)+(1-p)*np.log2(1-p))
plot_x = np.linspace(0.001,0.999,200)
plt.plot(plot_x, entropy(plot_x))
plt.show()#绘制出熵的变化情况
#第三部分:创建数据集并绘制所有样本点
from sklearn.datasets import load_iris
iris = load_iris()
x=iris.data[:,1:3]#我们只用第一列和第二列的数据即可
y=iris.target
plt.scatter(x[:,0],x[:,1],c=y)#横轴为第一列,纵轴为第二列
plt.show()
#第四部分:sklearn中的决策树
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier(max_depth=2, criterion='entropy')  # 设置树的深度为2层,并设置按照熵进行划分标准
clf.fit(x, y)
#第五部分:使用决策边界来绘制样本点分类散布情况
def decision_boundary_plot(X, y, clf):
    axis_x1_min, axis_x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    axis_x2_min, axis_x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    x1, x2 = np.meshgrid(np.arange(axis_x1_min, axis_x1_max, 0.01),
                         np.arange(axis_x2_min, axis_x2_max, 0.01))
    z = clf.predict(np.c_[x1.ravel(), x2.ravel()])
    z = z.reshape(x1.shape)
    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#F5B9EF', '#BBFFBB', '#F9F9CB'])
    plt.contourf(x1, x2, z, cmap=custom_cmap)
    plt.scatter(X[:, 0], X[:, 1], c=y)
    plt.show()
decision_boundary_plot(x,y,clf)
#第六部分:可视化分类结构图
from sklearn.tree import plot_tree
import matplotlib.pyplot as plt
# 绘制决策树
plt.figure(figsize=(10, 6))  # 设置图像大小
plot_tree(clf, filled=True)  # `filled=True` 会为不同的类别填充颜色
plt.show()

from collections import Counter
import numpy as np
# 计算熵的函数
def calc_entropy(y):
    counter = Counter(y)  # 统计每个类别的数量
    sum_ent = 0
    for i in counter:
        p = counter[i] / len(y)
        sum_ent += -(p * np.log2(p))
    return sum_ent

# 划分数据集的函数,dim 代表维度,value 代表划分阈值
def split_dataset(x, y, dim, value):
    index_left = (x[:, dim] <= value)
    index_right = (x[:, dim] > value)
    return x[index_left], y[index_left], x[index_right], y[index_right]

# 寻找最优划分条件的函数
def find_best_split(x, y):
    best_dim = -1
    best_value = -1
    best_entropy = np.inf
    best_entropy_left, best_entropy_right = -1, -1
    for dim in range(x.shape[1]):
        sorted_index = np.argsort(x[:, dim])
        for i in range(x.shape[0] - 1):
            value_left, value_right = x[sorted_index[i], dim], x[sorted_index[i + 1], dim]
            if value_left != value_right:
                value = (value_left + value_right) / 2  # 候选阈值
                x_left, y_left, x_right, y_right = split_dataset(x, y, dim, value)
                entropy_left, entropy_right = calc_entropy(y_left), calc_entropy(y_right)
                entropy = (len(x_left) * entropy_left + len(x_right) * entropy_right) / x.shape[0]
                if entropy < best_entropy:
                    best_dim = dim
                    best_value = value
                    best_entropy = entropy
                    best_entropy_left, best_entropy_right = entropy_left, entropy_right
    return best_dim, best_value, best_entropy, best_entropy_left, best_entropy_right
print(find_best_split(x,y))

我们这个的结果代表的是第一层的左右划分结果:

1代表第一列的分类标准是2.45为界限

0.0是分割的左边的熵值,1.0是右边的熵值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

还不秃顶的计科生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值