一、提升树
1.1 提升树概述
待更
1.2 提升树代码实现
为与李航《统计学习方法》第168页例8.2一致,回归树简化为只有一个根节点连接两个叶子结点的结构,因为只有一个特征。
当有多个特征的情况下应该递归生成回归树,但特征的划分方法与下面的代码一致。
import numpy as np
#单棵回归树,回归树本应递归生成,但这里为了与课本一致,简化成只有一个特征,即根节点带两个叶子结点的回归树
def Regression_Tree(Data):
n = len(Data)
points = [(Data[i][0]+Data[i+1][0])/2 for i in range(n-1)]
min_error = float('inf')
min_s = -1
min_c1 = -1
min_c2 = -1
for s in points: #检查每个切分点
R1 = [x[0] for x in Data if x[0] < s] #划分左区间
label_1 = [x[1] for x in Data if x[0] < s]
R2 = [x[0] for x in Data if x[0] > s] #划分右区间
label_2 = [x[1] for x in Data if x[0] > s]
c1 = np.mean(label_1) #左叶子结点取值
c2 = np.mean(label_2) #右叶子结点取值
ms = MSE(c1, label_1) + MSE(c2, label_2) #划分的均方误差
if ms < min_error: #寻找最小均方误差的划分方式
min_error = ms
min_s = s
min_c1 = c1
min_c2 = c2
tree = (min_s,(min_c1,min_c2))
residual = [[x[0], x[1]-Tree_predict(x[0], tree)] for x in Data] #计算残差
return tree, residual #返回当前树以及残差数据
def Boosting_Tree(Data, m):
final_model = []
data = [x[0] for x in Data]
label = [x[1] for x in Data]
for i in range(m): #需要组合多少次回归树
tree, Data = Regression_Tree(Data) #将残差作为下一次输入
final_model.append(tree) #纳入新的回归树
pred = [Boosting_predict(x, final_model) for x in data]
error = MSE(pred, label) #计算当前提升树的平方损失
print('组合{}棵回归树后的提升树平方损失为:{}'.format(i+1,error))
return final_model #返回回归树,这里也可以设置当损失达到多少时停止生成回归树
def MSE(pred,lable):
return sum((np.array(pred)-np.array(lable))**2)
#单棵树预测值
def Tree_predict(x, Tree):
return Tree[1][0] if x < Tree[0] else Tree[1][1]
#提升树预测值
def Boosting_predict(x, model):
#遍历每棵树,增加或减少值
pred = 0
for i in range(len(model)):
tree = model[i]
pred += tree[1][0] if x < tree[0] else tree[1][1]
return pred
if __name__ == '__main__':
label = [5.56, 5.70, 5.91, 6.40, 6.80, 7.05, 8.90, 8.70, 9.00, 9.05]
Data = [[i+1, label[i]] for i in range(10)] #两维[data,label]
Final_boosting_tree = Boosting_Tree(Data,6) #后面的数据设定为生成多少棵回归树
结果:
组合1棵回归树后的提升树平方损失为:1.9300083333333338
组合2棵回归树后的提升树平方损失为:0.8006750000000015
组合3棵回归树后的提升树平方损失为:0.47800833333333437
组合4棵回归树后的提升树平方损失为:0.30555925925926064
组合5棵回归树后的提升树平方损失为:0.2289152263374492
组合6棵回归树后的提升树平方损失为:0.17217806498628285
与李航《统计学习方法》第169-170页结果一致
也可以一直迭代下去,损失会越来越低:
组合12棵回归树后的提升树平方损失为:0.07710099633806546
组合13棵回归树后的提升树平方损失为:0.06961581825503288
组合14棵回归树后的提升树平方损失为:0.06035149269490475
组合15棵回归树后的提升树平方损失为:0.049114857588362024
组合16棵回归树后的提升树平方损失为:0.0459049073710459
组合17棵回归树后的提升树平方损失为:0.040459737736702577
组合18棵回归树后的提升树平方损失为:0.03836252259100614
组合19棵回归树后的提升树平方损失为:0.03221858035110763
组合20棵回归树后的提升树平方损失为:0.028268903196886488