当前位置:   article > 正文

机器学习之决策树详解及Python实现_决策树python实现

决策树python实现

一、决策树定义

决策树是一种树形结构,其中每个内部节点表示一个属性上的测试,每个分支代表一个测试输出,每个叶节点代表一种类别(在分类中)或一个实值(在回归中)。从根到叶节点的每条路径代表了一个分类规则。决策树学习的目的是为了产生一颗泛化能力强,即处理未见示例能力强的决策树。

二、构建决策树的三种方法

  1. ID3算法:使用信息增益来选择划分属性。信息增益越大,则意味着使用该属性进行划分所获得的“纯度提升”越大。

    • 信息熵公式:
    • 信息增益公式:
  2. C4.5算法:是ID3算法的改进,使用增益率来选择划分属性,以解决信息增益偏向于选择取值较多的属性的问题。

    • 增益率公式:
    • 其中,称为属性a的“固有值”。
  3. CART算法:既可以用于分类也可以用于回归。CART树是二叉树,内部节点特征的取值为“是”和“否”。对于分类问题,CART使用基尼指数来选择划分属性。

    • 基尼指数公式:

三、使用Python实现ID3和CART决策树

1.ID3算法实现

ID3算法主要步骤

  1. 选择最佳划分属性

    • 计算数据集中每个属性的信息增益。
    • 选择信息增益最高的属性作为划分属性。
  2. 划分数据集

    • 根据选定的划分属性将数据集分成若干个子集,每个子集对应于划分属性的一个值。
  3. 递归构建子树

    • 对每个子集递归地执行步骤1和步骤2,直到满足停止条件(如所有样本属于同一类别、没有剩余属性或信息增益低于某个阈值)。

phyon代码实现ID3

  1. import numpy as np
  2. class Node:
  3. def __init__(self, feature=None, threshold=None, left=None, right=None, *, value=None):
  4. self.feature = feature
  5. self.threshold = threshold
  6. self.left = left
  7. self.right = right
  8. self.value = value
  9. def is_leaf_node(self):
  10. return self.value is not None
  11. class ID3Classifier:
  12. def __init__(self, min_samples_split=2, max_depth=100, n_feats=None):
  13. self.min_samples_split = min_samples_split
  14. self.max_depth = max_depth
  15. self.n_feats = n_feats
  16. self.root = None
  17. def fit(self, X, y):
  18. self.n_feats = X.shape[1] if not self.n_feats else min(self.n_feats, X.shape[1])
  19. self.root = self._grow_tree(X, y)
  20. def predict(self, X):
  21. return np.array([self._traverse_tree(x, self.root) for x in X])
  22. def _grow_tree(self, X, y, depth=0):
  23. n_samples, n_features = X.shape
  24. n_labels = len(np.unique(y))
  25. # Stopping criteria
  26. if (depth >= self.max_depth or n_labels == 1 or n_samples < self.min_samples_split):
  27. leaf_value = self._most_common_label(y)
  28. return Node(value=leaf_value)
  29. feat_idxs = np.random.choice(n_features, self.n_feats, replace=False)
  30. # Greedily select the best split according to information gain
  31. best_feat, best_thresh = self._best_criteria(X, y, feat_idxs)
  32. # Grow the children that result from the split
  33. left_idxs, right_idxs = self._split(X[:, best_feat], best_thresh)
  34. left = self._grow_tree(X[left_idxs, :], y[left_idxs], depth+1)
  35. right = self._grow_tree(X[right_idxs, :], y[right_idxs], depth+1)
  36. return Node(best_feat, best_thresh, left, right)
  37. def _best_criteria(self, X, y, feat_idxs):
  38. best_gain = -1
  39. split_idx, split_thresh = None, None
  40. for feat_idx in feat_idxs:
  41. X_column = X[:, feat_idx]
  42. thresholds = np.unique(X_column)
  43. for threshold in thresholds:
  44. gain = self._information_gain(y, X_column, threshold)
  45. if gain > best_gain:
  46. best_gain = gain
  47. split_idx = feat_idx
  48. split_thresh = threshold
  49. return split_idx, split_thresh
  50. def _information_gain(self, y, X_column, split_thresh):
  51. # Parent loss
  52. parent_entropy = self._entropy(y)
  53. # Generate split
  54. left_idxs, right_idxs = self._split(X_column, split_thresh)
  55. if len(left_idxs) == 0 or len(right_idxs) == 0:
  56. return 0
  57. # Compute the weighted avg. of the loss for the

2.测试数据集结果。为了完整性,我们需要实现_most_common_label, _entropy, 和 _split 方法,以及数据集来测试代码。以下是一个补全后的版本,并附带一个简单的数据集进行测试:

  1. import numpy as np
  2. class Node:
  3. # ...(类定义如上所示)
  4. class ID3Classifier:
  5. # ...(类定义如上所示)
  6. def _most_common_label(self, y):
  7. counter = np.bincount(y)
  8. most_common = np.argmax(counter)
  9. return most_common
  10. def _entropy(self, y):
  11. _, counts = np.unique(y, return_counts=True)
  12. probabilities = counts / counts.sum()
  13. entropy = sum(probabilities * -np.log2(probabilities))
  14. return entropy
  15. def _split(self, X_column, split_thresh):
  16. left_idxs = np.argwhere(X_column <= split_thresh).flatten()
  17. right_idxs = np.argwhere(X_column > split_thresh).flatten()
  18. return left_idxs, right_idxs
  19. # 创建一个简单的数据集
  20. X = np.array([
  21. [1, 0],
  22. [1, 1],
  23. [0, 0],
  24. [0, 1],
  25. [1, 0],
  26. [0, 0],
  27. [1, 1],
  28. [0, 1],
  29. [1, 0],
  30. [1, 1]
  31. ])
  32. y = np.array([0, 0, 1, 1, 0, 1, 0, 1, 1, 0]) # 二分类问题:0 和 1

CART算法创建决策树

在Python中,使用CART(Classification and Regression Trees)算法创建决策树通常涉及使用现成的机器学习库,如scikit-learn。scikit-learn提供了DecisionTreeClassifier类,该类默认使用CART算法来构建决策树。 下面是一个使用scikit-learn的DecisionTreeClassifier来基于给定数据集创建决策树的示例:

  1. import numpy as np
  2. from sklearn.tree import DecisionTreeClassifier
  3. from sklearn.model_selection import train_test_split
  4. from sklearn.metrics import accuracy_score
  5. # 给定的数据集
  6. X = np.array([
  7. [1, 0],
  8. [1, 1],
  9. [0, 0],
  10. [0, 1],
  11. [1, 0],
  12. [0, 0],
  13. [1, 1],
  14. [0, 1],
  15. [1, 0],
  16. [1, 1]
  17. ])
  18. y = np.array([0, 0, 1, 1, 0, 1, 0, 1, 1, 0])
  19. # 将数据集分为训练集和测试集
  20. X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
  21. # 创建CART决策树分类器
  22. clf = DecisionTreeClassifier(criterion='gini', random_state=42)
  23. # 训练决策树
  24. clf.fit(X_train, y_train)
  25. # 在测试集上进行预测
  26. y_pred = clf.predict(X_test)
  27. # 计算准确率
  28. accuracy = accuracy_score(y_test, y_pred)
  29. print(f"Accuracy: {accuracy}")
  30. # 可视化决策树(需要安装graphviz库和pydotplus库)
  31. # 注意:这部分代码在某些环境中可能无法运行,因为它依赖于系统级别的Graphviz工具
  32. from sklearn.tree import export_graphviz
  33. import pydotplus
  34. dot_data = export_graphviz(clf, out_file=None,
  35. feature_names=['feature_1', 'feature_2'],
  36. class_names=['class_0', 'class_1'],
  37. filled=True, rounded=True,
  38. special_characters=True)
  39. graph = pydotplus.graph_from_dot_data(dot_data)
  40. graph.write_png('decision_tree.png')

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/696277
推荐阅读
相关标签
  

闽ICP备14008679号