ACL 2019 - AMR Parsing as Sequence-to-Graph Transduction

news/2024/11/15 8:30:05/

AMR Parsing as Sequence-to-Graph Transduction

论文:https://arxiv.org/pdf/1905.08704.pdf

代码:https://github.com/sheng-z/stog

期刊/会议:ACL 2019

摘要

我们提出了一个基于注意力的模型,将AMR解析视为序列到图的转导。与大多数依赖于预训练的对齐器、外部语义资源或数据扩充的AMR解析器不同,我们提出的解析器是无对齐器的,并且可以用有限的标记AMR数据对其进行有效训练。我们的实验结果在AMR 2.0(LDC2017T10上为76.3%F1)和AMR 1.0(LDC2014T12上为70.2%F1)方面均优于所有先前报道的SMATCH评分。

1、简介

抽象语义表示(AMR,Banarescu et al,2013)解析是将自然语言文本转换为AMR的任务,AMR是一种用于捕获句子级语义的基于图形的形式主义。AMR解析中的挑战包括:(1)它属性的可重入性——同一概念可以参与多个关系——这导致了与树相反的图(Wang et al,2015);(2) 图中的节点(概念)和文本中的单词之间缺乏正确标准比对,这限制了依赖显式比对来生成训练数据的尝试(Flanigan et al, 2014; Wang et al, 2015; Damonte et al, 2017; Foland and Martin, 2017; Peng et al, 2017b; Groschwitz et al, 2018; Guo and Lu, 2018);以及(3)相对有限的标记数据量(Konstas et al ,2017)。

建模对齐为潜在变量,利用外部语义资源,数据增强,基于注意力的端到端方法被用于解决上述问题。

为了解决重入性问题,提出了一个基于注意力的模型,将AMR解析作为序列到图的转化。所提出的模型由扩展的指针生成器网络支持,不需要对准器,并且可以用有限的标记AMR数据进行有效训练。在两个公开可用的AMR基准测试上的实验表明,我们的解析器在这两个基准测试上都明显优于以前最好的解析器。它获得了最好的SMATCH评分:在LDC2017T10上为76.3%的F1,在LDC2014T12上为70.2%的F1。我们还提供广泛的消融和定性研究,量化每个成分的贡献。

2、其他角度去看重入性

AMR是一个有根的、有向的、通常是无环的图,其中节点表示概念,标记的有向边表示它们之间的关系(AMR示例见图1)。AMR是图而不是树的原因是它允许重入语义关系。例如,在图1(a)中,“Victim”是help-01的ARG0和ARG1。虽然已经致力于发展用于AMR解析的基于图的算法(Chiang et al, 2013; Flanigan et al, 2014),但将句子解析为AMR图而不是树更具挑战性,因为存在有效的现成的基于树的算法,例如Chu and Liu (1965); Edmonds (1968)。为了利用这些基于树的算法以及其他结构化预测范式(McDonald et al, 2005),我们引入了另一种可重入性观点。

当一个节点参与多个语义关系时,采用AMR重入性。我们通过复制具有可重入关系的节点,将AMR图转换为树;也就是说,每当一个节点具有可重入关系时,我们都会复制该节点,并使用该副本参与该关系,从而生成一个树。接下来,为了保留可重入性信息,我们通过为每个节点分配一个索引来添加一层额外的注释。重复的节点被分配与原始节点相同的索引。图1(b)显示了结果AMR树:节点的下标是索引;两个“victim”节点具有相同的索引,因为它们引用了相同的概念。原始AMR图可以通过合并索引相同的节点并统一来自/到这些节点的边来恢复。Artzi等人(2015)在从CCG到AMR的转换中引入了Skolem ID来表示回指参考,van Noord和Bos(2017a)也使用了类似的想法,他们保留了共同索引的AMR变量,以及转化它们去成为数字。

3、任务定义

如果我们考虑以索引节点为预测目标的AMR树,那么我们的解析方法被形式化为两个阶段的过程:节点预测边预测。解析过程的示例如图2所示。

节点预测:一个输入的句子 w = < w 1 , w 2 , … , w n > w=<w_1,w_2,\ldots,w_n> w=<w1,w2,,wn>,每一个 w i w_i wi是句子中的一个单词,我们的方法顺序地解码节点 u = < u 1 , u 2 , … , u w > u=<u_1,u_2,\ldots,u_w> u<u1,u2,,uw>,并确定地分配它们的索引 d = < d 1 , … , d m > d=<d_1,\ldots,d_m> d<d1,,dm>
P ( u ) = ∏ i = 1 m P ( u i ∣ u < i , d < i , w ) P(u)=\prod_{i=1}^{m} P(u_i|u_{<i},d_{<i},w) P(u)=i=1mP(uiu<i,d<i,w)
我们允许相同的节点重复出现在列表中,一个节点的多次出现将被分配相同的索引。我们选择按顺序预测而不是同时预测节点,因为(1)我们认为当前节点生成对未来节点生成是有信息的;(2) 有效端到端模型的变体(Bahdanau et al, 2014; Vinyals et al, 2015)可以用于对这一过程进行建模。在训练时,我们使用对参考AMR树的预序遍历来获得节点的参考列表及其索引。

边预测:给出一个句子 w w w,一个节点列表 u u u和索引 d d d,我们在约束 d d d u u u上有有效树空间 y ( u ) y(u) y(u)中寻找一个最高得分的解析树 y y y。解析树 y y y是一组有向头修正的边 y = { ( u i , u j ) ∣ 1 ≤ i , j ≤ m } y=\{(u_i,u_j)|1 \le i,j \le m \} y={(ui,uj)∣1i,jm}。为了使搜索易于处理,我们采用了基于弧形因子图的方法(McDonald et al, 2005; Kiperwasser and Goldberg, 2016),将树的分数分解为其头修正边的分数之和:
p a r s e ( u ) = arg ⁡ max ⁡ y ∈ y ( u ) ∑ ( u i , u j ) ∈ y s c o r e ( u i , u j ) parse(u)={\arg \max}_{y \in y(u)} \sum_{(u_i,u_j) \in y} score(u_i,u_j) parse(u)=argmaxyy(u)(ui,uj)yscore(ui,uj)
基于边缘的得分,可以使用Chu-Liu Edmonds算法有效地找到得分最高的解析树(即最大生成树)。我们进一步将索引作为约束纳入算法中,如第4.4节所述。在获得解析树之后,我们合并相同索引的节点以恢复标准AMR图。

4、模型

我们的模型有两个主要模块:(1)用于节点预测的扩展指针生成器网络;以及(2)用于边缘预测的深度biaffine分类器。这两个模块对应于AMR解析的两阶段过程,并且在训练过程中共同学习。

4.1 扩展的指针生成器网络

受张等人(2018)中自复制(self-copy)机制的启发,我们扩展了指针生成器网络(See et al.,2017)用于节点预测。提出了一种用于文本摘要的指针生成器网络,该网络可以通过指针从源文本中复制单词,同时保留通过生成器生成新单词的能力。我们的扩展的主要区别在于,它不仅可以复制源文本中的节点,还可以复制目标端先前生成的节点。这种目标端指向非常适合我们的任务,因为我们将预测的节点可以是其他节点的副本。虽然还有其他指针/副本网络(Gulcehre et al, 2016; Merity et al, 2016; Gu et al, 2016; Miao and Blunsom, 2016; Nallapati et al, 2016),但我们发现指针生成器网络在降低AMR解析中的数据稀疏性方面非常有效。

如图3所示,扩展的指针生成器网络由四个主要组件组成:编码器嵌入层、编码器、解码器嵌入层和解码器。

编码器嵌入层:该层将输入句子中的单词转换为向量表示。每个向量是GloVe (Pennington et al, 2014), BERT (Devlin et al, 2018), POS (part-of-speech) 标签和匿名化指标的嵌入以及通过字符级卷积神经网络学习的特征的级联(CharCNN,Kim et al,2016)。

匿名化指示符是告诉编码器该词是否是匿名化词的二分类指示符。在预处理中,输入句子中命名实体的文本跨度将被匿名标记(如person、country)取代,以减少稀疏性。

除了BERT,所有其他嵌入都是从它们相应的学习嵌入查找表中提取的。BERT以子字单元作为输入,这意味着一个字可能对应于BERT的多个隐藏状态。为了准确地使用这些隐藏状态来表示每个单词,我们将平均池化函数应用于BERT的输出。图4说明了从BERT生成单词级嵌入的过程。

编码器:编码器是一个多层双向的RNN网络:
h i l = [ f l → ( h i l − 1 , h i − 1 l ) ; f l ← ( h i l − 1 , h i + 1 l ) ] h_i^l=[\overrightarrow {f^l}(h_i^{l-1},h_{i-1}^l);\overleftarrow {f^l} (h_i^{l-1},h_{i+1}^l) ] hil=[fl (hil1,hi1l);fl (hil1,hi+1l)]
f l → , f l ← \overrightarrow {f^l},\overleftarrow {f^l} fl ,fl 表示两个LSTM核心单元, h i l h_i^l hil是第 i i i个时刻,编码器第 l l l个隐藏层。 h i 0 h_i^0 hi0是单词 w i w_i wi的编码器嵌入层输出。

解码嵌入层:和编码器嵌入层类似,这层的输出向量表示用于AMR节点。不同之处在于,每个向量是GloVe、POS标签、索引的嵌入以及来自CharCNN的特征向量的级联。

节点的POS标签是在运行时推断的:如果一个节点是输入句子的副本,则使用相应单词的POS标签;如果一个节点是前面节点的副本,则使用其先前节点的POS标签;如果一个节点是从词汇表中发出的新节点,则使用UNK标记。

我们在这一层中不包括BERT嵌入,因为AMR节点,尤其是它们的顺序,与自然语言文本(BERT是在其上预训练的)有很大不同。我们试图在这一层中使用“固定”的BERT,但没有带来改进。

解码器:在每个步骤 t t t,解码器( l l l层单向LSTM)接收来自最后一层的隐藏状态 s t l − 1 s^{l−1}_t stl1和来自前一时间步骤的隐藏状态 s t − 1 l s^l_{t−1} st1l,并生成隐藏状态 s t l s^l_t stl:
s t l = f l ( s t l − 1 , s t − 1 l ) s_t^l=f^l(s_t^{l-1},s_{t-1}^l) stl=fl(stl1,st1l)
s t 0 s_t^0 st0是两个向量的连接,前一个节点 u t − 1 u_{t−1} ut1的解码器嵌入层输出(在训练时, u t − 1 u_{t−1} ut1是参考节点列表的前一个;在测试时,它是解码器发出的前一节点),以及前一步的注意力向量 s ~ t − 1 \tilde{s}_{t−1} s~t1 s 0 l s^l_0 s0l是最后一个编码器隐藏状态的串联 f l → , f l ← \overrightarrow {f^l},\overleftarrow {f^l} fl ,fl

source attention distribution a s r c t a_{src}^t asrct通过加性注意力被计算:
e s r c t = v s r c ⊤ tanh ⁡ ( W s r c h 1 : n l + U s r c s t l + b s r c ) , a s r c t = s o f t m a x ( e a r c t ) e_{src}^{t}=v_{src}^{\top} \tanh (W_{src} h_{1:n}^l + U_{src}s_t^l + b_{src}),\\ a_{src}^t=softmax(e_{arc}^t) esrct=vsrctanh(Wsrch1:nl+Usrcstl+bsrc),asrct=softmax(earct)
然后使用它来产生编码器隐藏状态的加权和,即上下文向量 c t c_t ct

Attentional vector s ~ t \tilde{s}_t s~t包含了源侧信息和目标侧信息,并通过MLP计算:
s ~ t = tanh ⁡ ( W c [ c t : s t l ] + b c ) \tilde{s}_t=\tanh(W_c [c_t:s_t^l]+b_c) s~t=tanh(Wc[ct:stl]+bc)
Attentional vector s ~ t \tilde{s}_t s~t有三个作用:

  1. 它被传入一个线性层和softmax层去产生词汇分布:
    P v o c a b = s o f t m a x ( W v o c a b s ~ t + b v o c a b ) P_{vocab}=softmax(W_{vocab} \tilde{s}_t + b_{vocab}) Pvocab=softmax(Wvocabs~t+bvocab)

  2. 被用于使用target attention distribution a t g t t a_{tgt}^t atgtt
    e t g t t = v t g t ⊤ tanh ⁡ ( W [ t g t ] s ~ 1 : t − 1 + U t g t s ~ t + b t g t ) a t g t t = s o f t m a x ( e t g t t ) e_{tgt}^t=v_{tgt}^{\top} \tanh(W_{[tgt]} \tilde{s}_{1:t-1}+U_{tgt}\tilde{s}_t + b_{tgt}) a_{tgt}^t=softmax(e_{tgt}^t) etgtt=vtgttanh(W[tgt]s~1:t1+Utgts~t+btgt)atgtt=softmax(etgtt)

  3. 被用于计算source-side 复制概率 p s r c p_{src} psrc,target-side 复制概率 p t g t p_{tgt} ptgt,通过一个选择层generation概率 p g e n p_{gen} pgen
    [ p s r c , p t g t , p g e n ] = s o f t m a x ( W s w i t c h s ~ t + b s w i t c h ) [p_{src},p_{tgt},p_{gen}]=softmax(W_{switch} \tilde{s}_t + b_{switch}) [psrc,ptgt,pgen]=softmax(Wswitchs~t+bswitch)
    p s r c + p t g t + p g e n = 1 p_{src}+p_{tgt}+p_{gen}=1 psrc+ptgt+pgen=1。它们充当一个软开关,在通过从目标注意力分布attgt中采样从先前节点复制现有节点或以两种方式发出新节点之间进行选择:(1)通过从 P v o c a b P_{vocab} Pvocab中采样从固定词汇表生成新节点,或(2)通过从源注意力分布 a s r c t a^t_{src} asrct中采样从输入句子复制单词(作为新节点)。

节点 u t u_t ut的最终概率分布 P ( n o d e ) ( u t ) P^{(node)}(u_t) P(node)(ut)定义如下。如果 u t u_t ut是现有节点的副本,则:
P ( n o d e ) ( u t ) = p t g t ∑ i : u i = u t t − 1 a t g t i [ i ] P^{(node)}(u_t)=p_{tgt} \sum_{i:u_i=u_t}^{t-1} a_{tgt}^{i}[i] P(node)(ut)=ptgti:ui=utt1atgti[i]
否则:
P ( n o d e ) ( u t ) = p g e n P v o c a b ( u t ) + p s r c ∑ i : w i = u t n a s r c t [ i ] P^{(node)}(u_t)=p_{gen}P_{vocab}(u_t)+ p_{src} \sum_{i:w_i=u_t}^{n} a_{src}^{t}[i] P(node)(ut)=pgenPvocab(ut)+psrci:wi=utnasrct[i]
a t [ i ] a^t[i] at[i] a t a^t at中的第 i i i个元素。请注意,新节点可能具有与现有节点相同的表面形式。我们使用索引跟踪它们的差异。节点 u t u_t ut的索引 d t d_t dt被确定地分配如下:
d t = { t , if  u t is a new node;  d j , if  u t is a copy of its antecedent  u j d_{t}=\left\{\begin{array}{c} t, \text { if } u_{t} \text { is a new node; } \\ d_{j}, \text { if } u_{t} \text { is a copy of its antecedent } u_{j} \end{array}\right. dt={t, if ut is a new node; dj, if ut is a copy of its antecedent uj

4.2 深度Biaffine分类

对于第二阶段(即边缘预测),我们使用了一种深度biaffine分类器,该分类器最初被提出用于基于图的依赖解析(Dozat and Manning,2016),最近已被应用于语义解析(Peng et al.,2017a;Dozat and Manning,2018)。

如图5所示,我们使用的主要区别在于,我们没有重新编码AMR节点,而是直接使用来自扩展的指针生成器网络的解码器隐藏状态作为深度biaffine分类器的输入。我们发现使用解码器隐藏状态作为输入的两个优点:(1)通过输入馈送方法,解码器隐藏状态包含来自输入句子和预测节点的上下文信息;(2) 由于解码器隐藏状态用于节点预测和边预测,我们可以在我们的模型中联合训练这两个模块。

给定解码器隐藏状态 < s 1 , … , s m > <s_1,\ldots,s_m> <s1,,sm>和伪根的学习向量表示 s 0 ′ , s_0', s0我们遵循Dozat和Manning(2016),将边预测分解为两个部分:一个预测有向边 ( u k , u t ) (u_k,u_t) (uk,ut)是否存在于两个节点 u k u_k uk u t u_t ut之间,另一个预测每个潜在边的最佳标签。

边和标签分数计算如下:
s t ( e d g e − h e a d ) = M L P e d g e − h e a d ( s t ) , s t ( e d g e − d e p ) = M L P e d g e − d e p ( s t ) , s t ( l a b e l − h e a d ) = M L P l a b e l − h e a d ( s t ) , s t ( l a b e l − d e p ) = M L P l a b e l − h e a d ( d e p ) , s c o r e k , t ( e d g e ) = B i a f f i n e ( s k ( e d g e − h e a d ) , s t ( e d g e − d e p ) ) , s c o r e k , t ( l a b e l ) = B i a f f i n e ( s k ( l a b e l − h e a d ) , s t ( l a b e l − d e p ) ) s_t^{(edge-head)}=MLP^{edge-head}(s_t),\\ s_t^{(edge-dep)}=MLP^{edge-dep}(s_t),\\ s_t^{(label-head)}=MLP^{label-head}(s_t),\\ s_t^{(label-dep)}=MLP^{label-head}(dep),\\ score_{k,t}^{(edge)}=Biaffine(s_k^{(edge-head)},s_t^{(edge-dep)}),\\ score_{k,t}^{(label)}=Biaffine(s_k^{(label-head)},s_t^{(label-dep)}) st(edgehead)=MLPedgehead(st),st(edgedep)=MLPedgedep(st),st(labelhead)=MLPlabelhead(st),st(labeldep)=MLPlabelhead(dep),scorek,t(edge)=Biaffine(sk(edgehead),st(edgedep)),scorek,t(label)=Biaffine(sk(labelhead),st(labeldep))
Biaffine和Bilinear将被定义如下:
M L P ( x ) = E L U ( W x + b ) , B i a f f i n e ( x 1 , x 2 ) = x 1 ⊤ U x 2 + W [ x 1 ; x 2 ] + b , B i l i n e a r ( x 1 , x 2 ) = x 1 ⊤ U x 2 + b MLP(x)=ELU(Wx+b),\\ Biaffine(x_1,x_2)=x_1^{\top} U x_2 + W[x_1;x_2]+b,\\ Bilinear(x_1,x_2)=x_1^{\top} U x_2 +b MLP(x)=ELU(Wx+b),Biaffine(x1,x2)=x1Ux2+W[x1;x2]+b,Bilinear(x1,x2)=x1Ux2+b
给定一个节点 u t u_t ut u k u_k uk u t u_t ut的边头节点的概率定义为:
P t ( h e a d ) ( u k ) = exp ⁡ ( s c o r e k , t ( e d g e ) ) ∑ j = 1 m exp ⁡ ( s c o r e j , t ( e d g e ) ) P_t^{(head)}(u_k)=\frac{\exp (score_{k,t}^{(edge)})}{\sum_{j=1}^m \exp (score_{j,t}^{(edge)})} Pt(head)(uk)=j=1mexp(scorej,t(edge))exp(scorek,t(edge))
( u k , u t ) (u_k,u_t) (uk,ut)的概率为:
P k , t ( l a b e l ) ( l ) = exp ⁡ ( s c o r e k , t ( l a b e l ) [ l ] ) ∑ l ′ exp ⁡ ( s c o r e k , t ( l a b e l ) [ l ′ ] ) P_{k,t}^{(label)}(l)=\frac{\exp (score_{k,t}^{(label) }[l])}{\sum_{l'}\exp (score_{k,t}^{(label) }[l'])} Pk,t(label)(l)=lexp(scorek,t(label)[l])exp(scorek,t(label)[l])

4.3 训练

训练目标是共同最小化共指节点和边的损失,对于(1)共指节点 u t u_t ut,(2)节点 u t u_t ut的共指边头节点 u k u_k uk,以及(3) u k u_k uk u t u_t ut之间的共指边的标签 l l l,可以将其分解为每个时间步长 t t t的负对数似然的和:
m i n i m i z e − ∑ t = 1 m [ log ⁡ P ( n o d e ) ( u t ) + log ⁡ P t ( h e a d ) ( u k ) + log ⁡ P k , t ( l a b e l ) ( l ) + λ c o v l o s s t ] minimize -\sum_{t=1}^{m} [\log P^{(node)}(u_t) + \log P_t^{(head)}(u_k)+\log P_{k,t}^{(label)}(l)+\lambda covloss_t] minimizet=1m[logP(node)(ut)+logPt(head)(uk)+logPk,t(label)(l)+λcovlosst]
c o v l o s s t covloss_t covlosst是coverage loss是去惩罚重复节点: c o v l o s s t = ∑ i min ⁡ ( a s r c t [ i ] , c o v t [ i ] ) covloss_t=\sum_i \min (a_{src}^t [i],cov^t [i]) covlosst=imin(asrct[i],covt[i]) c o v t cov^t covt是所有先前解码时间步长上的源注意力分布的总和: c o v t = ∑ t ′ = 0 t − 1 a s r c t ′ cov^t=\sum_{t'=0}^{t-1} a_{src}^{t'} covt=t=0t1asrct

4.4 预测

对于节点预测,基于每个解码时间步长的最终概率分布 P ( n o d e ) ( u t ) P^{(node)}(u_t) P(node)(ut),我们实现贪婪搜索和beam search,以顺序解码节点列表 u u u和索引 d d d

对于边预测,给定预测节点列表 u u u、它们的索引 d d d和边缘分数 S = { s c o r e i , j e d g e ∣ 0 ≤ i , j ≤ m } S=\{score^{edge}_{i,j}|0≤i,j≤m\} S={scorei,jedge∣0ijm},我们应用ChuLiu-Edmonds算法和简单的自适应来找到最大生成树(MST)。如算法1所述,在调用ChuLiu-Edmonds算法之前,我们首先包括一个伪根 u 0 u_0 u0,以确保每个节点都有一个头,然后排除源节点和目标节点具有相同索引的边,因为这些节点将合并到一个节点中,以恢复自循环无效的标准AMR图。

5、实验

实验数据集:AMR2.0(LDC2017T10)、AMR1.0(LDC2014T12)。

实验结果

消融实验

6、总结

我们提出了一种基于注意力的AMR解析模型,在该模型中,我们将一系列新的组件引入到转导设置中,这些组件超出了典型的NMT系统在这项任务中的作用。我们的模型在两个AMR语料库上取得了最好的性能。对于未来的工作,我们希望将我们的模型扩展到其他语义解析任务(Oepen et al, 2014; Abend and Rappoport, 2013)。我们还对跨语言环境中的语义解析感兴趣(Zhang et al, 2018; Damonte and Cohen, 2018)。

最近工作


http://www.ppmy.cn/news/94266.html

相关文章

一文带你梳理Python的中级知识

Python是一种高级编程语言&#xff0c;它在众多编程语言中&#xff0c;拥有极高的人气和使用率。本文主要带大家梳理一下Python中常用的中级知识&#xff0c;希望对大家有所帮助 1. 文件操作 Python中的文件操作通常使用内置的open()函数来打开文件。以下是一个简单的示例&…

Java中如何使用策略模式减少 if / else 分支的使用

目录 1、策略模式 1.1 、策略模式包含三个角色&#xff1a; 2、需求 2.1 、传统方式 2.2 、策略模式实现 2.2.1 、新建PolicyPatternController.java 2.2.2 、Express.java(实体类) 2.2.3 、定义一个接口&#xff1a;PolicyPatternService.java 2.2.4 、定义3个实现类…

【腾讯云 Finops Crane 集训营】深入了解 Crane 开源项目,集训营实验操作指南,体验过程总结

前言 最近有幸参与了腾讯云举办的Finops Crane的集训营。在这个过程中&#xff0c;老师认真指导&#xff0c;让我受益非浅&#xff0c;也让我真正理解了这一产品所带来的意义。 在听了老师们的介绍和讲解后&#xff0c;我马不停蹄地开始了自己摸索。首先是跟着视频和官方教程…

猜谜游戏、彩云词典爬虫、SOCKS5代理的 Go(Golang) 小实践,附带全代码解释

猜谜游戏在编程语言实践都已经和 HelloWord 程序成为必不可少的新手实践环节&#xff0c;毕竟&#xff0c;它能够让我们基本熟悉 for 循环、变量定义、打印、if else 语句等等的使用&#xff0c;当我们基本熟悉该语言基础之后&#xff0c;就要学会其优势方面的程序实践&#xf…

表情符号(emoji)大全,只此一文便够了

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 表情符号&#xff08;emoji&#xff09;大全、只此一文便够了 摘要集中展示笑脸和动物人庆贺和物品食品和物交通和地点符号 符号表smileys_and_peopleanimals_and_naturefood_and_dr…

【数据结构】初步了解排序

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 目录 1.排序的概念及其运用 1.1排序的概念 2.常见排序算法的实现 2.1插入排序 2.2希尔排序 问题:gap是多少合适&#xff1f; 1.排序的概念及其运用 1.1排序的概念 排序&#xff1a;所…

Python根据经纬度在地图上显示(folium)

Python根据经纬度在地图上显示&#xff08;folium&#xff09; 一、folium介绍1.folium.Map参数简要介绍2.folium.Marker参数介绍 二、Python根据经纬度在地图上显示&#xff08;示例&#xff09;1.经纬度坐标标记2.经纬度坐标分组标记 一、folium介绍 1.folium.Map参数简要介…

Git使用各种情况场景记录

文章目录 4、Git使用各种情况场景记录&#xff1a;1、执行 "git fetch" 来获取远程仓库分支最新列表 到 本地仓库分支。3、设置邮箱地址&#xff1a;4、从特定远程分支dev获取&#xff1a;5、上传代码到特定远程分支dev&#xff1a;6、基于远程分支创建新分支&#x…