机器学习之基尼系数(描述数据纯度)(能够实现与信息熵相同的效果)

第一部分:基尼系数的基础知识

第二部分:探究二分类问题下“信息熵”和“基尼系数”之间的关系

(1)代码实现信息熵和基尼系数图像变化走势

#第一部分:导包
import numpy as np
import matplotlib.pyplot as plt
#第二部分:创建二分类问题熵变化图像
def entropy(p):
    return -(p*np.log2(p)+(1-p)*np.log2(1-p))#二分类问题下就这两种情况
#第三部分:创建二分类问题基尼系数变化图像
def gini(p):
    return 1-p**2-(1-p)**2
plot_x = np.linspace(0.001,0.999,200)
plt.plot(plot_x, entropy(plot_x),color='blue')#画出熵变化图像
plt.plot(plot_x, gini(plot_x),color='red')#画出基尼系数变化图像
plt.show()#绘制出熵的变化情况

①它们两个都是在p=0.5的时候,他们的值是最高的,这个时候基尼系数可以起到与信息熵相同的作用

②相比于信息熵,基尼系数的计算会快一些,因为信息后熵里面的对数运算比基尼系数中的平方运算要稍微复杂一些。

③它们的物理意义略有不同,信息熵表示随机变量的不确定度,而基尼系数表示在样本集合中,一个随机选中的样本,它被分错的概率,也就是纯度

(2)使用基尼系数实现决策树二分类问题

首先我们可以先借鉴一下之前使用信息熵实现决策树二分类问题,见我博客:机器学习实现决策树Decision Tree-CSDN博客

我们只需要在原先的基础上,将entropy改成gini就可以了:

注:如果不指定的话,默认也是gini划分的

完整代码:

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

#第二部分:创建二分类问题基尼系数变化图像
def gini(p):
    return 1-p**2-(1-p)**2
plot_x = np.linspace(0.001,0.999,200)
plt.plot(plot_x, gini(plot_x),color='red')#画出基尼系数变化图像
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 = DecisionTreeClassifier(max_depth=2, criterion='gini')  # 设置树的深度为2层,并设置按照gini进行划分标准
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))

这个里面也从entropy变成了gini.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

还不秃顶的计科生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值