返回

机器学习算法的前世今生,再谈决策树的模型解读与搭建实战

前端

前言

在上一篇文章中,我们简要介绍了决策树的基本原理。这篇文章的主要内容将介绍机器学习中决策树模型的具体解读和搭建实战。

决策树模型解读

  1. 模型结构 :决策树模型的结构类似于一棵倒立的树,其中每个节点代表一个特征,每个分支代表一个可能的决策。决策树的构建过程是通过递归地将数据划分为更小的子集来完成的,直到每个子集中只包含一种类型的实例。

  2. 分类和回归 :决策树可以用于分类和回归任务。在分类任务中,决策树的目的是将数据点分类到不同的类别中。在回归任务中,决策树的目的是预测一个连续值。

  3. 优点和缺点 :决策树有很多优点,包括:

    • 易于理解和解释。
    • 不需要预处理数据。
    • 可以处理高维数据。
    • 鲁棒性强。

决策树的缺点包括:

* 可能产生过拟合。
* 对缺失值敏感。
* 可能产生不稳定的模型。
  1. 参数调优 :决策树的参数包括:

    • 最大深度 :决策树的最大深度。
    • 最小样本数 :每个叶节点的最小样本数。
    • 分裂标准 :用于选择最佳分裂的标准。
  2. 决策树的应用 :决策树广泛应用于各种领域,包括:

    • 医学诊断
    • 欺诈检测
    • 客户流失预测
    • 推荐系统

决策树搭建实战

以下是用 Python 实现的决策树分类算法:

import numpy as np
import pandas as pd

class DecisionTreeClassifier:

    def __init__(self, max_depth=5, min_samples_split=2):
        self.max_depth = max_depth
        self.min_samples_split = min_samples_split

    def fit(self, X, y):
        self.tree_ = self._build_tree(X, y)

    def predict(self, X):
        return [self._predict_instance(x) for x in X]

    def _build_tree(self, X, y, depth=0):
        if depth >= self.max_depth or len(y) < self.min_samples_split:
            return DecisionTreeLeaf(y)

        feature, threshold = self._find_best_split(X, y)
        tree = DecisionTreeNode(feature, threshold)

        left_X, left_y = self._split_data(X, y, feature, threshold, True)
        right_X, right_y = self._split_data(X, y, feature, threshold, False)

        tree.left_ = self._build_tree(left_X, left_y, depth+1)
        tree.right_ = self._build_tree(right_X, right_y, depth+1)

        return tree

    def _find_best_split(self, X, y):
        best_feature = None
        best_threshold = None
        best_score = float('inf')

        for feature in range(X.shape[1]):
            for threshold in np.unique(X[:, feature]):
                score = self._evaluate_split(X, y, feature, threshold)
                if score < best_score:
                    best_feature = feature
                    best_threshold = threshold
                    best_score = score

        return best_feature, best_threshold

    def _evaluate_split(self, X, y, feature, threshold):
        left_X, left_y = self._split_data(X, y, feature, threshold, True)
        right_X, right_y = self._split_data(X, y, feature, threshold, False)

        left_entropy = self._entropy(left_y)
        right_entropy = self._entropy(right_y)

        return (len(left_X) / len(X)) * left_entropy + (len(right_X) / len(X)) * right_entropy

    def _entropy(self, y):
        unique_values = np.unique(y)
        probs = np.array([np.mean(y == value) for value in unique_values])
        return -np.sum(probs * np.log(probs))

    def _split_data(self, X, y, feature, threshold, left):
        if left:
            return X[X[:, feature] <= threshold], y[X[:, feature] <= threshold]
        else:
            return X[X[:, feature] > threshold], y[X[:, feature] > threshold]

    def _predict_instance(self, x):
        node = self.tree_
        while not isinstance(node, DecisionTreeLeaf):
            if x[node.feature_] <= node.threshold_:
                node = node.left_
            else:
                node = node.right_

        return node.class_

class DecisionTreeNode:

    def __init__(self, feature, threshold):
        self.feature_ = feature
        self.threshold_ = threshold
        self.left_ = None
        self.right_ = None

class DecisionTreeLeaf:

    def __init__(self, y):
        self.class_ = np.bincount(y).argmax()

# 使用示例
X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]])
y = np.array([0, 1, 0, 1, 0])

clf = DecisionTreeClassifier()
clf.fit(X, y)

print(clf.predict([[1, 2, 3]]))
# [0]