集成学习 | 集成学习思想:Boosting思想 | XGBoost算法、LightGBM算法

目录

  • 一. XGBoost 算法
    • 1. XGBoost 算法流程
    • 2. XGBoost 算法评价
  • 二. LightGBM 算法
    • 2. LightGBM 算法优势

上一篇文章中,我们了解了Boosting思想的两种算法:Adboost和GBDT;其中对于GBDT算法,存在两种改进,即:

  • XGBoost
  • LightGBM

一. XGBoost 算法

XGBoost是GBDT(梯度提升树)的一个改进版本
    能够更快的、更高效率的训练模型
    X代表的就是eXtreme(极致)

	学习器:决策树将这些决策树称为”弱学习器“,这些”弱学习器“共同组成了XGboost算法思想:XGBoost的决策树之间是有先后顺序后一棵决策树的生成会考虑前一棵决策树的预测结果,即:将前一棵决策树的偏差考虑在内,也就是更改y值数据使用:生成每棵决策树使用的是整个数据集

在这里插入图片描述

1. XGBoost 算法流程

  1. 构造初始化常数函数,以及模型跟新
    F 0 ( x ) = f 0 ( x ) = 0 F_{0}(x)=f_{0}(x)=0 F0(x)=f0(x)=0

    F 1 ( x ) = F 0 ( x ) + f 1 ( x ) F_{1}(x)=F_{0}(x)+f_{1}(x) F1(x)=F0(x)+f1(x)

    F 2 ( x ) = F 1 ( x ) + f 2 ( x ) F_{2}(x)=F_{1}(x)+f_{2}(x) F2(x)=F1(x)+f2(x)

    . . . . . . ...... ......

    F 0 ( x ) = F ( k − 1 ) ( x ) + f k ( x ) F_{0}(x)=F_{(k-1)}(x)+f_{k}(x) F0(x)=F(k1)(x)+fk(x)

    我们的目标为:求出函数 f 1 ( x ) f_{1}(x) f1(x) f 2 ( x ) f_{2}(x) f2(x),…, f k ( x ) f_{k}(x) fk(x)

  2. 定义损失函数
    XGBoost算法的损失函数:在GBDT的基础上增加了正则化项,用于限制模型的复杂度
    o b j = ∑ i = 1 n L ( y i , F i ( k ) ( x ) ) + ∑ i = 1 k Ω ( f i ) o b j=\sum_{i=1}^{n} L\left(y_{i}, F_{i}^{(k)}(x)\right)+\sum_{i=1}^{k} \Omega\left(f_{i}\right) obj=i=1nL(yi,Fi(k)(x))+i=1kΩ(fi)

    公式解释:

    o b j 函数 obj函数 obj函数 为构建 k k k棵树的总损失

    预测误差 + 每棵树复杂度的惩罚项

    对于正则化项,我们做出以下公式优化:
    f k ( x ) = w q ( x ) f_{k}(x)=w_{q(x)} fk(x)=wq(x)
    Ω ( f ) = γ T + 1 2 λ ∑ j = 1 T w j 2 \Omega(f)=\gamma T+\frac{1}{2} \lambda \sum_{j=1}^{T} w_{j}^{2} Ω(f)=γT+21λj=1Twj2

    公式解释:
    f k ( x ) f_{k}(x) fk(x)可以表示一棵树

    f 是一棵决策树, f k f_{k} fk是第 k k k棵决策树
    x 是一个样本,丢进 f 函数 f函数 f函数中就需要对该样本进行预测
    q ( x ) q(x) q(x) 表示进入的样本x落在哪个叶子节点中
    w q ( x ) w_{q(x)} wq(x) 是叶子节点 q ( x ) q(x) q(x)的值

    先算在哪个叶子节点上,然后根据该叶子节点的值返回

    Ω ( f ) \Omega(f) Ω(f)可以表示一棵树的复杂程度

    T 表示这棵决策树叶子节点的数量:叶子节点越多,决策树越复杂
    w j 2 w_{j}^{2} wj2 表示所有叶子节点值的平方和

    w w w为叶子节点的值
    由于每个弱学习器拟合的都是残差,所以 w w w不能太大
    如果模型企图去拟合离群点,那么 w w w就会变大

    此时,目标函数可以写为
    L k = ∑ i = 1 n L [ y i , F k − 1 ( x ) + f k ( x i ) ] + ∑ j = 1 K Ω ( f j ) L^{k}=\sum_{i=1}^{n} L\left[y_{i}, F_{k-1}(x)+f_{k}\left(x_{i}\right)\right]+\sum_{j=1}^{K} \Omega\left(f_{j}\right) Lk=i=1nL[yi,Fk1(x)+fk(xi)]+j=1KΩ(fj)

    公式推导:

    L k L^{k} Lk

    = ∑ i = 1 n L [ y i , F k − 1 ( x ) + f k ( x i ) ] + ∑ j = 1 K Ω ( f j ) =\sum_{i=1}^{n} L\left[y_{i}, F_{k-1}(x)+f_{k}\left(x_{i}\right)\right]+\sum_{j=1}^{K} \Omega\left(f_{j}\right) =i=1nL[yi,Fk1(x)+fk(xi)]+j=1KΩ(fj)

    = ∑ i = 1 n L [ y i , F k − 1 ( x ) + f k ( x i ) ] + ∑ j = 1 k − 1 Ω ( f j ) + Ω ( f k ) =\sum_{i=1}^{n} L\left[y_{i}, F_{k-1}(x)+f_{k}\left(x_{i}\right)\right]+\sum_{j=1}^{k-1} \Omega\left(f_{j}\right)+\Omega\left(f_{k}\right) =i=1nL[yi,Fk1(x)+fk(xi)]+j=1k1Ω(fj)+Ω(fk)

    = ∑ i = 1 n L [ y i , F k − 1 ( x ) + f k ( x i ) ] + Ω ( f k ) =\sum_{i=1}^{n} L\left[y_{i}, F_{k-1}(x)+f_{k}\left(x_{i}\right)\right]+\Omega\left(f_{k}\right) =i=1nL[yi,Fk1(x)+fk(xi)]+Ω(fk)

即: L k = ∑ i = 1 n L [ y i , F k − 1 ( x ) + f k ( x i ) ] + Ω ( f k ) L^{k}=\sum_{i=1}^{n} L\left[y_{i}, F_{k-1}(x)+f_{k}\left(x_{i}\right)\right]+\Omega\left(f_{k}\right) Lk=i=1nL[yi,Fk1(x)+fk(xi)]+Ω(fk)
3. 二阶展开

一元函数在x0点的泰勒展式:
f ( x ) = f ( x 0 ) + f ′ ( x 0 ) ( x − x 0 ) + f ′ ′ ( x 0 ) 2 ! ( x − x 0 ) 2 + … + f ( n ) ( x 0 ) n ! ( x − x 0 ) n + … f(x)=f\left(x_{0}\right)+f^{\prime}\left(x_{0}\right)\left(x-x_{0}\right)+\frac{f^{\prime \prime}\left(x_{0}\right)}{2 !}\left(x-x_{0}\right)^{2}+\ldots+\frac{f^{(n)}\left(x_{0}\right)}{n !}\left(x-x_{0}\right)^{n}+\ldots f(x)=f(x0)+f(x0)(xx0)+2!f′′(x0)(xx0)2++n!f(n)(x0)(xx0)n+
注意:我们只求至二阶导即可
所以,对于 L [ y i , F k − 1 ( x ) + f k ( x i ) ] L\left[y_{i}, F_{k-1}(x)+f_{k}\left(x_{i}\right)\right] L[yi,Fk1(x)+fk(xi)],可以写为:

L [ y i , F k − 1 ( x ) + f k ( x i ) ] L\left[y_{i}, F_{k-1}(x)+f_{k}\left(x_{i}\right)\right] L[yi,Fk1(x)+fk(xi)]

= L [ y i , F k − 1 ( x ) ] + ∂ F k − 1 L [ y i , F k − 1 ( x ) ] f k ( x i ) + 1 2 ∂ F k − 1 2 L [ y i , F k − 1 ( x ) ] f k 2 ( x i ) =L[y_{i}, F_{k-1}(x)]+\partial_{F_{k-1}}L[y_{i}, F_{k-1}(x)] f_{k}\left(x_{i}\right)+\frac{1}{2} \partial_{F_{k-1}}^{2}L[y_{i}, F_{k-1}(x)] f_{k}^{2}\left(x_{i}\right) =L[yi,Fk1(x)]+Fk1L[yi,Fk1(x)]fk(xi)+21Fk12L[yi,Fk1(x)]fk2(xi)

其中:
g i = ∂ F k − 1 L [ y i , F k − 1 ( x ) ] ,即 L 关于 x 0 的一阶导 g_{i}=\partial_{F_{k-1}}L[y_{i}, F_{k-1}(x)],即L关于x_{0}的一阶导 gi=Fk1L[yi,Fk1(x)],即L关于x0的一阶导
h i = ∂ F k − 1 2 L [ y i , F k − 1 ( x ) ] ,即 L 关于 x 0 的二阶导 h_{i}= \partial_{F_{k-1}}^{2}L[y_{i}, F_{k-1}(x)] ,即L关于x_{0}的二阶导 hi=Fk12L[yi,Fk1(x)],即L关于x0的二阶导

对于 L [ y i , F k − 1 ( x ) + f k ( x i ) ] L\left[y_{i}, F_{k-1}(x)+f_{k}\left(x_{i}\right)\right] L[yi,Fk1(x)+fk(xi)]

x = F k − 1 ( x ) + f k ( x i ) x = F_{k-1}(x)+f_{k}\left(x_{i}\right) x=Fk1(x)+fk(xi)

x 0 = F k − 1 ( x ) x_{0}= F_{k-1}(x) x0=Fk1(x)

x − x 0 = f k ( x i ) x-x_{0} = f_{k}(x_{i}) xx0=fk(xi)

i为样本,所以 g i , h i g_{i},h_{i} gihi是可以计算得到的
也就是说, L [ y i , F k − 1 ( x ) ] L[y_{i}, F_{k-1}(x)] L[yi,Fk1(x)]为常数

即,为了求下一棵树,我需要求每个样本的一阶导,二阶导

因此,我们可以得到:
L [ y i , F k − 1 ( x ) + f k ( x i ) ] = L [ y i , F k − 1 ( x ) ] + g i ∗ f k ( x i ) + 1 2 h i ∗ f k 2 ( x i ) L\left[y_{i}, F_{k-1}(x)+f_{k}\left(x_{i}\right)\right]=L[y_{i}, F_{k-1}(x)]+g_{i} * f_{k}\left(x_{i}\right)+\frac{1}{2} h_{i} * f_{k}^{2}\left(x_{i}\right) L[yi,Fk1(x)+fk(xi)]=L[yi,Fk1(x)]+gifk(xi)+21hifk2(xi)
因为 L [ y i , F k − 1 ( x ) ] L[y_{i}, F_{k-1}(x)] L[yi,Fk1(x)]为常数,所以对于每个样本,可以得到:
L k = ∑ i = 1 n g i ∗ f k ( x i ) + 1 2 h i ∗ f k 2 ( x i ) L^{k}=\sum_{i=1}^{n}g_{i} * f_{k}\left(x_{i}\right)+\frac{1}{2} h_{i} * f_{k}^{2}\left(x_{i}\right) Lk=i=1ngifk(xi)+21hifk2(xi)
L k = ∑ i = 1 n ( g i ∗ w q ( x i ) + 1 2 h i ∗ w q ( x i ) 2 ) + γ T + 1 2 λ ∑ j = 1 T w j 2 L^{k}=\sum_{i=1}^{n}\left(g_{i} * w_{q\left(x_{i}\right)}+\frac{1}{2} h_{i} * w_{q\left(x_{i}\right)}^{2}\right)+\gamma T+\frac{1}{2} \lambda \sum_{j=1}^{T} w_{j}^{2} Lk=i=1n(giwq(xi)+21hiwq(xi)2)+γT+21λj=1Twj2

我们认为,对于n个样本,最终会落到T个叶子节点上去
也就是说,对于某一个叶子节点:

g a + g b + g c + . . . . = G j g_{a}+g_{b}+g_{c}+.... = G_{j} ga+gb+gc+....=Gj

同理,也可得到 H j H_{j} Hj

将公式转换为对于每个每个叶子节点求和,我们就可以得到:
L k = ∑ j = 1 T ( G j ∗ w j + 1 2 H j ∗ w j 2 ) + γ T + 1 2 λ ∑ j = 1 T w j 2 L^{k}=\sum_{j=1}^{T}\left(G_{j} * w_{j}+\frac{1}{2} H_{j} * w_{j}^{2}\right)+\gamma T+\frac{1}{2} \lambda \sum_{j=1}^{T} w_{j}^{2} Lk=j=1T(Gjwj+21Hjwj2)+γT+21λj=1Twj2
合并后,最终得到的损失函数为:
L k = ∑ j = 1 T ( G j ∗ w j + 1 2 ( H j + λ ) ∗ w j 2 ) + γ T L^{k}=\sum_{j=1}^{T}\left(G_{j} * w_{j}+\frac{1}{2}\left(H_{j}+\lambda\right) * w_{j}^{2}\right)+\gamma T Lk=j=1T(Gjwj+21(Hj+λ)wj2)+γT

  1. 为了使损失函数最小,需要损失函数对于 w j w_{j} wj 求导,并令导数为0,求得最优的w:

     	注意:此时树的结构是确定的,即q函数确定
    

w j ∗ = − G j H j + λ w_{j}^{*}=-\frac{G_{j}}{H_{j}+\lambda} wj=Hj+λGj
即:每个叶子节点值为 w j ∗ w_{j}^{*} wj时,模型最佳

w w w带入,得到最小损失为:
L min ⁡ k = − 1 2 ∑ j = 1 T G j 2 H j + λ + γ T L_{\min }^{k}=-\frac{1}{2} \sum_{j=1}^{T} \frac{G_{j}^{2}}{H_{j}+\lambda}+\gamma T Lmink=21j=1THj+λGj2+γT

  1. 计算增益

上面,我们在树结构确定时,算出来最小损失
那么,我们现在的问题是:怎么确定树的结构?

对于一次节点分裂,显然损失下降越多,分裂节点越佳

这里我们解释 ∑ j = 1 T G j \sum_{j=1}^{T}G_{j} j=1TGj
假设数据集中共存在10个样本: g 1 , g 2 , . . . , g 10 g_{1},g_{2},...,g_{10} g1g2...g10

将样本1-5落在R叶子节点内
将样本6-10落在L叶子节点内

因此我们可以得到 ∑ j = 1 T G j = G R + G L \sum_{j=1}^{T}G_{j}=G_{R}+G_{L} j=1TGj=GR+GL
同理,可以得到 H R , H L H_{R},H_{L} HRHL

对于分裂前,我们有:
loss  before  = − 1 2 ( G L + G R ) 2 ( H L + H R ) + λ + γ \text { loss }_{\text {before }}=-\frac{1}{2} \frac{\left(G_{L}+G_{R}\right)^{2}}{\left(H_{L}+H_{R}\right)+\lambda}+\gamma  loss before =21(HL+HR)+λ(GL+GR)2+γ
对于分裂后,我们有:
loss  a f t e r = − [ 1 2 G L 2 H L + λ + γ ] − [ 1 2 G R 2 H R + λ + γ ] = − 1 2 ( G L 2 H L + λ + G R 2 H R + λ ) + 2 γ \text { loss }_{a f t e r}=-[\frac{1}{2} \frac{G_{L}^{2}}{H_{L}+\lambda } +\gamma] -[\frac{1}{2} \frac{G_{R}^{2}}{H_{R}+\lambda } +\gamma] =-\frac{1}{2}\left(\frac{G_{L}^{2}}{H_{L}+\lambda}+\frac{G_{R}^{2}}{H_{R}+\lambda}\right)+2 \gamma  loss after=[21HL+λGL2+γ][21HR+λGR2+γ]=21(HL+λGL2+HR+λGR2)+2γ

因此,信息增益为:

计算所有候选分裂点对应的gain
选择gain最大的分裂点进行分裂
如果一个节点的所有候选分裂点都不能带来gain,则该节点不分裂

g a i n = 1 2 ( G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 ( H L + H R ) + λ ) − γ gain=\frac{1}{2}\left(\frac{G_{L}^{2}}{H_{L}+\lambda}+\frac{G_{R}^{2}}{H_{R}+\lambda}-\frac{\left(G_{L}+G_{R}\right)^{2}}{\left(H_{L}+H_{R}\right)+\lambda}\right)-\gamma gain=21(HL+λGL2+HR+λGR2(HL+HR)+λ(GL+GR)2)γ

2. XGBoost 算法评价

  • 与决策树不同,XGBoost并不直接使用基尼系数或信息增益这些指标来进行特征选择或分裂点选择,而是计算每个特征的分裂增益(Gain)来选择最佳的最佳的特征和分裂点,从而构建更准确的树模型
  • 分裂增益表示在分裂前后损失函数的减少程度

在计算分裂增益时,有两种方式:

  1. 精确算法:遍历所有特征的所有可能的分裂点,计算gain值,选择最大的 gain值对应的分裂点进行分裂
    如:上述公式推导部分

  2. 近似算法:对于每个特征,只考虑分位点,减少计算复杂度

    	分位点:按照上一轮的预测误差函数的二阶导数值作为权重进行划分
    

在这里插入图片描述

二. LightGBM 算法

LightGBM是由微软开发的boosting集成模型,类似于XGBoost,对GBDT进行了优化和高效实现,原理有一些相似之处;但它的主要优势在于能够处理大规模数据

	在实验中:LightGBM 比 XGBoost 快将近10倍内存占用率大约为XGBoost的1/6

2. LightGBM 算法优势

	GBDT 在每一次迭代的时候,都需要遍历整个训练数据多次如果把整个训练数据一次性装进内存,会明显限制训练数据的大小如果不装进内存,反复地读写训练数据又会消耗非常大的时间。

面对大规模工业级数据,传统的GBDT算法无法满足需求。LightGBM的主要目的之一是解决上述大数据量级下的GBDT训练问题,以便在工业实践中支持大规模数据并保证效率

	算法思想:LightGBM提出直方图算法:为了减少分裂点的数量

直方图就是把连续的浮点特征离散化为k个整数(也就是分桶bins的思想),比如:

[ 0 , 0.1 ] = > 0 [0,0.1] =>0 [0,0.1]=>0
[ 0.1 , 0.3 ] = > 1 [0.1,0.3] => 1 [0.1,0.3]=>1

这里的思想类似XGBoost的分位点

在这里插入图片描述


感谢阅读🌼
如果喜欢这篇文章,记得点赞👍和转发🔄哦!
有任何想法或问题,欢迎留言交流💬,我们下次见!
本文相关代码存放位置
    【Boosting思想 扩展算法 代码实现

祝愉快🌟!


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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

外包干了20天,技术退步明显.......

先说一下自己的情况,大专生,21年通过校招进入杭州某软件公司,干了接近2年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了2年的功能测试…

1分钟带你学会使用Python操作 xlsx 文件绘制面积图

​我们工作中经常要处理海量的数据,如果没有一个直观的可视化工具,怎么可能一眼就看出数据背后的故事呢?数据可视化显得越来越重要,数据分析已经成了现代人必备的技能。 今天来和大家分享一个超有趣的数据可视化方法——绘制面积…

Redis中文乱码问题

最近排查问题,发现之前的开发将日志写在redis缓存中(不建议这样做),我在查看日志的时候发现没办法阅读,详细是这样的: 查阅资料后发现是进制问题,解决方法是启动客户端的时候将redis-cli改为red…

流畅的 Python 第二版(GPT 重译)(四)

第二部分:函数作为对象 第七章:函数作为一等对象 我从未认为 Python 受到函数式语言的重大影响,无论人们说什么或想什么。我更熟悉命令式语言,如 C 和 Algol 68,尽管我将函数作为一等对象,但我并不认为 Py…

【机器学习】机器学习是什么?

文章目录 前言 机器学习 序列学习和对抗学习有什么不同 总结 前言 在当今快速发展的科技时代,人工智能已经成为推动社会进步的重要力量。机器学习,作为人工智能领域的一个重要分支,它的核心能力在于使计算机系统能够从数据中学习规律&…

Python RPA简单开发实践(selenium登陆浏览器自动输入密码登陆)

打开csdn博客,简单版 class BS:def __init__(self, url):self.url url# self.password password# self.username usernamedef login_url(self):from selenium import webdriver# 不自动关闭浏览器option webdriver.ChromeOptions()option.add_experimental_opt…

Vue 若依框架 form-generator添加表格组件和动态表单组件

效果图: 在若依框架自带的流程表单配置基础上添加这两个组件 config.js // 表单属性【右面板】 export const formConf {formRef: elForm,formModel: formData,other: other,size: medium,labelPosition: right,labelWidth: 100,formRules: rules,gutter: 15,dis…

LeetCode每日一题[c++]-322.零钱兑换

题目描述 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。 你可以认为每种硬币的数量是无…

游戏提示steam_api64.dll丢失怎样修复?教你5种快速修复的方法

在计算机系统中,如果未能成功找到或加载steam_api64.dll文件,可能会引发一系列的问题和故障现象。这个特定的DLL文件是Steam平台的核心组件之一,对于运行基于Steam平台的游戏或应用至关重要。当系统提示“找不到steam_api64.dll”时&#xff…

抖音视频关键词爬虫批量采集软件|视频提取下载工具

视频关键词批量采集软件 — 助力您快速获取所需视频 主要功能: 关键词批量提取视频和单独视频提取,提取后下载功能。 功能解析: 1. 关键词批量提取视频的解析 通过输入关键词进行视频搜索和提取。例如,输入“汽车配件”&#x…

N9010B EXA 信号分析仪 10 Hz 至 44 GHz

N9010B EXA 信号分析仪 10 Hz 至 44 GHz 产品综述 <<<<频率范围&#xff1a;10 Hz 至 44 GHz>>> keysight N9010B EXA 信号分析仪&#xff0c;10 Hz 至 44 GHz无论是增强产品性能还是提高测试吞吐量&#xff0c;您的通用型信号分析仪都要有能力满足各…

为什么电商系统一定要跟企业ERP做数据对接?

一篇文章告诉你&#xff0c;为什么电商系统一定要跟企业ERP做数据对接&#xff1f; 在电商日益发展的情况下&#xff0c;每个电商企业的单量越来越大。但是电商系统对于财务来说并不友好&#xff0c;所以企业会另外上一套财务系统方便财务做账和企业内部管理。那如果还是按照之…

后端常问面经之操作系统

请简要描述线程与进程的关系,区别及优缺点&#xff1f; 本质区别&#xff1a;进程是操作系统资源分配的基本单位&#xff0c;而线程是任务调度和执行的基本单位 在开销方面&#xff1a;每个进程都有独立的代码和数据空间&#xff08;程序上下文&#xff09;&#xff0c;程序之…

产品经理面试自我介绍,这3大错误千万别犯!

金三银四求职季&#xff0c;你是不是也有面试的冲动&#xff01;但面试并不是头脑一热就能取得好结果&#xff0c;在此之前&#xff0c;必须得有周全的准备&#xff0c;才能应对好面试官的“连环问”&#xff01; 所以&#xff0c;今天这篇产品经理面试干货分享给大家~ 今天文…

MySQL-1.数据库的基本操作

1. 数据库的基本操作 show databases; information_schema&#xff1a;信息图式&#xff0c;存储服务器管理数据库的信息 mysql&#xff1a;存放系统信息&#xff0c;用户名密码等 performance_schema&#xff1a;性能图式 sys&#xff1a;系统文件 1.1 创建数据库-studen…

流畅的 Python 第二版(GPT 重译)(六)

第三部分&#xff1a;类和协议 第十一章&#xff1a;一个 Python 风格的对象 使库或框架成为 Pythonic 是为了让 Python 程序员尽可能轻松和自然地学会如何执行任务。 Python 和 JavaScript 框架的创造者 Martijn Faassen。 由于 Python 数据模型&#xff0c;您定义的类型可以…

【设计模式】实战篇

目录标题 【实战一】模板方法模式抽象类子类 【实战一】模板方法模式 抽象类 定义一个抽象类&#xff1a;FarmWorkNodeRecord&#xff1a;表示其记录是用来操作计划的节点对象的。 public abstract class FarmWorkNodeRecordService {// 模拟Mapperprivate String plantPlan…

Arduino中的map函数

一、案例 val analogRead(dyPin); //读取模拟口的模拟量数值 dyValuemap(val,0,1023,0,500);//这个函数是将电位器调节的模拟量的值按比例转换成对应的电压量 问题&#xff0c;为什么不是0~499呢&#xff1f; 其实也行↓ 当map(val, 0, 1023, 0, 500)被调用时&#xff0…

关于异业联盟模式做成小程序的可行性分析

随着移动互联网的快速发展&#xff0c;小程序作为一种轻量级应用&#xff0c;受到了越来越多企业和用户的青睐。而异业联盟模式则是一种有效的商业合作方式&#xff0c;能够实现资源共享、优势互补和共同发展。将异业联盟模式做成小程序&#xff0c;不仅可以提高用户体验&#…

[论文笔记] Dual-Channel Span for Aspect Sentiment Triplet Extraction

一种利用句法依赖和词性相关性信息来过滤噪声&#xff08;无关跨度&#xff09;的基于span方法。 会议EMNLP 2023作者Pan Li, Ping Li, Kai Zhang团队Southwest Petroleum University论文地址https://aclanthology.org/2023.emnlp-main.17/代码地址https://github.com/bert-ply…