17- 梯度提升回归树GBRT (集成算法) (算法)

news2024/11/25 23:11:57

梯度提升回归树:

  • 梯度提升回归树是区别于随机森林的另一种集成方法,它的特点在于纠正与加强,通过合并多个决策树来构建一个更为强大的模型。
  • 该模型即可以用于分类问题,也可以用于回归问题中。
  • 在该模型中,有三个重要参数分别为 n_estimators(子树数量)、learning_rate(学习率)、max_depth(最大深度)。
    • n_estimators  子树数量:  通常用来设置纠正错误的子树数量,梯度提升树通常使用深度很小(1到 5之间)的子树,即强预剪枝,来进行构造强化树。并且这样占用的内存也更少,预测速度也更快。
    • learning_rate  学习率:  通常用来控制每颗树纠正前一棵树的强度。较高的学习率意味着每颗树都可以做出较强的修正,这样的模型普遍更复杂。
    • max_depth  最大深度:  通常用于降低每颗树的复杂度,从而避免深度过大造成过拟合的现象。梯度提升模型的 max_depth 通常都设置得很小,一般来讲不超过5
  • 梯度提升决策树是监督学习 最强大也是最常用 的模型之一。

  • 该算法无需对数据进行缩放就可以表现得很好,而且也适用于二元特征与连续特征同时存在的数据集。

  • 缺点是需要进行仔细调参,且训练时间可能较长,通常不适用于高维稀疏数据

单一KNN算法:         # knn近邻算法: K-近邻算法(KNN)

from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier()
knn.fit(X_train,y_train)

KNN集成算法

from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import BaggingClassifier
# 100个算法,集成算法,准确提升到了73.3%
knn = KNeighborsClassifier()
# bag中100个knn算法
bag_knn = BaggingClassifier(base_estimator=knn, n_estimators=100, max_samples=0.8,
                            max_features=0.7)
bag_knn.fit(X_train,y_train)
print('KNN集成算法,得分是:', bag_knn.score(X_test,y_test))

逻辑斯蒂回归集成算法:

from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import BaggingClassifier
bag = BaggingClassifier(base_estimator=LogisticRegression(),n_estimators=500,
                        max_samples=0.8, max_features=0.5)
bag.fit(X_train,y_train)

决策树集成算法:

from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import BaggingClassifier
bag = BaggingClassifier(base_estimator=DecisionTreeClassifier(),n_estimators=100,
                        max_samples=1.0,max_features=0.5)
bag.fit(X_train,y_train)

梯度提升回归算法:

from sklearn.ensemble import GradientBoostingRegressor
gbdt = GradientBoostingRegressor(n_estimators=3,loss = 'ls', # 最小二乘法
                                 learning_rate=0.1)
gbdt.fit(X,y)    # 训练


1、集成算法

1.1、不同集成算法

集成算法流程概述

 同质学习器(也叫算法,model,模型)

  • 随机森林,同质学习器,内部的100个模型,都是决策树

  • bagging:套袋法

    • 随机森林

    • 极端森林

  • boosting:提升法

    • GBDT

    • AdaBoost

1.2、bagging

1.3、自建集成算法(同质)

1、导包数据创建

import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
X,y = datasets.load_wine(return_X_y = True)
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state = 1024)

2、KNN集成算法

算法原理:

# 一个算法,准确率 62%
knn = KNeighborsClassifier()
knn.fit(X_train,y_train)
print('单一KNN算法,得分是:',knn.score(X_test,y_test))   # 0.6222222222222222

# 100个算法,集成算法,准确提升到了73.3%
knn = KNeighborsClassifier()
# bag中100个knn算法
bag_knn = BaggingClassifier(base_estimator=knn,n_estimators=100,max_samples=0.8,
                            max_features=0.7)
bag_knn.fit(X_train,y_train)
print('KNN集成算法,得分是:',bag_knn.score(X_test,y_test))  # 0.7555555555555555 

3、逻辑斯蒂回归集成算法

import warnings
warnings.filterwarnings('ignore')
lr = LogisticRegression()
lr.fit(X_train,y_train)
print('单一逻辑斯蒂算法,得分是:',lr.score(X_test,y_test))   # 0.9333333333333333

# 偶尔效果会好
bag = BaggingClassifier(base_estimator=LogisticRegression(),n_estimators=500,
                        max_samples=0.8, max_features=0.5)
bag.fit(X_train,y_train)
print('逻辑斯蒂集成算法,得分是:', bag.score(X_test,y_test)) # 0.9333333333333333

4、决策树自建集成算法

clf = DecisionTreeClassifier()
clf.fit(X_train,y_train)
print('单棵决策树,得分是:',clf.score(X_test,y_test))  # 0.9555555555555556
bag = BaggingClassifier(base_estimator=DecisionTreeClassifier(),n_estimators=100,
                        max_samples=1.0,max_features=0.5)
bag.fit(X_train,y_train)
print('决策树集成算法,得分是:',bag.score(X_test,y_test))  # 0.9777777777777777

1.4、boosting

2、GBDT

2.1、梯度提升树概述

  • gradient Boosting DecisionTree  一一> GBDT

  • Boosting :提升的,一点点靠近最优答案

  • 残差

    • 残差的意思就是: A的预测值 + A的残差 = A的实际值

    • 残差 = 实际值 - 预测值

    • 预测值 = 实际值 - 残差

2.2、梯度提升树应用

1、使用全量数据构建梯度提升树(0.1434)

from sklearn.ensemble import GradientBoostingRegressor
import numpy as np
import pandas as pd 

# 加载数据
data_train = pd.read_csv('zhengqi_train.txt', sep='\t')
data_test = pd.read_csv('zhengqi_test.txt', sep='\t')
X_train = data_train.iloc[:,:-1]
y_train = data_train['target']
X_test = data_test

# GBDT模型训练预测
gbdt = GradientBoostingRegressor()
gbdt.fit(X_train,y_train)
y_pred = gbdt.predict(X_test)
np.savetxt('GBDT_full_feature_result.txt', y_pred)

2、使用部分数据构建梯度提升树(0.1486)

from sklearn.linear_model import ElasticNet
from sklearn.ensemble import GradientBoostingRegressor
import numpy as np
import pandas as pd 

# 加载数据
data_train = pd.read_csv('zhengqi_train.txt', sep='\t')
data_test = pd.read_csv('zhengqi_test.txt', sep='\t')
X_train = data_train.iloc[:,:-1]
y_train = data_train['target']
X_test = data_test

# 先使用ElaticNet模型进行数据筛选
model = ElasticNet(alpha = 0.1, l1_ratio=0.05)
model.fit(X_train, y_train)
cond = model.coef_ != 0
X_train = X_train.iloc[:,cond]
X_test = X_test.iloc[:,cond]
print('删除数据后,形状是:',X_train.shape)

# GBDT模型训练预测
gbdt = GradientBoostingRegressor()
gbdt.fit(X_train,y_train)
y_pred = gbdt.predict(X_test)
np.savetxt('GBDT_drop_feature_result.txt', y_pred)

2.3、梯度提升树原理

1、创建数据并使用梯度提升回归树进行预测

import numpy as np
from sklearn.ensemble import GradientBoostingRegressor
import matplotlib.pyplot as plt
from sklearn import tree
import graphviz

### 实际问题,年龄预测,回归问题
# 简单的数据,算法原理,无论简单数据,还是复杂数据,都一样
# 属性一表示花销,属性二表示上网时间
X = np.array([[600,0.8],[800,1.2],[1500,10],[2500,3]])
y = np.array([14,16,24,26]) # 高一、高三,大四,工作两年
# loss  = ls 最小二乘法
learning_rate = 0.1
gbdt = GradientBoostingRegressor(n_estimators=3,loss = 'ls',# 最小二乘法
                                 learning_rate=0.1)#learning_rate 学习率
gbdt.fit(X,y)#训练
y_ = gbdt.predict(X) # 预测

2、计算残差

# 目标值,真实值,算法,希望,预测,越接近真实,模型越好!!!
print(y)
# 求平均,这个平均值就是算法第一次预测的基准,初始值
print(y.mean())
# 残差:真实值,和预测值之间的差
residual = y - y.mean()
residual
# 残差,越小越好
# 如果残差是0,算法完全准确的把数值预测出来!

3、绘制三棵树

  • 第一棵树

# 第一颗树,分叉时,friedman-mse (就是均方误差)= 26
print('均方误差:',((y - y.mean())**2).mean())
dot_data = tree.export_graphviz(gbdt[0,0],filled=True)
graph = graphviz.Source(dot_data)

# 梯度下降,降低残差
residual = residual - learning_rate*residual
residual
# 输出:array([-5.4, -3.6,  3.6,  5.4])
  • 第二棵树
# 第二颗树
dot_data = tree.export_graphviz(gbdt[1,0],filled=True)
graph = graphviz.Source(dot_data)

# 梯度下降,降低残差
residual = residual - learning_rate*residual
residual
# 输出:array([-4.86, -3.24,  3.24,  4.86])
  • 第三棵树
# 第三颗树
dot_data = tree.export_graphviz(gbdt[2,0],filled=True)
graph = graphviz.Source(dot_data)
# 梯度下降,降低残差
residual = residual - learning_rate*residual
residual
# 输出:array([-4.374, -2.916,  2.916,  4.374])

4、使用残差计算最终结果

# 使用残差一步步,计算的结果
y_ = y - residual
print('使用残差一步步计算,最终结果是:\n',y_)
# 使用算法,预测
gbdt.predict(X)
# 两者输出结果一样

2.4、梯度提升回归树的最佳裂分条件计算

1、第一棵树,分裂情况如下:

# 计算未分裂均方误差
lower_mse = ((y - y.mean())**2).mean()
print('未分裂均方误差是:',lower_mse)
best_split = {}
for index in range(2):
    for i in range(3):
        t = X[:,index].copy()
        t.sort()
        split = t[i:i + 2].mean()
        cond = X[:,index] <= split
        mse1 = round(((y[cond] - y[cond].mean())**2).mean(),3)
        mse2 = round(((y[~cond] - y[~cond].mean())**2).mean(),3)
        p1 = cond.sum()/cond.size
        mse = round(mse1 * p1 + mse2 * (1- p1),3)
        print('第%d列' % (index),'裂分条件是:',split,'均方误差是:',mse1,mse2,mse)
        if mse < lower_mse:
            best_split.clear()
            lower_mse = mse
            best_split['第%d列'%(index)] = split
        elif mse == lower_mse:
            best_split['第%d列'%(index)] = split
print('最佳分裂条件是:',best_split)
# 输出:
'''
未分裂均方误差是: 26.0
第0列 裂分条件是: 700.0 均方误差是: 0.0 18.667 14.0
第0列 裂分条件是: 1150.0 均方误差是: 1.0 1.0 1.0
第0列 裂分条件是: 2000.0 均方误差是: 18.667 0.0 14.0
第1列 裂分条件是: 1.0 均方误差是: 0.0 18.667 14.0
第1列 裂分条件是: 2.1 均方误差是: 1.0 1.0 1.0
第1列 裂分条件是: 6.5 均方误差是: 27.556 0.0 20.667
最佳分裂条件是: {'第0列': 1150.0, '第1列': 2.1}
'''

2、第二棵树,分裂情况如下:

# 梯度下降,降低残差
residual = residual - learning_rate*residual
# 计算未分裂均方误差
lower_mse = round(((residual - residual.mean())**2).mean(),3)
print('未分裂均方误差是:',lower_mse)
best_split = {}
for index in range(2):
    for i in range(3):
        t = X[:,index].copy()
        t.sort()
        split = t[i:i + 2].mean()
        cond = X[:,index] <= split
        mse1 = round(((residual[cond] - residual[cond].mean())**2).mean(),3)
        mse2 = round(((residual[~cond] - residual[~cond].mean())**2).mean(),3)
        p1 = cond.sum()/cond.size
        mse = round(mse1 * p1 + mse2 * (1- p1),3)
        print('第%d列' % (index),'裂分条件是:',split,'均方误差是:',mse1,mse2,mse)
        if mse < lower_mse:
            best_split.clear()
            lower_mse = mse
            best_split['第%d列'%(index)] = split
        elif mse == lower_mse:
            best_split['第%d列'%(index)] = split
print('最佳分裂条件是:',best_split)
# 输出
'''
未分裂均方误差是: 21.06
第0列 裂分条件是: 700.0 均方误差是: 0.0 15.12 11.34
第0列 裂分条件是: 1150.0 均方误差是: 0.81 0.81 0.81
第0列 裂分条件是: 2000.0 均方误差是: 15.12 0.0 11.34
第1列 裂分条件是: 1.0 均方误差是: 0.0 15.12 11.34
第1列 裂分条件是: 2.1 均方误差是: 0.81 0.81 0.81
第1列 裂分条件是: 6.5 均方误差是: 22.32 0.0 16.74
最佳分裂条件是: {'第0列': 1150.0, '第1列': 2.1}
'''

3、第三棵树,分裂情况如下:

# 梯度下降,降低残差
residual = residual - learning_rate*residual
# 计算未分裂均方误差
lower_mse = round(((residual - residual.mean())**2).mean(),3)
print('未分裂均方误差是:',lower_mse)
best_split = {}
for index in range(2):
    for i in range(3):
        t = X[:,index].copy()
        t.sort()
        split = t[i:i + 2].mean()
        cond = X[:,index] <= split
        mse1 = round(((residual[cond] - residual[cond].mean())**2).mean(),3)
        mse2 = round(((residual[~cond] - residual[~cond].mean())**2).mean(),3)
        p1 = cond.sum()/cond.size
        mse = round(mse1 * p1 + mse2 * (1- p1),3)
        print('第%d列' % (index),'裂分条件是:',split,'均方误差是:',mse1,mse2,mse)
        if mse < lower_mse:
            best_split.clear()
            lower_mse = mse
            best_split['第%d列'%(index)] = split
        elif mse == lower_mse:
            best_split['第%d列'%(index)] = split
print('最佳分裂条件是:',best_split)
# 输出
'''
未分裂均方误差是: 17.059
第0列 裂分条件是: 700.0 均方误差是: 0.0 12.247 9.185
第0列 裂分条件是: 1150.0 均方误差是: 0.656 0.656 0.656
第0列 裂分条件是: 2000.0 均方误差是: 12.247 0.0 9.185
第1列 裂分条件是: 1.0 均方误差是: 0.0 12.247 9.185
第1列 裂分条件是: 2.1 均方误差是: 0.656 0.656 0.656
第1列 裂分条件是: 6.5 均方误差是: 18.079 0.0 13.559
最佳分裂条件是: {'第0列': 1150.0, '第1列': 2.1}
'''

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/345999.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

海盗峡湾——NFT 作品集来袭!

陌生人们&#xff0c;通过这个作品集&#xff0c;可以让你沉浸在海盗们的文化和魔法中。这可能是你唯一的机会&#xff0c;用这些资产把你的土地变成海盗王国&#xff0c;所以不要犹豫了&#xff01; 这个由 Alina Siniakova 制作的系列于 2 月 3 日晚上 11 点在 The Sandbox 市…

倒带ChunJun,同心前行|2022年度回顾2023年共建规划

ChunJun是一个开始于2018年的批流一体数据集成框架项目&#xff0c;原名FlinkX。2022年2月22日&#xff0c;在FlinkX进行初版开源的整整四年后&#xff0c;技术团队决定对FlinkX进行整体升级&#xff0c;并更名为ChunJun&#xff0c;希望为大家真正提供一个稳定、高效、易用的批…

服务器常见的网络攻击以及防御方法

网络安全威胁类别 网络内部的威胁&#xff0c;网络的滥用&#xff0c;没有安全意识的员工&#xff0c;黑客&#xff0c;骇客。 木马攻击原理 C/S 架构&#xff0c;服务器端被植入目标主机&#xff0c;服务器端通过反弹连接和客户端连接。从而客户端对其进行控制。 病毒 一…

蓝桥杯C/C++VIP试题每日一练之报时助手

💛作者主页:静Yu 🧡简介:CSDN全栈优质创作者、华为云享专家、阿里云社区博客专家,前端知识交流社区创建者 💛社区地址:前端知识交流社区 🧡博主的个人博客:静Yu的个人博客 🧡博主的个人笔记本:前端面试题 个人笔记本只记录前端领域的面试题目,项目总结,面试技…

Nacos——Nacos简介以及Nacos Server安装

资料来源&#xff1a;02-Nacos配置管理-什么是配置中心_哔哩哔哩_bilibili nacos记得下载2.x版本的&#xff0c;负责以后新建配置的时候会出现“发布错误&#xff0c;请检查参数是否正确”错误&#xff01;&#xff01;&#xff01;&#xff01; 目录 一、Nacos简介 1.1 四…

【CS224W】(task4)图嵌入表示学习

note node2vec&#xff1a; 计算随机游走概率从节点uuu开始模拟rrr条长度为lll的游走链路使用 Stochastic Gradient Descent 优化损失函数 Node2vec在节点分类方面表现更好&#xff1b;而其他方法在链路预测上效果更好&#xff0c;如random walk效率更高&#xff1b;graph emb…

请注意,PDF正在传播恶意软件

据Bleeping Computer消息&#xff0c;安全研究人员发现了一种新型的恶意软件传播活动&#xff0c;攻击者通过使用PDF附件夹带恶意的Word文档&#xff0c;从而使用户感染恶意软件。 类似的恶意软件传播方式在以往可不多见。在大多数人的印象中&#xff0c;电子邮件是夹带加载了恶…

Redis-简单动态字符串

Redis中字符串应该是我们使用最多的一种数据类型了&#xff0c;但是有没有想过Redis是如何存储字符串的呢&#xff1f;Redis并没有用C语言传统的字符串(C语言中的字符串一般末尾采用空字符结尾&#xff0c;\0)&#xff0c;而是采用它们自己实现的一种简单动态字符串(SDS)实现的…

若依ruoyi——手把手教你制作自己的管理系统【二、修改样式】

阿里图标一(&#xffe3;︶&#xffe3;*)) 图片白嫖一((*&#xffe3;3&#xffe3;)╭ ********* 专栏略长 爆肝万字 细节狂魔 请准备好一键三连 ********* 运行成功后&#xff1a; idea后台正常先挂着 我习惯用VScode操作 当然如果有两台机子 一个挂后台一个改前端就更好…

java中volatile与synchronized的区别,volatile为什么不能保证原子性

1.volatile与synchronized的区别 2.volatile为什么不能保证原子性 定义&#xff1a; 即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断&#xff0c;要么就都不执行。 原子性是拒绝多线程操作的&#xff0c;不论是多核还是单核&#xff0c;具有原子性的量…

【C/C++】VS2019下C++生成DLL并且成功调用(金针菇般细)

目录 一&#xff0c;生成动态链接库 二&#xff0c;使用动态链接库 一&#xff0c;生成动态链接库 1.打开VS2019&#xff0c;创建新项目&#xff0c;选择 动态链接库(DLL) 模板后进行下一步 2.输入项目名称&#xff0c;其它默认就行(可自行选择)&#xff0c;点击创建 3 工程…

hive开窗函数

hive开窗函数 窗口函数 数据准备 1 jx 20 2 zx 24 3 yx 18 4 wz 10 5 yy 34 6 wy 25create table t (> id int,> name string,> age int> )> row format delimited fields terminated by ; load data inpath /data/data.txt into table t;ROW_NUMBER ROW_N…

网上订餐项目(含后台管理界面)

项目开发环境 项目使用IDEA 2018.3.5进行开发。Maven版本为 3.6.2。Tomcat版本为 8.5.42。数据库为mysql 5.7。JDK版本为1.8_211。项目使用SpringSpringMVCMybits框架。 点餐前台功能 登陆界面如下 登陆后可添加菜品到餐车 餐车里可查看添加的菜品 提交后可查看已派送和未…

Zookeeper配置化中心

zookeeper的基本知识 zookeeper的数据结构:zookeeper提供的命名空间非常类似于标准的文件系统&#xff0c;key-value的形式存储&#xff0c;名称key由/分割的一系列路径元素&#xff0c;zookeeper名称空间中的每个节点都是一个路径标志。 windows下的zookeeper安装&#…

使用Docker快速部署ES单机

所有的操作都是基于Docker来的&#xff0c;没有装Docker的话请参照官方文档安装单机环境部署初始化相关目录mkdir -p /usr/local/elasticsearch/{config,plugins,data}准备配置文件vim /usr/local/elasticsearch/config/elasticsearch.yml将下面的内容粘贴到elasticsearch.yml#…

训练一个中文gpt2模型

前言 这是我的github上的一个介绍&#xff0c;关于如何训练中文版本的gpt2的。链接为: https://github.com/yuanzhoulvpi2017/zero_nlp 介绍 本文&#xff0c;将介绍如何使用中文语料&#xff0c;训练一个gpt2可以使用你自己的数据训练&#xff0c;用来&#xff1a;写新闻、…

linux中top命令分析

TOP命令是 比较常用的性能分析命令&#xff0c;可以看出服务器CPU 、负载、内存、磁盘、IO等数值&#xff0c;接下来就详细解读top命令 top命令 打开服务器终端&#xff0c;直接输入top&#xff0c;top命令中的数据显示的都是当前的实时数据 直接这样输入&#xff0c;回车即…

iptables防火墙屏蔽指定ip的端口

因为需要测试客户端程序与hadoop服务器之间正常通信需要开通的端口, 所以在hadoop各服务器上使用iptables防火墙屏蔽了测试客户端程序的ip和所有端口。然后&#xff0c;根据报错信息提示的端口号来逐步放开直到能正常通信下载文件。 在服务器端屏蔽指定ip访问所有端口 #查看…

UUID的弊端以及雪花算法

目录 一、问题 为什么需要分布式全局唯一ID以及分布式ID的业务需求 ID生成规则部分硬性要求 ID号生成系统的可用性要求 二、一般通用方案 &#xff08;一&#xff09;UUID &#xff08;二&#xff09;数据库自增主键 &#xff08;三&#xff09;Redis生成全局id策略 三…

与AI相遇 | 在ChatGPT中输入“情人节”,我们会得到......?

最近ChatGPT可谓是风靡全球&#xff0c;大家彼此的问候从“你吃饭了吗”变成“你玩ChatGPT了吗”。这款当今最火爆的AI语言模型&#xff0c;是美国人工智能研究实验室OpenAI新推出的一种人工智能技术驱动的自然语言处理工具&#xff0c;使用了Transformer神经网络架构&#xff…