ID3和C4.5决策树算法的Python实现
2024.01.29 16:38浏览量:7简介:本文将介绍ID3和C4.5决策树算法的基本原理,并通过Python代码实现这两种算法。代码中包含了详细的注释,帮助读者理解算法的实现过程。
千帆应用开发平台“智能体Pro”全新上线 限时免费体验
面向慢思考场景,支持低代码配置的方式创建“智能体Pro”应用
在数据挖掘和机器学习中,决策树是一种常用的分类和回归方法。ID3和C4.5是两种经典的决策树算法,它们通过递归地将数据集划分成更小的子集来构建决策树。下面我们将分别介绍这两种算法的Python实现。
首先,我们需要导入所需的库:
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
接下来,我们使用Scikit-learn库中的datasets模块加载数据集。这里以鸢尾花数据集为例:
# 加载鸢尾花数据集
iris = datasets.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=42)
现在我们可以开始实现ID3和C4.5算法。
首先,我们来实现ID3算法。ID3算法使用信息增益来选择划分属性。信息增益越大,划分效果越好。在计算信息增益时,我们需要计算每个属性的信息熵。信息熵是数据集中类别分布的不确定性度量。对于一个包含n个样本的数据集,如果其中有m个属于某一类别,则该数据集的信息熵为:E = -m/n log2(m/n)。如果数据集中的样本都属于同一类别,则信息熵为0。
下面是一个简单的ID3算法实现:
```python
def calc_entropy(y):
计算信息熵
unique_labels = np.unique(y)
probs = [y.tolist().count(label) / len(y) for label in unique_labels]
entropy = -sum([p * np.log2(p) for p in probs])
return entropy
def split_data(X, y, axis, value):
划分数据集
ret_X = []
ret_y = []
for ind in range(len(X)):
if X[ind][axis] == value:
ret_X.append(X[ind])
ret_y.append(y[ind])
return np.array(ret_X), np.array(ret_y)
def choose_best_feature_to_split(X, y):
num_features = len(X[0]) - 1 # 除了目标变量的特征数量
base_entropy = calc_entropy(y) # 基础熵(所有样本都属于同一类别时的熵)
best_feature = -1 # 最佳划分属性索引
max_info_gain = 0 # 最大信息增益
for i in range(num_features): # 遍历所有特征
feat_list = [example[i] for example in X] # 获取第i个特征的所有值列表
unique_vals = set(feat_list) # 获取第i个特征的所有唯一值集合
new_entropy = 0 # 当前特征的信息增益为0时的熵(所有样本都属于同一类别时的熵)
for value in unique_vals: # 遍历第i个特征的所有唯一值
sub_X, sub_y = split_data(X, y, i, value) # 根据第i个特征的值将数据集划分为子集
if len(sub_X) == 0: # 如果子集为空,则跳过该唯一值,继续下一个唯一值处理。这是为了防止出现空子集导致错误。
continue
new_entropy += len(sub_X) / len(X) * calc_entropy(sub_y) # 计算当前唯一值对应的子集熵的加权平均值,加权系数为子集中的样本数占总样本数的比例。这是为了处理不均衡的数据集。如果某一类的样本数量特别少,那么这个类的信息熵会被低估,从而导致错误的划分。通过加权平均可以修正这个问题。当子集中所有样本都属于同一类别时,

发表评论
登录后可评论,请前往 登录 或 注册