一、认识决策树
1.1决策树的概念
决策树是一种机器学习中常用的预测模型,它模拟了人类决策过程的一种方法。它通过使用树状结构来表示一系列的决策规则,以及在每个决策节点上对输入数据进行分支的方式。
在决策树中,每个内部节点代表一个特征或属性,用于对输入数据进行划分。而每个叶子节点代表一个输出结果或者决策。从根节点开始,根据输入数据的特征值逐步向下遍历,直到达到叶子节点,得到最终的决策结果。
1.2决策树的优缺点
优点:
- 简单直观:决策树模型易于理解和解释,可以提供可视化的决策过程,使得非专业人士也能够理解和使用。
- 适应性强:决策树能够处理离散型和连续型特征,以及处理缺失数据。它可以自动选择重要的特征,并且对于特征的缩放不敏感。
- 高效性:在构建决策树时,由于节点划分的简单计算,决策树的训练速度相对较快。
- 可解释性强:通过决策树的路径,我们可以清晰地了解到每一步的决策过程,因此决策树模型的结果更容易被人理解和接受。
缺点:
- 容易过拟合:决策树倾向于将训练数据中的噪声和异常值也纳入考虑,导致模型过于复杂,出现过拟合现象。这可以通过剪枝等正则化技术进行改善。
- 不稳定性:对于数据的细微变化,决策树可能产生较大的变化。这是因为决策树模型的划分依赖于特征选择指标,不同指标可能导致不同的决策树结构。
- 忽略特征间的相关性:决策树模型在划分数据时,仅考虑单个特征的信息,忽略了特征间可能存在的相关性。这对于某些问题可能会导致不准确的预测结果。
- 局部最优解:决策树使用贪心算法进行树的构建,可能导致得到的决策树是局部最优解,而非全局最优解。
二、构建决策树
2.1决策树构建的一般流程
- 特征选择:选择对数据进行划分的最佳特征,常用的特征选择指标有信息增益、基尼指数等。
- 树的构建:根据选择的特征,在当前节点上创建一个新的决策节点,并将数据集划分为不同的子集。
- 递归构建:对每个子集递归地执行上述步骤,直到满足终止条件(如数据集为空或者已经不存在可划分的特征)。
- 剪枝:为了避免过拟合,可以对生成的决策树进行剪枝操作,去掉一些决策节点或子树。
2.2信息增益
信息增益是决策树中常用的特征选择指标,用于衡量在某个特征划分下对数据集的纯度提升程度。在构建决策树时,选择最大信息增益的特征作为划分依据,可以使得每次划分后的数据子集更加纯净,从而提高模型的预测准确性。
在信息论中,熵(Entropy)是表示随机变量不确定性的度量。对于一个二分类问题,假设有两个类别,正例和负例,那么熵的计算公式为:
其中,p1 和 p2 分别表示正例和负例在数据集 D 中的比例。
在特征 A 的条件下,将数据集 D 划分为 k 个子集 �1,�2,...,��D1,D2,...,Dk。使用条件熵(Conditional Entropy)来度量特征 A 对数据集 D 的信息增益,计算公式为:
其中,∣Di∣ 表示子集 Di 的样本个数。
信息增益(Information Gain)定义为原始数据集熵 H(D) 与特征 A 条件下的条件熵 H(D|A) 之差,公式为:
信息增益越大,表示在特征 A 的条件下,数据集 D 的不确定性减少得越多,即特征 A 对于分类任务的贡献越大。因此,在特征选择时,选择具有最大信息增益的特征作为划分依据,可以使得决策树的每个节点更加纯净,并提高模型的预测准确性。
2.3基尼值和基尼指数
基尼值(Gini impurity)是衡量数据集纯度的指标,主要用于决策树中的特征选择。基尼值表示从数据集中随机选择两个样本,它们所属类别不一致的概率。在二分类问题中,基尼值的计算公式为:
其中,p 表示正例在数据集中的比例,即 p=∣D∣/∣D+∣,∣D+∣ 表示正例的样本个数,∣D∣ 表示数据集的总样本个数。
对于多分类问题,基尼值的计算为:
其中,pi 表示第 i 类样本在数据集中的比例。
基尼值越小,表示数据集的纯度越高,即样本越倾向于属于同一类别。在决策树的特征选择中,我们希望选择能够最大程度减少基尼值的特征进行划分。
基尼指数(Gini index)是基于基尼值的特征选择指标。对于某个特征 A,假设它有 k 个取值,将数据集 D 按照特征 A 划分为 k 个子集 D1,D2,...,Dk,每个子集对应于特征 A 的一个取值。基尼指数的计算公式为:
其中,∣Di∣ 表示子集 Di 的样本个数,pij 表示子集 Di 中第 j 类样本的比例。
选择基尼指数最小的特征作为划分依据,可以使得决策树的每个节点都能够尽量减少基尼值,提高数据集的纯度和模型的准确性。
三、生成决策树
1、计算给定标签的熵
def calc_entropy(y):
classes, counts = np.unique(y, return_counts=True)
probabilities = counts / len(y)
entropy = -np.sum(probabilities * np.log2(probabilities))
return entropy
2、 找到最佳划分特征
def find_best_feature(X, y):
num_features = X.shape[1]
best_feature = None
best_info_gain = 0
for feature_idx in range(num_features):
info_gain = calc_information_gain(X, y, feature_idx)
if info_gain > best_info_gain:
best_info_gain = info_gain
best_feature = feature_idx
return best_feature
3、创建决策树
def create_decision_tree(X, y):
if len(np.unique(y)) == 1:
return DecisionNode(label=y[0])
if X.shape[1] == 0:
return DecisionNode(label=np.argmax(np.bincount(y)))
best_feature = find_best_feature(X, y)
tree = DecisionNode(feature=best_feature)
feature_values = np.unique(X[:, best_feature]) for value in feature_values:
subset_indices = np.where(X[:, best_feature] == value)
subset_X = X[subset_indices]
subset_y = y[subset_indices]
tree.children.append((value, create_decision_tree(subset_X, subset_y)))
return tree
4、示例数据
X = np.array([ [1, 0], [1, 1], [0, 1], [0, 0] ]) y = np.array([1, 1, 0, 0])
5、创建决策树
tree = create_decision_tree(X, y) print(tree)