0


了解大数据中的决策树

前言

决策树(Decision Tree)是一种类似于流程图的树形结构,每个内部节点表示在一个属性上的测试,每个分支代表一个属性输出,而每个叶节点代表类或类分布。决策树通过树状结构,基于数据特征与目标变量之间的关系,将数据集划分为不同的子集,以逐步构建决策规则。其工作原理是从根节点开始,根据输入特征的取值,沿着相应的分支向下移动,直到到达一个叶节点,叶节点的值即为最终分类或预测结果,递归地选择最优特征进行分裂,构建出完整的决策树。

一、决策树原理及构建

原理

决策树的概念来源于统计学和决策论,能够直观地模拟人类的决策过程。它通过递归地将数据集划分为多个子集,形成树状结构,以表示数据的分布和分类规则。每个内部节点代表一个特征的决策,每个叶子节点则是决策结果(分类或回归值)。决策树的构建主要基于“信息增益”(Information Gain)或“基尼不纯度”(Gini Impurity)等指标。其核心思想是逐步选择最佳的特征来划分数据集,从而构建出能够最好地分类或回归的树。

信息增益:表示某个特征对分类结果的不确定性的减少量。信息增益越大,表示该特征越能有效减少不确定性,从而更好地划分数据。

基尼不纯度:用于衡量一个数据集在某特征下的不纯度。基尼不纯度越低,数据集越“纯”。

构建步骤

决策树的构建过程是一个递归选择最优特征,并根据特征的不同取值对数据进行划分的过程,直到满足停止条件为止。以下是构建步骤:

①准备数据:将数据集划分成训练集和测试集,进行缺失值处理和特征选择。

②选择最优特征:对于数据集中的每个特征,计算其对数据集的信息增益或基尼不纯度,选择信息增益最大或基尼不纯度最小的特征作为本次分类的特征。

③划分数据集:根据选择的特征,将数据集划分成若干子集,每个子集包含特征一致的一部分数据。

④递归构建决策树:对于每个子集,重复上述选择最优特征和划分数据集的过程,直到子集中的数据属于同一类别或者到达一定的停止条件为止。常见的停止条件包括:所有样本属于同一类别、特征集为空、或者样本数量小于预设的阈值。

⑤测试模型:将测试集中的数据输入到构建好的模型中,计算模型的分类准确度和召回率等评估指标。

⑥优化模型:对于分类错误的样本,可以通过调整参数(如决策树的最大深度、最小样本数等)和增加样本来优化模型。此外,为了防止决策树过拟合,还可以进行剪枝操作,即去除不必要的分支,保留重要的决策节点,从而提高模型的泛化能力。

二、决策树的典型算法

ID3算法

概念:ID3(Iterative Dichotomiser 3)算法是决策树学习算法的一种经典方法,它根据信息增益来选择每个节点的分裂属性。

  • 步骤选择最佳特征:构建根节点,将所有训练数据都放在根节点,根据信息增益选择最能区分数据的特征作为当前节点的分割标准。
  • 数据分割:使用选定的最佳分裂属性将当前节点的数据集划分成多个子集,每个子集对应于分裂属性的不同取值。
  • 递归构建树:对于每个子集,递归地应用上述步骤,直到达到停止条件。停止条件可以是节点中样本的类别完全相同,或者节点中的样本数小于某个阈值。
  • 生成树:重复上述步骤,直到所有叶子节点都是纯的(即只包含同一类别的样本)或者达到停止条件。
  • 优点:简单易懂,生成的决策树易于解释。
  • 缺点:对缺失值敏感,不能处理连续型属性,容易过拟合。

C4.5算法

  • 概念:C4.5是ID3的改进版本,引入了能够处理连续属性和缺失值的机制,以及剪枝操作,能够更好地应对实际问题。
  • 改进:1. 处理连续属性:通过将连续属性离散化,C4.5能够处理连续属性。2. 处理缺失值:C4.5提供了处理缺失值的方法,使得算法在存在缺失值的情况下也能正常工作。3. 剪枝操作:C4.5引入了剪枝操作,通过剪除不必要的分支,提高了决策树的泛化能力。
  • 应用:C4.5算法既适合于分类问题,又适合于回归问题。

CART算法

  • 概念:CART(Classification and Regression Trees)算法是一种广泛使用的决策树算法,它可以用于分类问题和回归问题。
  • 特点:1. 二叉树结构:CART算法生成的决策树是二叉树,即每个节点最多有两个子节点。2. 基尼系数:CART算法使用基尼系数来衡量数据集的不纯度,并选择能够最大程度减少不纯度的特征作为分裂属性。3. 剪枝操作:CART算法也包含了剪枝操作,以提高决策树的泛化能力。
  • 应用:CART算法在分类和回归问题中都有广泛的应用。

ID3、C4.5和CART是决策树的典型算法,它们各有特点,适用于不同的应用场景。在实际应用中,可以根据具体问题的需求和数据的特性选择合适的算法。

三.决策树的算法实现示例

ID3算法代码示例

  1. import numpy as np
  2. from collections import Counter
  3. class DecisionTree:
  4. class Node:
  5. def __init__(self):
  6. self.value = None # 内部叶节点属性
  7. self.feature_index = None
  8. self.children = {}
  9. def __str__(self):
  10. if self.children:
  11. s = '内部节点<%s>:\n' % self.feature_index
  12. for fv, node in self.children.items():
  13. ss = '[%s]-> %s' % (fv, node)
  14. s += '\t' + ss.replace('\n', '\n\t') + '\n'
  15. s = s[:-1]
  16. else:
  17. s = '叶节点(%s)' % self.value
  18. return s
  19. def __init__(self, gain_threshold=1e-2): # 信息增益阈值
  20. self.gain_threshold = gain_threshold
  21. def _entropy(self, y): # 熵: -sum(pi*log(pi))
  22. c = np.bincount(y)
  23. p = c[np.nonzero(c)] / y.size
  24. return -np.sum(p * np.log2(p))
  25. def _conditional_entropy(self, feature, y): # 条件熵
  26. feature_values = np.unique(feature)
  27. h = 0.
  28. for v in feature_values:
  29. y_sub = y[feature == v]
  30. p = y_sub.size / y.size
  31. h += p * self._entropy(y_sub)
  32. return h
  33. def _information_gain(self, feature, y): # 信息增益 = 经验熵 - 经验条件熵
  34. return self._entropy(y) - self._conditional_entropy(feature, y)
  35. def _select_feature(self, X, y, features_list): # 选择信息增益最大特征
  36. if features_list:
  37. gains = np.apply_along_axis(self._information_gain, 0, X[:, features_list], y)
  38. index = np.argmax(gains)
  39. if gains[index] > self.gain_threshold:
  40. return index
  41. return None
  42. def _create_tree(self, X, y, features_list): # 创建节点
  43. node = DecisionTree.Node()
  44. labels_count = np.bincount(y)
  45. node.value = np.argmax(labels_count) # 节点值总等于数据集中样本最多的类标记
  46. if np.count_nonzero(labels_count) != 1: # 判断类标记是否全部一致
  47. index = self._select_feature(X, y, features_list)
  48. if index is not None:
  49. node.feature_index = features_list.pop(index)
  50. feature_values = np.unique(X[:, node.feature_index])
  51. for v in feature_values:
  52. idx = X[:, node.feature_index] == v
  53. X_sub, y_sub = X[idx], y[idx]
  54. node.children[v] = self._create_tree(X_sub, y_sub, features_list.copy())
  55. return node
  56. def train(self, X_train, y_train): # 训练决策树
  57. _, n = X_train.shape
  58. self.tree_ = self._create_tree(X_train, y_train, list(range(n)))
  59. def predict(self, X_test): # 对每一个测试样本, 调用_predict_one, 将收集到的结果数组返回
  60. return np.apply_along_axis(self._predict_one, axis=1, arr=X_test)
  61. def _predict_one(self, x_test): # 搜索决策树, 对单个样本进行预测
  62. node = self.tree_
  63. while node.children:
  64. child = node.children.get(x_test[node.feature_index])
  65. if not child:
  66. break
  67. node = child
  68. return node.value
  69. def __str__(self):
  70. if hasattr(self, 'tree_'):
  71. return str(self.tree_)
  72. return ''
  73. # 使用示例数据集进行分类
  74. # 数据集加载和数据预处理部分略...
  75. # 假设X_train和y_train是已经准备好的训练数据集
  76. # 假设X_test是待预测的测试数据集
  77. tree = DecisionTree()
  78. tree.train(X_train, y_train)
  79. predictions = tree.predict(X_test)
  80. print(predictions)

C4.5算法代码示例

  1. import numpy as np
  2. from collections import Counter
  3. def calc_entropy(labels):
  4. counter = Counter(labels)
  5. probs = [counter[c] / len(labels) for c in counter]
  6. entropy = -np.sum(probs * np.log2(probs))
  7. return entropy
  8. def calc_info_gain(data, labels, feature_idx):
  9. feature_values = set(data[:, feature_idx])
  10. entropy_before = calc_entropy(labels)
  11. gain = entropy_before
  12. for value in feature_values:
  13. subset = data[data[:, feature_idx] == value]
  14. subset_labels = labels[data[:, feature_idx] == value]
  15. weight = len(subset_labels) / len(labels)
  16. gain -= weight * calc_entropy(subset_labels)
  17. return gain
  18. def choose_best_feature(data, labels):
  19. num_features = data.shape[1]
  20. best_feature = None
  21. best_gain = 0
  22. for i in range(num_features):
  23. info_gain = calc_info_gain(data, labels, i)
  24. if info_gain > best_gain:
  25. best_gain = info_gain
  26. best_feature = i
  27. return best_feature
  28. def create_decision_tree(data, labels):
  29. if len(set(labels)) == 1:
  30. return labels[0]
  31. if data.shape[1] == 0:
  32. return Counter(labels).most_common(1)[0][0]
  33. best_feature = choose_best_feature(data, labels)
  34. tree = {best_feature: {}}
  35. feature_values = set(data[:, best_feature])
  36. for value in feature_values:
  37. subset = data[data[:, best_feature] == value]
  38. subset_labels = labels[data[:, best_feature] == value]
  39. tree[best_feature][value] = create_decision_tree(subset, subset_labels)
  40. return tree
  41. # 使用示例数据集进行分类
  42. data = np.array([[1, 1, 1], [1, 1, 0], [0, 1, 1], [0, 0, 1]])
  43. labels = np.array([1, 1, 0, 0])
  44. decision_tree = create_decision_tree(data, labels)
  45. print(decision_tree)

CART算法代码示例(回归树)

  1. import numpy as np
  2. import pickle
  3. import matplotlib.pyplot as plt
  4. from sklearn.datasets import load_boston
  5. def loadDataSet(fileName):
  6. dataMat = []
  7. fr = open(fileName)
  8. for line in fr.readlines():
  9. curLine = line.strip().split('\t')
  10. fltLine = list(map(float, curLine))
  11. dataMat.append(fltLine)
  12. return dataMat
  13. def binSplitDataSet(dataSet, feature, value):
  14. mat0 = dataSet[dataSet[:, feature] > value]
  15. mat1 = dataSet[dataSet[:, feature] <= value]
  16. return mat0, mat1
  17. def regLeaf(dataSet):
  18. return np.mean(dataSet[:, -1])
  19. def regErr(dataSet):
  20. return np.var(dataSet[:, -1]) * len(dataSet)
  21. def chooseBestSplit(dataSet, leafType=regLeaf, errType=regErr, ops=(1, 4)):
  22. tolS = ops[0]; tolN = ops[1]
  23. if len(set(dataSet[:, -1].T.tolist()[0])) == 1:
  24. return None, leafType(dataSet)
  25. m, n = dataSet.shape
  26. S = errType(dataSet)
  27. bestS = float('inf'); bestIndex = 0; bestValue = 0
  28. for featIndex in range(n - 1):
  29. for splitVal in set(dataSet[:, featIndex].T.A.tolist()[0]):
  30. mat0, mat1 = binSplitDataSet(dataSet,

总结

大数据决策树是一种基于树形结构的机器学习算法,特别适用于处理和分析大规模数据集。它通过递归地将数据集分割成更小的子集,以构建出一个类似于树状的预测模型。在树的每个节点上,算法会根据某个特征属性的值来判断数据应该流向哪个分支,直到到达叶子节点,给出最终的预测结果或分类标签。

大数据决策树的优势在于其直观易懂、易于实现,并且能够有效地处理高维数据和具有缺失值的数据集。此外,它还能够自动进行特征选择和交互效应的识别,为决策过程提供有价值的洞察。然而,随着数据量的增加,决策树可能会变得过于复杂,导致过拟合问题。因此,在实际应用中,常需要结合剪枝、集成学习等技术来优化模型性能。

总之,大数据决策树是一种强大且灵活的工具,能够帮助我们从海量数据中挖掘出有价值的规律和模式,为决策提供有力支持。


本文转载自: https://blog.csdn.net/youganma/article/details/143286889
版权归原作者 什么又不懂了? 所有, 如有侵权,请联系我们删除。

“了解大数据中的决策树”的评论:

还没有评论