当前位置: 首页 > article >正文

【机器学习】回归树

回归树是一种用于数值型目标变量的监督学习算法,通过将特征空间划分为多个区域,并在每个区域内使用简单的预测模型(如区域均值)来进行回归。回归树以“递归划分-计算区域均值”的方式逐层生成树节点,最终形成叶节点预测值。相比于线性回归,回归树更适合处理非线性和复杂数据结构。

回归树的基本原理

在回归树中,每个节点执行以下操作:

  • 选择最优特征及分割点:通过最小化均方误差(Mean Squared Error, MSE)等标准选择最佳分割特征和分割点。
  • 分割数据:根据选择的分割特征将数据划分成两部分,形成左子节点和右子节点。
  • 递归分割:对子节点进行递归分割,直至满足停止条件(如最大深度或最小样本数)。

分割准则

均方误差(MSE)

在回归树中,常用均方误差(MSE)作为分割准则:
MSE = 1 N ∑ i = 1 N ( y i − y ˉ ) 2 \text{MSE} = \frac{1}{N} \sum_{i=1}^{N} (y_i - \bar{y})^2 MSE=N1i=1N(yiyˉ)2
其中,( y_i ) 是样本 ( i ) 的实际值,( \bar{y} ) 是区域内样本的平均值。分割点选择通过最小化分割前后数据的 MSE 来完成。

回归树的构建步骤

  1. 选择最佳分割特征与分割点:遍历每个特征和可能的分割点,计算分割后的MSE,选择使MSE最小的分割特征和点。
  2. 递归分割数据:在左、右子节点递归执行上述过程,形成新的分支节点。
  3. 生成叶节点:一旦满足停止条件,将当前节点的预测值设为该区域中所有样本的均值。

用 Numpy 实现回归树

以下代码展示了如何用 Numpy 实现一个基本的回归树,并通过均方误差来确定分割点。

import numpy as np
import matplotlib.pyplot as plt

# 计算均方误差(MSE)
def mean_squared_error(y):
    return np.var(y) * len(y)

# 数据集分割
def split_dataset(X, y, feature, threshold):
    left_mask = X[:, feature] <= threshold
    right_mask = ~left_mask
    return X[left_mask], y[left_mask], X[right_mask], y[right_mask]

# 查找最佳分割特征和分割点
def best_split(X, y):
    best_mse = float("inf")
    best_feature, best_threshold = None, None
    for feature in range(X.shape[1]):
        thresholds = np.unique(X[:, feature])
        for threshold in thresholds:
            _, y_left, _, y_right = split_dataset(X, y, feature, threshold)
            if len(y_left) == 0 or len(y_right) == 0:
                continue
            mse_split = mean_squared_error(y_left) + mean_squared_error(y_right)
            if mse_split < best_mse:
                best_mse = mse_split
                best_feature = feature
                best_threshold = threshold
    return best_feature, best_threshold

# 回归树类
class RegressionTree:
    def __init__(self, max_depth=3, min_samples_split=2):
        self.max_depth = max_depth
        self.min_samples_split = min_samples_split
        self.tree = None

    def fit(self, X, y, depth=0):
        if len(y) < self.min_samples_split or depth >= self.max_depth:
            return np.mean(y)
        
        feature, threshold = best_split(X, y)
        if feature is None:
            return np.mean(y)
        
        left_X, left_y, right_X, right_y = split_dataset(X, y, feature, threshold)
        left_node = self.fit(left_X, left_y, depth + 1)
        right_node = self.fit(right_X, right_y, depth + 1)
        
        self.tree = {"feature": feature, "threshold": threshold, "left": left_node, "right": right_node}
        return self.tree

    def predict_sample(self, x, tree):
        if not isinstance(tree, dict):
            return tree
        if x[tree["feature"]] <= tree["threshold"]:
            return self.predict_sample(x, tree["left"])
        else:
            return self.predict_sample(x, tree["right"])

    def predict(self, X):
        return np.array([self.predict_sample(x, self.tree) for x in X])

# 生成示例数据
np.random.seed(0)
X = np.random.rand(100, 1) * 10  # 特征数据
y = 2 * X.flatten() + np.random.randn(100) * 2  # 标签数据

# 训练回归树
tree = RegressionTree(max_depth=4, min_samples_split=5)
tree.fit(X, y)

# 预测并可视化
X_test = np.linspace(0, 10, 100).reshape(-1, 1)
y_pred = tree.predict(X_test)

plt.scatter(X, y, color="blue", label="训练数据")
plt.plot(X_test, y_pred, color="red", label="回归树预测")
plt.xlabel("特征")
plt.ylabel("目标值")
plt.title("回归树预测示意图")
plt.legend()
plt.show()

在代码中,我们首先通过遍历各个特征和分割点来选择最优分割点,使得均方误差最小。然后在每个节点递归进行分割,直至达到设定的深度或最小样本数。最终通过构建的树结构进行预测。

使用 Sklearn 的回归树

Scikit-Learn 提供了 DecisionTreeRegressor 来实现回归树模型,可以大大简化建模过程。

from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import mean_squared_error

# 训练回归树
regressor = DecisionTreeRegressor(max_depth=4, min_samples_split=5)
regressor.fit(X, y)

# 预测
y_pred_sklearn = regressor.predict(X_test)

# 计算均方误差
mse = mean_squared_error(y, regressor.predict(X))
print("均方误差:", mse)

# 可视化
plt.scatter(X, y, color="blue", label="训练数据")
plt.plot(X_test, y_pred_sklearn, color="red", label="Sklearn 回归树预测")
plt.xlabel("特征")
plt.ylabel("目标值")
plt.title("Sklearn 回归树预测示意图")
plt.legend()
plt.show()

总结

本文介绍了回归树的基本概念与实现,包括回归树的分割准则、MSE 计算、最佳分割点选择等细节。通过 Numpy 手动实现了一个简单的回归树模型,并展示了如何在 Scikit-Learn 中快速实现和使用回归树。


http://www.kler.cn/a/378309.html

相关文章:

  • SpringBoot自动装配过程
  • 【linux】HTTPS 协议原理
  • CentOS9 Stream 设置禁用IPV6
  • Java | Leetcode Java题解之第526题优美的排列
  • Docker使用复习(11.3)
  • 嵌入式——了解stm32
  • 【大语言模型】ACL2024论文-06 探索思维链COT在多模态隐喻检测中的应用
  • Logback 常用配置详解
  • 第十九章 Vue组件之data函数
  • Python Matplotlib 如何处理大数据集的绘制,提高绘图效率
  • lc 73 矩阵置0 ACM模式
  • webpack5
  • 【RK3588 Linux 5.x 内核编程】-设备驱动中的sysfs
  • 【架构艺术】服务架构稳定性的基础保障
  • 嵌入式开发之刷新流
  • SAO-LSSVM分类预测 | SAO-LSSVM雪消融算法优化最小二乘支持向量机多特征分类预测
  • JavaScript 进阶 - 第4天 (黑马笔记)
  • [JAVAEE] 面试题(二) - CAS 和 原子类
  • Java项目实战II基于Spring Boot的秒杀系统设计与实现(开发文档+数据库+源码)
  • 使用Markdown编写适用于GitHub的README.md文件的目录结构
  • css-flex布局属性
  • Python爬虫:揭开店铺详情的神秘面纱
  • 【Jenkins】 上传docker包并推送到远程仓库
  • 构建您自己的 RAG 应用程序:使用 Ollama、Python 和 ChromaDB 在本地设置 LLM 的分步指南
  • 独立开发的个人品牌打造:个人IP与独立开发的结合
  • 如何将epub转换成word?