【论文阅读笔记| AACL-IJCNLP2022】PESE: Event Structure Extraction using Pointer Network based

论文题目:PESE: Event Structure Extraction using Pointer Network based Encoder-Decoder Architecture

论文来源: AACL-IJCNLP2022

论文链接:PESE: Event Structure Extraction using Pointer Network based Encoder-Decoder Architecture (aclanthology.org)

代码链接:GitHub - alapanju/PESE: This is the code for our AACL-IJCNLP2022 paper "PESE: Event Structure Extraction using Pointer Network based Encoder-Decoder Architecture"

0 摘要

事件抽取(EE)的任务的目的是从文本中找到事件和与事件相关的论元信息,并以结构化的格式表示它们。以往的大多数工作都试图通过单独识别多个子结构并将它们聚合以得到完整的事件结构来解决这个问题。该方法的问题是无法识别事件参与者之间的所有相互依赖关系(事件触发词、论元和角色)。在本文中,我们以唯一的元组格式表示每个事件记录,该格式包含触发词短语、触发词类型、论元短语和相应的角色信息。我们提出的基于指针网络的编码器-解码器模型通过利用事件参与者之间的交互,为EE任务提供一个真正的端到端解决方案,在每个时间步中生成一个事件元组。我们在ACE2005数据集上评估了我们的模型,实验结果证明了我们的模型通过实现与最先进的方法相比的有效性。

1 引言

从文本文档中进行的事件抽取(EE)是自然语言处理和理解的关键任务之一。事件抽取处理从自然语言文本中识别事件框架。这些事件框架具有一个复杂的结构,其中包含有关事件触发词、事件类型、事件特定的论元和事件论元角色的信息。例如,

In Baghdad, a cameraman died when an American tank fired on the Palestine hotel.

在这个句子中,died和fired分别是事件类型Die和Attack的事件触发词。该句子包含以下实体短语:Baghdad, a cameraman, an American tank and Palestine hotel.其中一些实体在上述事件中扮演特定的角色,称为事件论元。事件类型Die的(论元;角色)对包括:(Baghdad; Place), (A cameraman; victim), (American tank; instrument)。然而,Attack事件的(论元;角色)对为:(Baghdad; Place), (A cameraman; target), (American tank; instrument) 和 (Palestine Hotel; Target)。显然,一个句子可能包含多个事件;一个实体可能被多个事件类型框架共享;此外,一个特定的论元可能在不同的事件框架中扮演不同的角色。因此,一个理想的事件抽取系统将识别所有的触发词,对正确的事件类型进行分类,抽取所有与事件相关的论元,并正确地预测事件论元的角色。每一个子任务都同样重要和具有挑战性。

大多数现有的工作将EE任务分解为这些预定义的子任务,然后聚合这些输出以得到完整的事件框架。其中一些模型遵循pipline方法,在不同的阶段识别触发词和相应的论元。相比之下,其他的模型依赖于联合建模,可以同时预测触发词和相关论元。然而,pipline方法必须处理错误传播问题,而联合模型必须利用事件触发词、论元和相应角色之间的信息共享和相互依赖性。事件参与者之间的交互具有以下类型:

  1. 事件间交互:通常一个句子中的事件类型相互依赖
  2. 事件内论元交互:特定事件提及的论元之间存在一定关系
  3. 事件间论元交互:句子中提到的两个不同事件共享的目标实体或论元通常具有一些相互依赖关系
  4. 事件类型-角色交互:每个事件帧根据其模式定义有一组不同的论元角色;因此,事件类型和论元角色有一种密切的关系
  5. 论元-角色交互:事件论元角色也依赖于候选论元的实体类型

人们在开发这些交互作用方面付出了大量努力,但尽管它们的结果很有希望,但大多数现有系统未能捕获所有这些相互依赖

为了利用上述事件参与者之间的交互作用,我们提出了一个基于神经网络的序列来构建学习模型,该模型可以从输入的句子中生成句子级的事件框架。每个事件帧都包含一个(触发词、论元)短语对,以及相应的触发词类型(事件类型)和角色标签信息。灵感来自模型用于联合实体关系抽取(Nayak和吴,2020)(陈等人,2021),aspect sentiment三元组抽取(慕克吉等人,2021)和语义角色标记(费等人,2021),我们设计了一个基于指针网络的事件结构抽取(PESE)框架,利用事件-论元-角色相互依赖从文本中提取事件框架。编码器对输入句子进行编码,而解码器基于输入句子编码和在前面的时间步中生成的事件帧来识别每个时间步中的事件帧。创新之处在于这种建模的有效性:

  1. 不是将整个任务分解为单独的子任务,我们的模型可以检测触发词、论元和角色标签一起
  2. 能够通过在连续的时间步长中生成每个事件元组,来提取单个句子中出现的多个事件
  3. 能够提取多个具有公共触发词或论元短语的事件元组
  4. 实验结果表明,该模型还可以识别句子中重叠的论元。

综上所述,本文的贡献如下:

  1. 我们提出了一种新的事件框架表示模式,其中每个帧都包含关于一个(事件、论元)短语对的信息。
  2. 我们提出了一个句子级的端到端事件抽取模型,该模型利用事件论元-角色的相互关联性,试图在一个句子中找到触发词、论元跨度和相应的标签。以一个句子为输入,并生成该句子中出现的所有的事件框架作为输出。
  3. 我们已经将我们提出的方法应用于ACE2005数据集,实验结果表明,我们的方法优于几个最先进的基线模型。

2 相关工作

根据ACE2005指南,EE的任务是组成三到四个对应的子任务。之前大量关于EE的研究只关注一些特定的子任务,如:事件检测或论元抽取。能够提取完整事件结构的模型主要分为两种方式: pipline方法和联合建模方法。最近,诸如问答、机器阅读理解、零样本学习也被用于解决事件检测问题。

最近一些遵循序列生成方法进行事件抽取的工作也取得了有希望的结果。在之前的方法中,最接近我们的方法的是TEXT2EVENT,它也以端到端的方式从句子中生成事件结构。但是它们以token格式生成事件表示,这意味着在每个时间步中模型生成一个token。而我们的模型在每个时间步长中生成一个单一的事件帧,这在端到端事件结构抽取中更为现实。

3 事件帧表示

给定一个句子,我们提出的端到端EE模型提取了该句子中出现的所有事件框架。这些事件框架是特定于事件的信息的结构化表示形式:(1)事件触发词短语,(2)事件类型,(3)论元短语,(4)角色标签。在句子中,每个触发词和论元短语出现为一个连续的单词序列;因此,表示这些短语的一种有效方法是通过它们相应的开始和结束位置。因此,在本文中,我们使用存储所有记录的6元组结构来表示每个事件帧,如前所述。

6元组包含:

  1. 触发词短语的开始索引
  2. 触发词短语的结束索引
  3. 事件类型
  4. 论元短语的开始索引
  5. 论元短语的结束索引
  6. 触发词论元角色标签

触发词短语(1-2)的开始和结束索引表示事件触发词跨度,而论元短语(4-5)的开始和结束索引表示事件论元跨度,其他两个记录(3和6)是两个标签:事件类型和角色类型。

表1表示样本句子和相应的事件框架,这些句子的6元组表示。然而,在某些情况下,当一个事件触发词出现在一个没有任何论元短语的句子中时。为了推广事件元组表示,我们将两个额外的token:[unused1]和[unused2]连接在每个句子的前面,分别的位置为第一个和第二个。在句子中没有实际的论元短语的情况下,[unused2] token被用作虚拟论元,事件元组中的论元短语对应的开始和结束索引用1表示,角色类型用“NA”表示(见表1)。[unused1] token用于表示句子中没有任何有效的事件触发词。

3.1 问题定义

为了正式定义EE任务,首先我们考虑两个预定义的集合E和R,其中E \epsilon \left \{ E_{1},E_{2},E_{3},...,E_{p} \right \}是事件类型的集合,R\epsilon \left \{R_{1},R_{2},R_{3},...,R_{r} \right \}是角色标签的集合。在这里,p和r分别是事件类型和角色类型的数量。现在,给定一个句子S=\left \{ w_{1},w_{2},w_{3},...,w_{n} \right \}其中n是句子长度和wi是第i个token,我们的目标是提取一组事件元组ET=\left \{ et_{i} \right \}_{i=1}^{\left | ET \right |}其中et_{i}=\left \{ s_{i}^{tr},e_{i}^{tr},E_{i},s_{i}^{ar},e_{i}^{ar},R_{i} \right \},和|ET|表示事件帧出现在句子。在第i个事件元组(et_{i})表示中,s_{i}^{tr}e_{i}^{tr}分别表示触发词短语跨度的开始和结束指数,Ei表示候选触发的事件类型,s_{i}^{ar}e_{i}^{ar}分别表示论元短语跨度的开始和结束索引,Ri表示集合R的(触发词、论元)对的角色标签。

4 我们提出的EE框架

我们对端到端EE任务采用编码解码器结构。模型体系结构的概述如图1所示。我们的模型的输入是一个句子(即一个token序列),作为输出,我们得到一个该句子中存在的事件图元列表。在我们的模型中,我们在编码器是预训练过的BERT,解码器是LSTM。

4.1 句子编码

我们使用预训练好的BERT模型作为句子编码器来获得token的上下文表示。然而,词性(POS)标签信息是一个关键的特征,因为大多数触发词短语是名词、动词或形容词。此外,依赖树特征(DEP)是句子级任务中的另一个信息性线索。我们还使用实体类型信息(ENT)信息(BIO标签)作为特性。我们将POS、DEP、ENT和字符级特征与BERT嵌入结合起来,以表示输入句子中的每个标记。因此,除了预训练好的BERT嵌入外,我们还使用了其他四种嵌入:

  • POS嵌入E_{pos}\epsilon \mathbb{R}^{\left | POS \right |\times d_{pos}}
  • DEP嵌入E_{dep}\epsilon \mathbb{R}^{\left | DEP \right |\times d_{dep}}
  • 实体类型嵌入E_{ent}\epsilon \mathbb{R}^{\left | ENT \right |\times d_{ent}}
  • 字符级嵌入E_{char}\epsilon \mathbb{R}^{\left | V_{c} \right |\times d_{char}}

|POS|、|DEP|、|ENT|和|Vc|分别表示唯一pos标签、依赖关系标签、实体标签和唯一字符字母的计数。而d_{pos},d_{dep},d_{ent},d_{char}分别表示pos、依赖性、实体和字符特征的相应维度。我们应用最大池卷积神经网络得到句子S中每个标记的维直向c的特征级特征向量。所有这些特征表示都被连接起来,得到句子+中每个标记的聚合向量表示h_{i}^{E}。更具体地说,h_{i}^{E}\epsilon \mathbb{R}^{d_{h}},其中d_{h}=d_{BERT}+d_{pos}+d_{dep}+d_{ent}+d_{c}

4.2 事件帧的抽取

我们提出的解码器生成一组事件元组。该解码器包括序列发生器LSTM、两个指针网络和两个分类网络。事件框架序列是由序列生成器LSTM生成的。事件的触发词和论元跨度由指针网络识别。分类网络确定事件的类型和触发词-论元的角色标签。下面将更详细地描述这些模块中的每一个。

序列生成网络 

使用LSTM单元格来生成事件帧的序列。

输入:在每个时间步长 t 中,LSTM以注意力加权的句子嵌入(e_{t})和之前生成的所有元组嵌入(eTup_{prev})的聚合作为输入

输出: 中间隐藏表示h_{t}^{D}\left ( \epsilon \mathbb{R}^{d_{h}} \right ) 

使用注意力机制来获得句子嵌入e_{t} \epsilon \mathbb{R}^{d_{h}},用h_{t-1}^{D}eTup_{prev}作为query。解码器LSTM的隐藏状态表示为:

在生成当前的元组时,我们考虑了先前生成的元组表示目的是捕获事件-参与者的相互依赖关系,并避免生成重复的元组。利用后面描述的注意力方法生成句子嵌入向量等。在当前时间步长之前生成的所有事件元组的聚合表示,eTup_{prev}=\sum_{K=0}^{T-1}eTup_{k},其中eTup_{0}是一个零张量。在时间步t生成的事件元组由eTup_{t}=tr_{t}\bigoplus ar_{t}表示,其中tr_{t}ar_{t}分别是在时间步t从指针网络(稍后描述)获得的触发词和实体短语的向量表示。在这里,⊕表示连接操作。在生成每个事件元组时,我们会考虑这些以前生成的事件元组来捕获事件-事件之间的相互依赖关系。

用于触发词/论元跨度检测的指针网络   

目的:用于识别源句中的触发词和论元短语跨度。

每个指针网络包含一个BiLSTM网络,然后是两个前馈神经网络。我们的体系结构包含两个这样的指针网络,以分别识别触发词和论元短语的开始索引和结束索引。

在每个时间步t中

  1. 首先将中间向量h_{t}^{D}(从上一个LSTM层获得)与隐藏向量h_{i}^{E}(从编码器获得)连接起来,并将它们馈送到带有第一个指针网络的隐藏维d_{p}的Bi-LSTM层。
  2. Bi-LSTM网络为输入句子中的每个token生成一个隐藏向量h_{i}^{pt}\epsilon \mathbb{R}^{2d_{p}}。这些隐藏的表示同时被传递到两个带有softmax层的前馈网络,以得到句子中每个标记在0到1之间的两个标准化标量值(\hat{s}_{i}^{tr}\hat{e}_{i}^{tr})。这两个值表示对应的token成为当前事件元组的触发词短语的开始和结束索引的概率。

这里表示第一个指针网络的权值和偏置论元。  

提取元组论元短语的第二个指针网络还包含一个类似的具有两个前馈网络的BiLSTM。

在每个时间步长中,我们将前一个BiLSTM网络中的隐藏向量h_{i}^{pt}h_{t}^{D}h_{i}^{E}连接起来,并传递给第二个指针网络,与第一个指针网络相似的方程,得到\hat{s}_{i}^{ar}\hat{e}_{i}^{ar},这两个标量表示第 i 个token的起始和结束索引的归一化概率分数。

我们考虑将触发词指针网络的输出向量输入到论元指针网络的输入中,以利用触发词-论元之间的相互依赖关系。然而,我们使用从两个指针网络中收集到的归一化概率\hat{s}_{i}^{tr},\hat{e}_{i}^{tr},\hat{s}_{i}^{ar}\hat{e}_{i}^{ar}来得到触发词和论元短语、ev_{t}arr_{t}的向量表示:

我们需要两个基于前馈神经网络的分类层来识别每个事件元组中的事件类型、论元类型和角色标签。

首先,我们将触发词短语ev_{t}的向量表示与h_{t}^{D}连接起来,并将聚合的向量提供给第一个分类层,然后是一个softmax层,以找到检测到的触发词短语的正确事件类型

最后,将​​​​​​​ev_{t},arg_{t}h_{t}^{D}的连接馈到第二个前馈网络,然后是一个softmax层来预测正确的论元-角色标签,同时利用事件-角色和论元-角色的相互依赖关系。

4.3 训练

为了训练我们的模型,我们最小化负对数似然损失之和,用于识别相应的触发词和论元跨度的四个位置指标,以及两个分类任务:1)事件类型分类和2)角色分类。

Loss=-\frac{1}{B\times ET}\sum_{b=1}^{B}\sum_{et=1}^{ET}\left [ log\left ( s_{b,et}^{tr},e_{b,et}^{tr} \right )+ log\left ( s_{b,et}^{ar},e_{b,et}^{ar} \right ) +log(eType_{b,et}) +log(rType_{b,et})\right ]

这里,B是批大小,ET表示句子中事件元组的最大数量,B表示b个训练实例,等第t个时间步长。此外,s_{\ast ,\ast }^{\ast },e_{\ast ,\ast }^{\ast },eType_{\ast ,\ast }rType_{\ast ,\ast }分别表示触发词和实体短语的真实起始和结束索引位置的标准化软大分数及其对应的事件类型和角色标签。

4.4 触发词/论元跨度的推断

在每个时间步 t,指针解码器网络给我们四个归一化标量分数:\hat{s}_{i}^{tr},\hat{e}_{i}^{tr},\hat{s}_{i}^{ar}\hat{e}_{i}^{ar}分别表示i个标记作为触发词和论元跨度的开始索引和结束索引的概率。类似地,对于源句S(长度为n)中的每个token,我们得到四个概率分数,基于这些分数将提取有效的触发词和论元跨度。我们确定触发词的开始和结束的位置触发词和论元短语,聚合概率分数最大化的约束,在一个事件元组触发短语和论元短语没有任何重叠token并且1\leq b\leq e\leq n,其中b和e是相应的短语的开始和结束位置和n是句子的长度。首先,我们选择触发词短语的开始(b)和结束(e)位置索引,使\hat{s}_{b}^{tr}\times \hat{e}_{e}^{tr}为最大值。类似地,我们选择论元短语的开始和结束位置索引,这样提取的论元短语就不会与事件短语跨度重叠。因此,我们得到了四个位置指标及其相应的概率分数。我们重复整个过程,但是通过交换序列,也就是说,首先,识别论元跨度,然后是触发词短语跨度。因此,我们将得到另一组具有相应概率分数的四种位置指标。为了识别有效的触发词和论元短语跨度,我们选择了给出更高的概率分数乘积的索引集。

5 实验

5.1 数据集

本文中使用的ACE2005语料库共包含599个文档。训练集数据包含529个文档(14669句),验证集数据包含30个文档(873句),测试集数据包含40篇文章(711句)。该语料库包含33个事件子类型、13种论元类型和36个独特的角色标签。这里我们处理的是一个句子级的事件抽取任务,即,我们提出的系统基于句子中存在的信息找到事件帧。在数据集中有三种类型的句子:

  • 没有论元的单个触发词:句子只包含一个事件触发词,没有论元信息。
  • 单个事件和相关论元:句子只包含一个事件触发词和相关论元信息。
  • 多个事件和相关论元:句子包含多个事件触发词(属于相同或不同的事件类型),并具有相应的论元短语。每个论元对所提到的触发词扮演相同或不同的角色。
  • 无信息:这些句子不包含任何与预定义的事件类型对应的事件触发词。

对于预处理、标记化、后标记和生成依赖解析树,我们使用了spaCy库。在验证集集中获得最佳性能(F1值)的模型变体将被考虑在测试数据集中进行最终评估。

5.2 参数设置

编码器采用了预训练的bert-base。与Bert基模型相似,标记嵌入长度(dBERT)为768。我们设置了POS嵌入维数(dpos)= 50、DEP特征嵌入维数(ddep)= 50、实体特征嵌入维数(dent)=50、字符嵌入维数(dchar = 50)和字符级标记嵌入维数(dc = 50)。用于提取字符级标记嵌入的CNN层的filter大小为3,并考虑了最大长度为10的token。我们还设置了指针网络(dp)= 968中的解码器LSTM(dh)=968的隐藏维数和BiLSTM的隐藏维数。该模型训练了40个批大小为32的时代,我们使用学习率为0.001和权重衰减为10−5的Adam优化器进行参数优化。我们设置dropout为0.50,以避免过拟合。在我们的实验中,我们使用P100-PCIE 16GB GPU,使用的参数总数为≈220M。选择在开发数据集上f1得分最高的模型变体对测试数据进行评估。我们采用与之前的工作所定义的相同的正确性度量来评估预测结果。

5.3 baselines

为了评估我们提出的模型,我们将我们的性能与一些我们认为作为基线模型的SOTA模型进行了比较:

  1. JointBeam(Li et al.,2013)基于手工设计特征的结构预测提取事件。
  2. DMCNN(Chen et al.,2015)使用动态多池卷积神经网络以pipline的方式提取触发词和论元。
  3. JRNN(Nguyen等人,2016b)利用双向RNN模型,并在其模型中考虑事件-事件和事件-论元的依赖关系。
  4. JMEE(Liu et al.,2018)使用GCN模型与高速公路网络和自我关注进行联合事件和论元提取。
  5. DBRNN (Sha et al., 2018)在Bi-LSTM网络上添加依赖弧,以改善事件提取。
  6. Joint3EE(Nguyen和Nguyen,2019)建议共享公共编码层,以分别实现信息共享和解码触发词、论元和角色。
  7. GAIL(Zhang et al.,2019 b)提出一种使用生成式对抗网络(GAN)的逆强化学习方法。
  8. TANL(Paolini等人,2021年)采用基于序列生成的方法进行事件抽取。
  9. TEXT2EVENT(Lu et al.,2021)提出一个结构网络的序列,并通过约束解码和课程学习注入事件模式。
  10. PLMEE(Yang et al.,2019)提出了一种自动生成标记数据的方法,并试图克服EE任务中的角色重叠问题。

6 结果与分析

表2显示了我们提出的模型(称为PESE)与其他最先进的EE模型相比的总体性能。我们在行PESEavg中显示了超过4次运行的实验的平均分数。名为PESEbest的行描述了我们在每个子任务中的最佳F1分数。我们可以看到,在TI、TC和AI任务中,我们的模型的性能显著优于所有基线模型。此外,对于论元-角色分类(ARC)任务,我们的模型取得了具有竞争的结果。结果表推导出了一些重要的观察结果:

  1. 在TI任务中,我们的模型PESEavg比所有基线模型都好,比第二优模型(PLMEE)高6%。
  2. 同样,在TC的情况下,我们的模型比第二优模型(PLMEE)高出2.7%。此外,我们的模型在触发词分类(TC)任务中的性能优于专门针对TC子任务工作的最佳模型。
  3. 然而,与TI相比,在PESEavg和PESEbest中,TC的F1得分降低了6%以上,这表明在某些情况下,模型可以正确检测触发词,但不能识别正确的事件类型。在ACE2005年的数据集中,在33种事件类型中,大约有50%的事件出现的次数少于100次。训练集的这种不平衡可能是F1分数下降的原因之一。
  4. 在AI的情况下,我们的模型在所有基线模型中表现最好,平均F1得分为68.9%。在ACE2005数据集中,论元的最大长度为38,而触发词的最大长度仅为7。与TI任务相比,具有长单词序列和重叠实体的论元似乎使AI任务更复杂,而事件触发词大多是一到两个单词长的TI任务更复杂。
  5. 在ARC任务中,我们提出的模型的F1平均得分为58.4%,在所有报告的基线模型中排名第三。

我们的最佳结果PESEbest得到的F1得分为59.3%,仅比最佳结果(JMEE)低1%。然而,在没有注入任何事件-本体信息的情况下,我们认为这种端到端性能相当有前途。为了进一步探索我们的模型的有效性,我们在测试数据集上做了一些比较实验,并在表3中显示了在单事件和多事件场景下的性能。

6.1 多个事件场景

与之前的研究类似,我们根据存在的事件触发词的数量对测试句子进行划分,并分别对这些句子进行评估。在单触发词和多触发词场景中,该模型在事件类型识别任务中的性能都超过90%。有趣的是,在触发词分类(TC)的情况下,该模型在多触发词实例中表现相对较好,这假设了我们的模型在捕获句子中事件间依赖关系方面的有效性。

6.2 共享论元场景

我们还研究了我们的模型在共享论元场景上的性能。在ACE2005数据集中,一个事件实例可能包含多个论元,或者一个论元短语可以由多个事件实例共享。与DBRNN相比,我们的模型在单论元和多论元场景中都表现得更好。

6.3 重叠论元短语

在某些情况下,实体短语的某些部分被视为不同的论元。例如,former Chinese president 是类型Person的论元,而Chinese是时间类型GPE的论元。当句子内的所有论元都不同时,我们的模型在论元短语识别方面达到了80.6%。另外,在存在重叠论元的情况下,F1得分为74.3%,相当优于BERD模型报告的结果。

6.4 确定多个角色

当每个提到的事件在一个句子中只有一个论元-角色记录时,我们的模型产生的F1分数为54.1%。在存在多个论元-角色信息的情况下,F1得分为61%。我们也考虑了一个特定论元在一个句子中包含单个或多个角色信息的情况。对于单个角色类型,模型的F1得分达到82.4%,对于多角色实例,对应的F1得分为54.7%。

6.5 消融实验

为了研究在我们的模型中使用的外部特征的影响,我们在表4中报告了消融研究的观察结果。我们可以看到,实体类型的信息对于端到端事件抽取非常重要。它非常显著地提高了在每个子任务上的F1分数。定量分数还验证了后标签和依赖标签特性的使用。字符级特性的使用也使我们在模型性能上有了微小的改进。

7 结论

在本文中,我们提出了一个联合事件抽取模型,它从文本中捕获事件框架,以端到端的方式利用事件内和事件间的交互。与其他将EE视为标记分类问题或序列标记问题的方法不同,我们提出了一个序列到元组生成模型,该模型在每个时间步中提取包含触发词、论元和角色信息的事件元组。实验结果表明,该方法是有效的。未来,我们计划在模型中使用跨句子上下文,并注入事件本体信息来提高我们的性能。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值