提交 3e7bea88 编写于 作者: C caoying03

follow comments.

上级 45f06897
......@@ -4,15 +4,19 @@
自然语言分析技术大致分为三个层面:词法分析、句法分析和语义分析。语义角色标注是实现浅层语义分析的一种方式。在一个句子中,谓词是对主语的陈述或说明,指出“做什么”、“是什么”或“怎么样,代表了一个事件的核心,跟谓词搭配的名词称为论元。语义角色是指论元在动词所指事件中担任的角色。主要有:施事者(Agent)、受事者(Patient)、客体(Theme)、经验者(Experiencer)、受益者(Beneficiary)、工具(Instrument)、处所(Location)、目标(Goal)和来源(Source)等。
请看下面的例子
请看下面的例子,“遇到” 是谓词(Predicate,通常简写为“Pred”),“小明”是施事者(Agent),“小红”是受事者(Patient),“昨天” 是事件发生的时间(Time),“公园”是事情发生的地点(Location)。
$$\mbox{[小明]}_{\mbox{Agent}}\mbox{[昨天]}_{\mbox{Time}}\mbox{[晚上]}_\mbox{Time}\mbox{在[公园]}_{\mbox{Location}}\mbox{[遇到]}_{\mbox{Predicate}}\mbox{了[小红]}_{\mbox{Patient}}\mbox{。}$$
在上面的句子中,“遇到” 是谓词(Predicate,通常简写为“Pred”),“小明”是施事者(Agent),“小红”是受事者(Patient),“昨天” 是事件发生的时间(Time),“公园”是事情发生的地点(Location)
语义角色标注(Semantic Role Labeling,SRL)以句子的谓词为中心,不对句子所包含的语义信息进行深入分析,只分析句子中各成分与谓词之间的关系,即句子的谓词(Predicate)- 论元(Argument)结构,并用语义角色来描述这些结构关系,是许多自然语言理解任务(如信息抽取,篇章分析,深度问答等)的一个重要中间步骤。在研究中一般都假定谓词是给定的,所要做的就是找出给定谓词的各个论元和它们的语义角色
语义角色标注(Semantic Role Labeling,SRL)以句子的谓词为中心,不对句子所包含的语义信息进行深入分析,只分析句子中各成分与谓词之间的关系,即:句子的谓词(Predicate)- 论元(Argument)结构,并用语义角色来描述这些结构关系。在研究中一般都假定谓词是给定的,所要做的就是找出给定谓词的各个论元和它们的语义角色,是许多自然语言理解任务(如:信息抽取,篇章分析,深度问答等)的一个重要中间步骤。
传统的SRL系统大多建立在句法分析基础之上,通常包括5个流程:
传统的SRL系统大多建立在句法分析基础之上,通常包括5个流程:(1)构建一棵句法分析树,例如,图1是对上面例子进行依存句法分析得到的一棵句法树。(2)从句法树上识别出给定谓词的候选论元。(3)候选论元剪除;一个句子中的候选论元可能很多,候选论元剪除就是从大量的候选项中剪除那些最不可能成为论元的候选项。(4)论元识别:这个过程是从上一步剪除之后的候选中判断哪些是真正的论元,通常当做一个二分类问题来解决。(5)对第(4)步的结果,通过多分类得到论元的语义角色标签。可以看到,句法分析是基础,并且后续步骤常常会构造的一些人工特征,这些特征往往也来自句法分析。
1. 构建一棵句法分析树,例如,图1是对上面例子进行依存句法分析得到的一棵句法树。
2. 从句法树上识别出给定谓词的候选论元。
3. 候选论元剪除;一个句子中的候选论元可能很多,候选论元剪除就是从大量的候选项中剪除那些最不可能成为论元的候选项。
4. 论元识别:这个过程是从上一步剪除之后的候选中判断哪些是真正的论元,通常当做一个二分类问题来解决。
5. 对第4步的结果,通过多分类得到论元的语义角色标签。可以看到,句法分析是基础,并且后续步骤常常会构造的一些人工特征,这些特征往往也来自句法分析。
<div align="center">
<img src="image/dependency_parsing.png" width = "80%" height = "80%" align=center /><br>
......@@ -95,24 +99,24 @@ $$L(\lambda, D) = - \text{log}\left(\prod_{m=1}^{N}p(Y_m|X_m, W)\right) + C \fra
在SRL任务中,输入是 “谓词” 和 “一句话”,目标是从这句话中找到谓词的论元,并标注论元的语义角色。如果一个句子含有$n$个谓词,这个句子会被处理$n$次。一个最为直接的模型是下面这样:
1. 构造输入
1. 构造输入
- 输入1是谓词,输入2是句子
- 将输入1扩展成和输入2一样长的序列,用one-hot方式表示;
2. one-hot方式的谓词序列和句子序列通过词表,转换为实向量表示的词向量序列;
3. 将步骤2中的2个词向量序列作为双向LSTM的输入,学习输入序列的特征表示;
4. CRF以步骤3中模型学习到的特征为输入,以标记序列为监督信号,实现序列标注;
大家可以尝试上面这种方法。这里,我们提出一些改进,引入两个简单但对提高系统性能非常有效的特征:
大家可以尝试上面这种方法。这里,我们提出一些改进,引入两个简单但对提高系统性能非常有效的特征:
- 谓词上下文:上面的方法中,只用到了谓词的词向量表达谓词相关的所有信息,这种方法始终是非常弱的,特别是如果谓词在句子中出现多次,有可能引起一定的歧义。从经验出发,谓词前后若干个词的一个小片段,能够提供更丰富的信息,帮助消解歧义。于是,我们把这样的经验也添加到模型中,为每个谓词同时抽取一个“谓词上下文” 片段,也就是从这个谓词前后各取$n$个词构成的一个窗口片段;
- 谓词上下文区域标记:为句子中的每一个词引入一个0-1二值变量,表示们是否在“谓词上下文”片段中;
- 谓词上下文:上面的方法中,只用到了谓词的词向量表达谓词相关的所有信息,这种方法始终是非常弱的,特别是如果谓词在句子中出现多次,有可能引起一定的歧义。从经验出发,谓词前后若干个词的一个小片段,能够提供更丰富的信息,帮助消解歧义。于是,我们把这样的经验也添加到模型中,为每个谓词同时抽取一个“谓词上下文” 片段,也就是从这个谓词前后各取$n$个词构成的一个窗口片段;
- 谓词上下文区域标记:为句子中的每一个词引入一个0-1二值变量,表示们是否在“谓词上下文”片段中;
修改后的模型如下(图6是一个深度为4的模型结构示意图):
1. 构造输入
- 输入1是句子序列,输入2是谓词,输入3是对给定的谓词,输入4是谓词上下文,从句子中抽取这个谓词前后各$n$个词,构成谓词上下文,用one-hot方式表示,输入5是谓词上下文区域标记,标记了句子中每一个词是否在谓词上下文中;
- 将输入2~4均扩展为和输入1一样长的序列;
2. 输入1~4均通过词表取词向量转换为实向量表示的词向量序列;其中输入1~3共享同一个词表,输入4独有词表;
- 输入1是句子序列,输入2是谓词序列,输入3是谓词上下文,从句子中抽取这个谓词前后各$n$个词,构成谓词上下文,用one-hot方式表示,输入4是谓词上下文区域标记,标记了句子中每一个词是否在谓词上下文中;
- 将输入2~3均扩展为和输入1一样长的序列;
2. 输入1~4均通过词表取词向量转换为实向量表示的词向量序列;其中输入1、3共享同一个词表,输入2和4各自独有词表;
3. 第2步的4个词向量序列作为双向LSTM模型的输入;LSTM模型学习输入序列的特征表示,得到新的特性表示序列;
4. CRF以第3步中LSTM学习到的特征为输入,以标记序列为监督信号,完成序列标注;
......@@ -124,18 +128,18 @@ $$L(\lambda, D) = - \text{log}\left(\prod_{m=1}^{N}p(Y_m|X_m, W)\right) + C \fra
## 数据准备
### 数据介绍与下载
在此教程中,我们选用[CoNLL 2005](http://www.cs.upc.edu/~srlconll/)SRL任务开放出的数据集作为示例。运行 `sh ./get_data.sh` 会自动从官方网站上下载原始数据。需要特别说明的是,CoNLL 2005 SRL任务的训练数集和开发集在比赛之后并非免费进行公开,目前,能够获取到的只有测试集,包括Wall Street Journal的23节和Brown语料集中的3节。在本教程中,我们以测试集中的WSJ数据为训练集来讲解模型。但是,由于测试集中样本的数量远远不够,如果希望训练一个可用的神经网络SRL系统,请考虑付费获取全量数据。原始数据解压后,以下目录是本教程会使用的数据:
在此教程中,我们选用[CoNLL 2005](http://www.cs.upc.edu/~srlconll/)SRL任务开放出的数据集作为示例。运行 `sh ./get_data.sh` 会自动从官方网站上下载原始数据。需要特别说明的是,CoNLL 2005 SRL任务的训练数集和开发集在比赛之后并非免费进行公开,目前,能够获取到的只有测试集,包括Wall Street Journal的23节和Brown语料集中的3节。在本教程中,我们以测试集中的WSJ数据为训练集来讲解模型。但是,由于测试集中样本的数量远远不够,如果希望训练一个可用的神经网络SRL系统,请考虑付费获取全量数据。
原始数据中同时包括了词性标注、命名实体识别、语法解析树等多种信息。本教程中,我们使用test.wsj文件夹中的数据进行训练和测试,并只会用到words文件夹(文本序列)和props文件夹(标注结果)下的数据。本教程使用的数据目录如下:
```text
conll05st-release/
└── test.wsj
├── props # 标注序列
├── props # 标注结果
└── words # 输入文本序列
```
原始数据中同时包括了词性标注、命名实体识别、语法解析树等多种信息。本教程中,我们使用test.wsj文件夹中的数据进行训练和测试,只会用到words文件夹(文本序列)和props文件夹(标注序列)下的数据。
标注信息源自Penn TreeBank\[[7](#参考文献)\]和PropBank\[[8](#参考文献)\]的标注结果。PropBank 使用的标注标记和我们在文章一开始示例中使用的标注标签不同,但原理是相同的,关于标注标签含义的说明,请参考论文\[[9](#参考文献)\]
标注信息源自Penn TreeBank\[[7](#参考文献)\]和PropBank\[[8](#参考文献)\]的标注结果。PropBank标注结果的标签和我们在文章一开始示例中使用的标注结果标签不同,但原理是相同的,关于标注结果标签含义的说明,请参考论文\[[9](#参考文献)\]
除数据之外,`get_data.sh`同时下载了以下资源:
......@@ -149,11 +153,11 @@ conll05st-release/
我们在英文维基百科上训练语言模型得到了一份词向量用来初始化SRL模型。在SRL模型训练过程中,词向量不再被更新。关于语言模型和词向量可以参考[词向量](https://github.com/PaddlePaddle/book/blob/develop/word2vec/README.md) 这篇教程。我们训练语言模型的语料共有995,000,000个token,词典大小控制为4900,000词。CoNLL 2005训练语料中有5%的词不在这4900,000个词中,我们将它们全部看作未登录词,用`<unk>`表示。
### 数据预处理
脚本在下载数据之后,同时调用了`extract_pair.py``extract_dict_feature.py`这两个脚本以完成了全部的输入数据准备工作,前者完成了下面的第1步,后者完成了下面的2~4步:
脚本在下载数据之后,又调用了`extract_pair.py``extract_dict_feature.py`两个子脚本进行数据预处理,前者完成了下面的第1步,后者完成了下面的2~4步:
1. 将文本序列和标记序列其合并到一条记录中;
2. 一个句子如果含有$n$个谓词,这个句子会被处理$n$次,变成$n$条独立的训练样本,每个样本一个不同的谓词;
3. 抽取谓词上下文和构造谓词上下文区域标记这样两个输入
2. 一个句子如果含有$n$个谓词,这个句子会被处理$n$次,变成$n$条独立的训练样本,每个样本一个不同的谓词;
3. 抽取谓词上下文和构造谓词上下文区域标记;
4. 构造以BIO法表示的标记;
`data/feature`文件是处理好的模型输入,一行是一条训练样本,以"\t"分隔,共9列,分别是:句子序列、谓词、谓词上下文(占 5 列)、谓词上下区域标志、标注序列。下表是一条训练样本的示例。
......@@ -170,7 +174,7 @@ conll05st-release/
| . | set | n't been set . × | 1 | O |
### 提供数据给 PaddlePaddle
1. 使用 hook 函数进行 PaddlePaddle 输入字段的格式定义。
1. 使用hook函数进行PaddlePaddle输入字段的格式定义。
```python
def hook(settings, word_dict, label_dict, predicate_dict, **kwargs):
......@@ -178,8 +182,8 @@ conll05st-release/
settings.label_dict = label_dict # 获取标记序列的字典
settings.predicate_dict = predicate_dict # 获取谓词的字典
# 所有输入特征都是使用one-hot表示序列,在 PaddlePaddle 中是 interger_value_sequence 类型
# input_types 是一个字典,字典中每个元素对应着配置中的一个 data_layer,key 恰好就是 data_layer 的名字
# 所有输入特征都是使用one-hot表示序列,在PaddlePaddle中是interger_value_sequence类型
# input_types是一个字典,字典中每个元素对应着配置中的一个data_layer,key恰好就是data_layer的名字
settings.input_types = {
'word_data': integer_value_sequence(len(word_dict)), # 句子序列
......@@ -194,7 +198,7 @@ conll05st-release/
}
```
2. 使用 process 将数据逐一提供给 PaddlePaddle,只需要考虑如何从原始数据文件中返回一条训练样本。
2. 使用process将数据逐一提供给PaddlePaddle,只需要考虑如何从原始数据文件中返回一条训练样本。
```python
def process(settings, file_name):
......@@ -242,7 +246,7 @@ conll05st-release/
### 数据定义
首先通过 define_py_data_sources2 从dataprovider中读入数据。配置文件中会读取三个字典:输入文本序列的自动、标记的字典、谓词的字典,并传给data provider ,data provider会利用这三个字典,将相应的文本输入转换成one-hot序列。
首先通过 define_py_data_sources2 从dataprovider中读入数据。配置文件中会读取三个字典:输入文本序列的字典、标记的字典、谓词的字典,并传给data provider,data provider会利用这三个字典,将相应的文本输入转换成one-hot序列。
```python
define_py_data_sources2(
......@@ -259,7 +263,7 @@ define_py_data_sources2(
```
### 算法配置
在这里,我们指定了模型的训练参数, 选择了$L_2$正则、学习率和batch size,并使用带Momentum的随机梯度下降法作为优化算法。
在这里,我们指定了模型的训练参数选择了$L_2$正则、学习率和batch size,并使用带Momentum的随机梯度下降法作为优化算法。
```python
settings(
......@@ -311,9 +315,9 @@ settings(
size=word_dim, input=x, param_attr=emb_para) for x in word_input
]
emb_layers.append(predicate_embedding)
emb_layers.append(mark_embedding)
mark_embedding = embedding_layer(
name='word_ctx-in_embedding', size=mark_dim, input=mark, param_attr=std_0)
emb_layers.append(mark_embedding)
```
3. 8个LSTM单元以“正向/反向”的顺序对所有输入序列进行学习。
......
......@@ -104,8 +104,6 @@ predicate_embedding = embedding_layer(
input=predicate,
param_attr=ParameterAttribute(
name='vemb', initial_std=default_std))
mark_embedding = embedding_layer(
name='word_ctx-in_embedding', size=mark_dim, input=mark, param_attr=std_0)
word_input = [word, ctx_n2, ctx_n1, ctx_0, ctx_p1, ctx_p2]
emb_layers = [
......@@ -113,6 +111,8 @@ emb_layers = [
size=word_dim, input=x, param_attr=emb_para) for x in word_input
]
emb_layers.append(predicate_embedding)
mark_embedding = embedding_layer(
name='word_ctx-in_embedding', size=mark_dim, input=mark, param_attr=std_0)
emb_layers.append(mark_embedding)
hidden_0 = mixed_layer(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册