{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "### 简介\n", "CART树即分类回归树(classification and regression tree),顾名思义,它即能用作分类任务又能用作回归任务,它的应用比较广泛,通常会用作集成学习的基分类器,总得来说,它与ID3/C4.5有如下不同: \n", "\n", "(1)它是一颗二叉树; \n", "\n", "(2)特征选择的方法不一样,CART分类树利用基尼系数做特征选择,CART回归树利用平方误差做特征选择; \n", "\n", "接下来,分别对CART分类树和回归树做介绍" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### CART分类树\n", "\n", "首先介绍特征选择方法,基尼系数: \n", "\n", "$$\n", "Gini(p)=\\sum_{k=1}^Kp_k(1-p_k)=1-\\sum_{k=1}^Kp_k^2\n", "$$ \n", "\n", "所以,对于给定的样本集合$D$,其基尼指数: \n", "\n", "$$\n", "Gini(D)=1-\\sum_{k=1}^K(\\frac{\\mid C_k \\mid}{\\mid D \\mid})^2\n", "$$ \n", "\n", "这里,$C_k$是$D$中属于第$k$类的样本子集,$K$是类的个数,由于CART树是二叉树,所以对于某特征$A$,判断其对分类标签的贡献时,只需要判断该特征是否等于某个取值$a$的情况,将当前数据集分割成$D_1$和$D_2$两部分: \n", "\n", "$$\n", "D_1=\\{(x,y)\\in D\\mid A(x)=a\\},D_2=D-D_1\n", "$$ \n", "\n", "所以在特征$A(x)=a$的条件下,集合$D$的基尼指数可以定义为: \n", "\n", "$$\n", "Gini(D,A,a)=\\frac{\\mid D_1 \\mid}{\\mid D \\mid}Gini(D_1)+\\frac{\\mid D_2 \\mid}{\\mid D \\mid}Gini(D_2),这里D_1=\\{(x,y)\\in D\\mid A(x)=a\\},D_2=D-D_1\n", "$$ \n", "\n", "#### 代码实现\n", "接下来进行CART分类树的代码实现,这里与ID3/C4.5最大的不同就是每次对当前结点仅进行二分处理" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "定义计算gini系数相关的函数,代码封装到ml_models.utils\n", "\"\"\"\n", "import numpy as np\n", "def gini(x, sample_weight=None):\n", " \"\"\"\n", " 计算基尼系数 Gini(D)\n", " :param x:\n", " :param sample_weight:\n", " :return:\n", " \"\"\"\n", " x_num = len(x)\n", " # 如果sample_weight为None设均设置一样\n", " if sample_weight is None:\n", " sample_weight = np.asarray([1.0] * x_num)\n", " x_counter = {}\n", " weight_counter = {}\n", " # 统计各x取值出现的次数以及其对应的sample_weight列表\n", " for index in range(0, x_num):\n", " x_value = x[index]\n", " if x_counter.get(x_value) is None:\n", " x_counter[x_value] = 0\n", " weight_counter[x_value] = []\n", " x_counter[x_value] += 1\n", " weight_counter[x_value].append(sample_weight[index])\n", "\n", " # 计算gini系数\n", " gini_value = 1.0\n", " for key, value in x_counter.items():\n", " p_i = 1.0 * value * np.mean(weight_counter.get(key)) / x_num\n", " gini_value -= p_i * p_i\n", " return gini_value\n", "\n", "\n", "def cond_gini(x, y, sample_weight=None):\n", " \"\"\"\n", " 计算条件gini系数:Gini(y,x)\n", " \"\"\"\n", " x = np.asarray(x)\n", " y = np.asarray(y)\n", " # x中元素个数\n", " x_num = len(x)\n", " # 如果sample_weight为None设均设置一样\n", " if sample_weight is None:\n", " sample_weight = np.asarray([1.0] * x_num)\n", " # 计算\n", " gini_value = .0\n", " for x_value in set(x):\n", " x_index = np.where(x == x_value)\n", " new_x = x[x_index]\n", " new_y = y[x_index]\n", " new_sample_weight = sample_weight[x_index]\n", " p_i = 1.0 * len(new_x) / x_num\n", " gini_value += p_i * gini(new_y, new_sample_weight)\n", " return gini_value\n", "\n", "\n", "def gini_gain(x, y, sample_weight=None):\n", " \"\"\"\n", " gini值的增益\n", " \"\"\"\n", " x_num = len(x)\n", " if sample_weight is None:\n", " sample_weight = np.asarray([1.0] * x_num)\n", " return gini(y, sample_weight) - cond_gini(x, y, sample_weight)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import os\n", "os.chdir('../')\n", "from ml_models import utils\n", "from ml_models.wrapper_models import DataBinWrapper\n", "\"\"\"\n", "CART分类树的实现,代码封装到ml_models.tree模块\n", "\"\"\"\n", "class CARTClassifier(object):\n", " class Node(object):\n", " \"\"\"\n", " 树节点,用于存储节点信息以及关联子节点\n", " \"\"\"\n", "\n", " def __init__(self, feature_index: int = None, feature_value=None, target_distribute: dict = None,\n", " weight_distribute: dict = None,\n", " left_child_node=None, right_child_node=None, num_sample: int = None):\n", " \"\"\"\n", " :param feature_index: 特征id\n", " :param feature_value: 特征取值\n", " :param target_distribute: 目标分布\n", " :param weight_distribute:权重分布\n", " :param left_child_node: 左孩子结点\n", " :param right_child_node: 右孩子结点\n", " :param num_sample:样本量\n", " \"\"\"\n", " self.feature_index = feature_index\n", " self.feature_value = feature_value\n", " self.target_distribute = target_distribute\n", " self.weight_distribute = weight_distribute\n", " self.left_child_node = left_child_node\n", " self.right_child_node = right_child_node\n", " self.num_sample = num_sample\n", "\n", " def __init__(self, criterion='gini', max_depth=None, min_samples_split=2, min_samples_leaf=1,\n", " min_impurity_decrease=0, max_bins=10):\n", " \"\"\"\n", " :param criterion:划分标准,默认为gini,另外entropy表示用信息增益比\n", " :param max_depth:树的最大深度\n", " :param min_samples_split:当对一个内部结点划分时,要求该结点上的最小样本数,默认为2\n", " :param min_samples_leaf:设置叶子结点上的最小样本数,默认为1\n", " :param min_impurity_decrease:打算划分一个内部结点时,只有当划分后不纯度(可以用criterion参数指定的度量来描述)减少值不小于该参数指定的值,才会对该结点进行划分,默认值为0\n", " \"\"\"\n", " self.criterion = criterion\n", " if criterion == 'gini':\n", " self.criterion_func = utils.gini_gain\n", " else:\n", " self.criterion_func = utils.info_gain_rate\n", " self.max_depth = max_depth\n", " self.min_samples_split = min_samples_split\n", " self.min_samples_leaf = min_samples_leaf\n", " self.min_impurity_decrease = min_impurity_decrease\n", "\n", " self.root_node: self.Node = None\n", " self.dbw = DataBinWrapper(max_bins=max_bins)\n", "\n", " def _build_tree(self, current_depth, current_node: Node, x, y, sample_weight):\n", " \"\"\"\n", " 递归进行特征选择,构建树\n", " :param x:\n", " :param y:\n", " :param sample_weight:\n", " :return:\n", " \"\"\"\n", " rows, cols = x.shape\n", " # 计算y分布以及其权重分布\n", " target_distribute = {}\n", " weight_distribute = {}\n", " for index, tmp_value in enumerate(y):\n", " if tmp_value not in target_distribute:\n", " target_distribute[tmp_value] = 0.0\n", " weight_distribute[tmp_value] = []\n", " target_distribute[tmp_value] += 1.0\n", " weight_distribute[tmp_value].append(sample_weight[index])\n", " for key, value in target_distribute.items():\n", " target_distribute[key] = value / rows\n", " weight_distribute[key] = np.mean(weight_distribute[key])\n", " current_node.target_distribute = target_distribute\n", " current_node.weight_distribute = weight_distribute\n", " current_node.num_sample = rows\n", " # 判断停止切分的条件\n", "\n", " if len(target_distribute) <= 1:\n", " return\n", "\n", " if rows < self.min_samples_split:\n", " return\n", "\n", " if self.max_depth is not None and current_depth > self.max_depth:\n", " return\n", "\n", " # 寻找最佳的特征以及取值\n", " best_index = None\n", " best_index_value = None\n", " best_criterion_value = 0\n", " for index in range(0, cols):\n", " for index_value in set(x[:, index]):\n", " criterion_value = self.criterion_func((x[:, index] == index_value).astype(int), y, sample_weight)\n", " if criterion_value > best_criterion_value:\n", " best_criterion_value = criterion_value\n", " best_index = index\n", " best_index_value = index_value\n", "\n", " # 如果criterion_value减少不够则停止\n", " if best_index is None:\n", " return\n", " if best_criterion_value <= self.min_impurity_decrease:\n", " return\n", " # 切分\n", " current_node.feature_index = best_index\n", " current_node.feature_value = best_index_value\n", " selected_x = x[:, best_index]\n", "\n", " # 创建左孩子结点\n", " left_selected_index = np.where(selected_x == best_index_value)\n", " # 如果切分后的点太少,以至于都不能做叶子节点,则停止分割\n", " if len(left_selected_index[0]) >= self.min_samples_leaf:\n", " left_child_node = self.Node()\n", " current_node.left_child_node = left_child_node\n", " self._build_tree(current_depth + 1, left_child_node, x[left_selected_index], y[left_selected_index],\n", " sample_weight[left_selected_index])\n", " # 创建右孩子结点\n", " right_selected_index = np.where(selected_x != best_index_value)\n", " # 如果切分后的点太少,以至于都不能做叶子节点,则停止分割\n", " if len(right_selected_index[0]) >= self.min_samples_leaf:\n", " right_child_node = self.Node()\n", " current_node.right_child_node = right_child_node\n", " self._build_tree(current_depth + 1, right_child_node, x[right_selected_index], y[right_selected_index],\n", " sample_weight[right_selected_index])\n", "\n", " def fit(self, x, y, sample_weight=None):\n", " # check sample_weight\n", " n_sample = x.shape[0]\n", " if sample_weight is None:\n", " sample_weight = np.asarray([1.0] * n_sample)\n", " # check sample_weight\n", " if len(sample_weight) != n_sample:\n", " raise Exception('sample_weight size error:', len(sample_weight))\n", "\n", " # 构建空的根节点\n", " self.root_node = self.Node()\n", "\n", " # 对x分箱\n", " self.dbw.fit(x)\n", "\n", " # 递归构建树\n", " self._build_tree(1, self.root_node, self.dbw.transform(x), y, sample_weight)\n", "\n", " # 检索叶子节点的结果\n", " def _search_node(self, current_node: Node, x, class_num):\n", " if current_node.left_child_node is not None and x[current_node.feature_index] == current_node.feature_value:\n", " return self._search_node(current_node.left_child_node, x, class_num)\n", " elif current_node.right_child_node is not None and x[current_node.feature_index] != current_node.feature_value:\n", " return self._search_node(current_node.right_child_node, x, class_num)\n", " else:\n", " result = []\n", " total_value = 0.0\n", " for index in range(0, class_num):\n", " value = current_node.target_distribute.get(index, 0) * current_node.weight_distribute.get(index, 1.0)\n", " result.append(value)\n", " total_value += value\n", " # 归一化\n", " for index in range(0, class_num):\n", " result[index] = result[index] / total_value\n", " return result\n", "\n", " def predict_proba(self, x):\n", " # 计算结果概率分布\n", " x = self.dbw.transform(x)\n", " rows = x.shape[0]\n", " results = []\n", " class_num = len(self.root_node.target_distribute)\n", " for row in range(0, rows):\n", " results.append(self._search_node(self.root_node, x[row], class_num))\n", " return np.asarray(results)\n", "\n", " def predict(self, x):\n", " return np.argmax(self.predict_proba(x), axis=1)\n", "\n", " def _prune_node(self, current_node: Node, alpha):\n", " # 如果有子结点,先对子结点部分剪枝\n", " if current_node.left_child_node is not None:\n", " self._prune_node(current_node.left_child_node, alpha)\n", " if current_node.right_child_node is not None:\n", " self._prune_node(current_node.right_child_node, alpha)\n", " # 再尝试对当前结点剪枝\n", " if current_node.left_child_node is not None or current_node.right_child_node is not None:\n", " # 避免跳层剪枝\n", " for child_node in [current_node.left_child_node, current_node.right_child_node]:\n", " # 当前剪枝的层必须是叶子结点的层\n", " if child_node.left_child_node is not None or child_node.right_child_node is not None:\n", " return\n", " # 计算剪枝的前的损失值\n", " pre_prune_value = alpha * 2\n", " for child_node in [current_node.left_child_node, current_node.right_child_node]:\n", " for key, value in child_node.target_distribute.items():\n", " pre_prune_value += -1 * child_node.num_sample * value * np.log(\n", " value) * child_node.weight_distribute.get(key, 1.0)\n", " # 计算剪枝后的损失值\n", " after_prune_value = alpha\n", " for key, value in current_node.target_distribute.items():\n", " after_prune_value += -1 * current_node.num_sample * value * np.log(\n", " value) * current_node.weight_distribute.get(key, 1.0)\n", "\n", " if after_prune_value <= pre_prune_value:\n", " # 剪枝操作\n", " current_node.left_child_node = None\n", " current_node.right_child_node = None\n", " current_node.feature_index = None\n", " current_node.feature_value = None\n", "\n", " def prune(self, alpha=0.01):\n", " \"\"\"\n", " 决策树剪枝 C(T)+alpha*|T|\n", " :param alpha:\n", " :return:\n", " \"\"\"\n", " # 递归剪枝\n", " self._prune_node(self.root_node, alpha)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "#造伪数据\n", "from sklearn.datasets import make_classification\n", "data, target = make_classification(n_samples=100, n_features=2, n_classes=2, n_informative=1, n_redundant=0,\n", " n_repeated=0, n_clusters_per_class=1, class_sep=.5,random_state=21)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#训练并查看效果\n", "tree = CARTClassifier()\n", "tree.fit(data, target)\n", "utils.plot_decision_function(data, target, tree)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "一样的,如果不加以限制,同样会存在过拟合现象,所以可以剪枝..." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#剪枝\n", "tree.prune(5)\n", "utils.plot_decision_function(data, target, tree)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### CART回归树\n", "回归树的特征选择是使用的平方误差,即选择一个特征$j$和一个取值$s$,将训练集按$X^j\\leq s$和$X^j>s$分为两部分,寻找使这两部分的误差平方之和下降最多的$j,s$,这个过程可以描述如下: \n", "\n", "$$\n", "\\min_{j,s}[\\min_{c_1}\\sum_{x_i\\in R_1(j,s)}(y_i-c_1)^2+\\min_{c_2}\\sum_{x_i\\in R_2(j,s)}(y_i-c_2)^2]\n", "$$ \n", "\n", "这里$R_1(j,s)=\\{x\\mid x^j\\leq s\\},R_2(j,s)=\\{x\\mid x^j> s\\},c_1=ave(y_i\\mid x_i\\in R_1(j,s)),c_2=ave(y_i\\mid x_i\\in R_2(j,s))$ \n", "\n", "代码实现: " ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "平方误差相关函数,封装到ml_models.utils\n", "\"\"\"\n", "def square_error(x, sample_weight=None):\n", " \"\"\"\n", " 平方误差\n", " :param x:\n", " :param sample_weight:\n", " :return:\n", " \"\"\"\n", " x = np.asarray(x)\n", " x_mean = np.mean(x)\n", " x_num = len(x)\n", " if sample_weight is None:\n", " sample_weight = np.asarray([1.0] * x_num)\n", " error = 0.0\n", " for index in range(0, x_num):\n", " error += (x[index] - x_mean) * (x[index] - x_mean) * sample_weight[index]\n", " return error\n", "\n", "\n", "def cond_square_error(x, y, sample_weight=None):\n", " \"\"\"\n", " 计算按x分组的y的误差值\n", " :param x:\n", " :param y:\n", " :param sample_weight:\n", " :return:\n", " \"\"\"\n", " x = np.asarray(x)\n", " y = np.asarray(y)\n", " # x中元素个数\n", " x_num = len(x)\n", " # 如果sample_weight为None设均设置一样\n", " if sample_weight is None:\n", " sample_weight = np.asarray([1.0] * x_num)\n", " # 计算\n", " error = .0\n", " for x_value in set(x):\n", " x_index = np.where(x == x_value)\n", " new_y = y[x_index]\n", " new_sample_weight = sample_weight[x_index]\n", " error += square_error(new_y, new_sample_weight)\n", " return error\n", "\n", "\n", "def square_error_gain(x, y, sample_weight=None):\n", " \"\"\"\n", " 平方误差带来的增益值\n", " :param x:\n", " :param y:\n", " :param sample_weight:\n", " :return:\n", " \"\"\"\n", " x_num = len(x)\n", " if sample_weight is None:\n", " sample_weight = np.asarray([1.0] * x_num)\n", " return square_error(y, sample_weight) - cond_square_error(x, y, sample_weight)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "CART回归树实现,封装到ml_models.tree\n", "\"\"\"\n", "class CARTRegressor(object):\n", " class Node(object):\n", " \"\"\"\n", " 树节点,用于存储节点信息以及关联子节点\n", " \"\"\"\n", "\n", " def __init__(self, feature_index: int = None, feature_value=None, y_hat=None, square_error=None,\n", " left_child_node=None, right_child_node=None, num_sample: int = None):\n", " \"\"\"\n", " :param feature_index: 特征id\n", " :param feature_value: 特征取值\n", " :param y_hat: 预测值\n", " :param square_error: 当前结点的平方误差\n", " :param left_child_node: 左孩子结点\n", " :param right_child_node: 右孩子结点\n", " :param num_sample:样本量\n", " \"\"\"\n", " self.feature_index = feature_index\n", " self.feature_value = feature_value\n", " self.y_hat = y_hat\n", " self.square_error = square_error\n", " self.left_child_node = left_child_node\n", " self.right_child_node = right_child_node\n", " self.num_sample = num_sample\n", "\n", " def __init__(self, criterion='mse', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_std=1e-3,\n", " min_impurity_decrease=0, max_bins=10):\n", " \"\"\"\n", " :param criterion:划分标准,目前仅有平方误差\n", " :param max_depth:树的最大深度\n", " :param min_samples_split:当对一个内部结点划分时,要求该结点上的最小样本数,默认为2\n", " :param min_std:最小的标准差\n", " :param min_samples_leaf:设置叶子结点上的最小样本数,默认为1\n", " :param min_impurity_decrease:打算划分一个内部结点时,只有当划分后不纯度(可以用criterion参数指定的度量来描述)减少值不小于该参数指定的值,才会对该结点进行划分,默认值为0\n", " \"\"\"\n", " self.criterion = criterion\n", " if criterion == 'mse':\n", " self.criterion_func = utils.square_error_gain\n", " self.max_depth = max_depth\n", " self.min_samples_split = min_samples_split\n", " self.min_samples_leaf = min_samples_leaf\n", " self.min_std = min_std\n", " self.min_impurity_decrease = min_impurity_decrease\n", "\n", " self.root_node: self.Node = None\n", " self.dbw = DataBinWrapper(max_bins=max_bins)\n", "\n", " def _build_tree(self, current_depth, current_node: Node, x, y, sample_weight):\n", " \"\"\"\n", " 递归进行特征选择,构建树\n", " :param x:\n", " :param y:\n", " :param sample_weight:\n", " :return:\n", " \"\"\"\n", " rows, cols = x.shape\n", " # 计算当前y的加权平均值\n", " current_node.y_hat = np.dot(sample_weight / np.sum(sample_weight), y)\n", " current_node.num_sample = rows\n", " # 判断停止切分的条件\n", " current_node.square_error = np.dot(y - np.mean(y), y - np.mean(y))\n", " if np.sqrt(current_node.square_error / rows) <= self.min_std:\n", " return\n", "\n", " if rows < self.min_samples_split:\n", " return\n", "\n", " if self.max_depth is not None and current_depth > self.max_depth:\n", " return\n", "\n", " # 寻找最佳的特征以及取值\n", " best_index = None\n", " best_index_value = None\n", " best_criterion_value = 0\n", " for index in range(0, cols):\n", " for index_value in sorted(set(x[:, index])):\n", " criterion_value = self.criterion_func((x[:, index] <= index_value).astype(int), y, sample_weight)\n", " if criterion_value > best_criterion_value:\n", " best_criterion_value = criterion_value\n", " best_index = index\n", " best_index_value = index_value\n", "\n", " # 如果criterion_value减少不够则停止\n", " if best_index is None:\n", " return\n", " if best_criterion_value <= self.min_impurity_decrease:\n", " return\n", " # 切分\n", " current_node.feature_index = best_index\n", " current_node.feature_value = best_index_value\n", " selected_x = x[:, best_index]\n", "\n", " # 创建左孩子结点\n", " left_selected_index = np.where(selected_x <= best_index_value)\n", " # 如果切分后的点太少,以至于都不能做叶子节点,则停止分割\n", " if len(left_selected_index[0]) >= self.min_samples_leaf:\n", " left_child_node = self.Node()\n", " current_node.left_child_node = left_child_node\n", " self._build_tree(current_depth + 1, left_child_node, x[left_selected_index], y[left_selected_index],\n", " sample_weight[left_selected_index])\n", " # 创建右孩子结点\n", " right_selected_index = np.where(selected_x > best_index_value)\n", " # 如果切分后的点太少,以至于都不能做叶子节点,则停止分割\n", " if len(right_selected_index[0]) >= self.min_samples_leaf:\n", " right_child_node = self.Node()\n", " current_node.right_child_node = right_child_node\n", " self._build_tree(current_depth + 1, right_child_node, x[right_selected_index], y[right_selected_index],\n", " sample_weight[right_selected_index])\n", "\n", " def fit(self, x, y, sample_weight=None):\n", " # check sample_weight\n", " n_sample = x.shape[0]\n", " if sample_weight is None:\n", " sample_weight = np.asarray([1.0] * n_sample)\n", " # check sample_weight\n", " if len(sample_weight) != n_sample:\n", " raise Exception('sample_weight size error:', len(sample_weight))\n", "\n", " # 构建空的根节点\n", " self.root_node = self.Node()\n", "\n", " # 对x分箱\n", " self.dbw.fit(x)\n", "\n", " # 递归构建树\n", " self._build_tree(1, self.root_node, self.dbw.transform(x), y, sample_weight)\n", "\n", " # 检索叶子节点的结果\n", " def _search_node(self, current_node: Node, x):\n", " if current_node.left_child_node is not None and x[current_node.feature_index] <= current_node.feature_value:\n", " return self._search_node(current_node.left_child_node, x)\n", " elif current_node.right_child_node is not None and x[current_node.feature_index] > current_node.feature_value:\n", " return self._search_node(current_node.right_child_node, x)\n", " else:\n", " return current_node.y_hat\n", "\n", " def predict(self, x):\n", " # 计算结果概率分布\n", " x = self.dbw.transform(x)\n", " rows = x.shape[0]\n", " results = []\n", " for row in range(0, rows):\n", " results.append(self._search_node(self.root_node, x[row]))\n", " return np.asarray(results)\n", "\n", " def _prune_node(self, current_node: Node, alpha):\n", " # 如果有子结点,先对子结点部分剪枝\n", " if current_node.left_child_node is not None:\n", " self._prune_node(current_node.left_child_node, alpha)\n", " if current_node.right_child_node is not None:\n", " self._prune_node(current_node.right_child_node, alpha)\n", " # 再尝试对当前结点剪枝\n", " if current_node.left_child_node is not None or current_node.right_child_node is not None:\n", " # 避免跳层剪枝\n", " for child_node in [current_node.left_child_node, current_node.right_child_node]:\n", " # 当前剪枝的层必须是叶子结点的层\n", " if child_node.left_child_node is not None or child_node.right_child_node is not None:\n", " return\n", " # 计算剪枝的前的损失值\n", " pre_prune_value = alpha * 2 + \\\n", " (0.0 if current_node.left_child_node.square_error is None else current_node.left_child_node.square_error) + \\\n", " (0.0 if current_node.right_child_node.square_error is None else current_node.right_child_node.square_error)\n", " # 计算剪枝后的损失值\n", " after_prune_value = alpha + current_node.square_error\n", "\n", " if after_prune_value <= pre_prune_value:\n", " # 剪枝操作\n", " current_node.left_child_node = None\n", " current_node.right_child_node = None\n", " current_node.feature_index = None\n", " current_node.feature_value = None\n", " current_node.square_error = None\n", "\n", " def prune(self, alpha=0.01):\n", " \"\"\"\n", " 决策树剪枝 C(T)+alpha*|T|\n", " :param alpha:\n", " :return:\n", " \"\"\"\n", " # 递归剪枝\n", " self._prune_node(self.root_node, alpha)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "#构造数据\n", "data = np.linspace(1, 10, num=100)\n", "target = np.sin(data) + np.random.random(size=100)#添加噪声\n", "data = data.reshape((-1, 1))" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "tree = CARTRegressor(max_bins=50)\n", "tree.fit(data, target)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "plt.scatter(data, target)\n", "plt.plot(data, tree.predict(data), color='r')" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#剪枝\n", "tree.prune(1)\n", "plt.scatter(data, target)\n", "plt.plot(data, tree.predict(data), color='r')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.4" } }, "nbformat": 4, "nbformat_minor": 2 }