决策树面试知识点最全总结(四)——CART回归树

CART回归树

如果样本的标签和样本的特征存在非线性关系时,则普通的线性回归、岭回归和Lasso回归都不再使用。
局部加权回归也可以对非线性数据进行较好的拟合,但是它是非参数模型,每次预测都要重新训练模型参数,计算量太大,耗费时间。
CART树回归算法属于一种局部的回归算法,通过将全局的数据集划分成多份容易建模的数据集,这样在每个个数据集上进行局部的回归建模。

CART回归树用平方误差最小化准则,进行特征选择,生成二叉树。
重点:
一个回归树对应着输入空间(即特征空间)的一个划分以及在划分的单元上的输出值。

1) 如何划分?划分标准时什么?
2)各个划分单元上的输出值怎么确定?
如果回答了以上2个问题,那么回归树模型就确定了。
假设已将输入空间划分为M个单元 R 1 , R 2 R m R_1,R_2…R_m ,并且在每个单元上都有一个固定的输出值 C m C_m ,于是回归树模型可表示为:
f ( x ) = m = 1 M c m I ( x R m ) f(x)=\displaystyle\sum_{m=1}^{M}c_mI(x∈R_m)
当输入空间的划分确定时,可以用平方误差 ( x i R m ) ( y i f ( x i ) ) 2 \displaystyle\sum_{(x_i ∈R_m)}(y_i-f(x_i))^2
来表示回归树关于训练数据的预测误差。
用平方误差最小准则求解每个单元上的最优输出值,易知单元 R m c m R m x i y i R_m上的c_m的最优值是R_m上的所有输入实例x_i对应的输出y_i的平均值
c m = a v e ( y i x i R m ) c'_m = ave(y_i|x_i ∈R_m)
这样就回答了第2个问题,剩下第一个问题 了,那么如何划分呢?

接下来的问题是确定如何划分数据集:

我们采用启发式的方法,选择第j个变量 x j x^j 和它的取值s,作为切分变量和切分点

接下来要回答的是:如何选择最好的切分向量和切分点?
这样考虑:这个切分向量和切分点可以将数据集分成2个区域
R 1 ( j , s ) = x x ( j ) < = s R 2 ( j , s ) = x x ( j ) > s R_1(j,s)={ x|x^{(j)}<= s }和R_2(j,s)={ x|x^{(j)}>s }
按平方误差来计算着两个区域上的误差
最佳的切分向量和切分点对(j,s)是满足以下条件的(j,s)对:
在这里插入图片描述
对于固定的切分变量j,可以找到最优的切分点s
c 1 = a v e ( y i x i R 1 ( j , s ) ) c_1 =ave(y_i|x_i∈R_1(j,s)) c 2 = a v e ( y i x i R 2 ( j , s ) ) c_2 =ave(y_i|x_i∈R_2(j,s))
遍历所有的切分变量j和切分点s,构成一个(j,s)对,选择使上述误差最小的js对对数据集进行划分,分成2个区域R1 和 R2,接着对每个区域重复上述划分过程,直到满足停止条件为止。这样就生成了一颗回归树。

最下二乘回归树生成算法:
输入:训练数据集D
输出:回归树f(x)
在训练数据集所在的输入空间中,递归的将每个区域划分成两个区域并决定每个区域上的输出值,构建二叉树。
1)选择最优切分变量J 与切分点S,求解
在这里插入图片描述
遍历变量j,对固定的切分变量j,扫描切分点s,选择使上式达到最小值的对(j,s)
2)用选定的对(j,s)划分区域并决定相应的输出值:
R 1 ( j , s ) = x x ( j ) < = s R_1(j,s)={x|x^{(j) }<= s} R 2 ( j , s ) = x x ( j ) > s R_2(j,s)={x|x^{(j) }> s}
C m = ( x i R m ( j , s ) y i ) C_m =(\displaystyle\sum_{x_i∈R_m(j,s) }y_i) / N m N_m --------m = 1.2
3)继续对两个子区域调用步骤1)2),直到满足停止条件。
4将输入空间划分为M个区域 R 1 , R 2 R M R_1,R_2 …… R_M ,生成决策树
f ( x ) = m = 1 M c m I ( x R m ) f(x)=\displaystyle\sum_{m=1}^{M}c_mI(x∈R_m)

还需要解决一下几个问题:
1)如何计算区域上的平方误差,下面给出python代码:

import numpy as np
def square_error(dataset):
	data = np.mat(dataset)
	return np.var(data[:,-1]) * np.shape(data)[0]
  1. 左右子树的划分
根据特征fea中的值value,将数据集data划分成左右子树
def split_tree(data,fea,value):
set_1 =[]
set_2=[]
for x in data:
	if x[fea] >= value:
		set_1.append(x)
	else:
		set_2.append(x)
return (set_1,set_2)
  1. CART回归树的构建:
class node :
	def __init__(self,feat=-1,value=None,result=None,right =None,left=None):
		self.feat = feat # 用于切分数据集的属性的列索引值
		self.value = value#设置划分的值
		self.result = result#存储叶子结点的值
		self.right =right
		self.left = left
def bulid_Tree(data,min_sample,min_error):
   # 构建决策树,返回该决策树的根节点
	if len(data) <= min_sample:
		return node(results = leaf(data))
		#初始化
		best_err=square_error(data)
		bestCriteria = None #存储最佳切分属性和切分点
		bestSets=None# 存储切分后的2个数据集
		#开始构建CART回归树
		feature_num = len(data[0])-1
		for fea in range(0,feature_num):
			feature_values={}
			for sample in data:
				feature_values[sample[fea]]=1
			for value in feature_values.keys():
				(set_1,set_2)=split_Tree(data,fea,value)
				if len(set_1)< 2 or len(set_2)<2:
					continue
				now_err = square_error(set_1)+square_error(set_2)
				if now_err < best_err and len(set_1) > 0 and len(set_2)>0:
					best_err = now_err
					bestCriteria = (fea,value)
					bestSets = (set_1,set_2)
		# 判断划分是否结束
		if best_err > min_err:
			right = bulid_Tree(bestSets[0],min_sample,min_err)
			left = bulid_Tree(bestSets[1],min_sample,min_err)
			return node(fea=bestCriteria[0],value = bestCriteria[1],right = right,left=left]
		else:
			return node(results=leaf(data))
# 计算该区域中所有样本的标签的均值
def leaf(data):
	data = np.mat(datSet)
	return np.mean(data[:,-1]
	

猜你喜欢

转载自blog.csdn.net/qq_16608563/article/details/82856947
今日推荐