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

【机器学习】回归树

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

回归树的基本原理

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

  • 选择最优特征及分割点:通过最小化均方误差(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] <= thresholdright_mask = ~left_maskreturn 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, Nonefor 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:continuemse_split = mean_squared_error(y_left) + mean_squared_error(y_right)if mse_split < best_mse:best_mse = mse_splitbest_feature = featurebest_threshold = thresholdreturn best_feature, best_threshold# 回归树类
class RegressionTree:def __init__(self, max_depth=3, min_samples_split=2):self.max_depth = max_depthself.min_samples_split = min_samples_splitself.tree = Nonedef 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.treedef predict_sample(self, x, tree):if not isinstance(tree, dict):return treeif 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.mrgr.cn/news/64319.html

相关文章:

  • 支付宝批量转账工具--企业资金快速流转的安心之选
  • 【天线&空中农业】花生霉变检测系统源码&数据集全套:改进yolo11-LVMB
  • 基于matlab的凸包(Convex Hull)算法理解与测试
  • Effective C++ 学习笔记二
  • python获取当前文件or目录路径
  • IDEA修改生成jar包名字的两种方法实现
  • 微信小程序scroll-view吸顶css样式化表格的表头及iOS上下滑动表头的颜色覆盖、z-index应用及性能分析
  • 异步回调之Join
  • 第十七课 component组件解析
  • Rust语言有哪些常用语句?
  • zyb 的 Codeforces Round 983 (Div. 2)
  • WPF+MVVM案例实战(十八)- 自定义字体图标按钮的封装与实现(ABD类)
  • Python使用K-means实现文本聚类
  • Respiratory Physiology Neurobiology
  • TCP编程-socket(套接字)编程实战1
  • RK3568平台开发系列讲解(中断篇)延迟工作实验
  • vscode makfile编译
  • 电阻基础知识(六)-电阻的失效模式和失效机理
  • 【MacOS实操】如何基于SSH连接远程linux服务器
  • redis详细教程(7.哨兵)
  • 《GBDT 算法的原理推导》 11-13初始化模型 公式解析
  • LangChain学习之路
  • 【Comsol教程】计算流道中的流量
  • 一般无人机和FPV无人机的区别
  • WorkFlow Communicator之TCPServer(上)
  • QT打包Macosx应用发布App Store简易流程