本文通过一个demo,学习DeepDive教程

本文中我们的目标是将使用非结构化的输入,在关系数据库中存储提取出的结果,并且加上deepdive对每个提取结果的预测置信度

也就是写一个DeepDive应用根据一个特定的模式来提取mentions与相邻实体和属性之间的关系。

这就是关系抽取任务。我们希望从新闻文章中抽取是夫妻关系的两个人的mentions.

高级的步骤有:

  • 数据处理。首先加载原始语料,添加NLP标注,提取候选关系对,以及一个mention相互间关系的稀疏特征
  • 对数据和规则的远程监督。接下来使用不同的方法来为数据提供监督,便于机器学习模型来学习权重
  • 学习和推断。指定模型高层次的配置
  • 误差分析和调试

0.准备

0.1 声明预测什么

应该告诉DeepDive我们想要预测的随机变量,保存在DDlog这一语言编写的文件中

%%file app.ddlog
# 本程序的目的是预测给定的两个mention是否为夫妻关系
has_spouse?(p1_id text,p2_id text
).

这回生成一个has_spouse表

0.2 设定数据库

接下来,DeepDive会把所有的数据:输入、中间结果、输出都保存在关系数据库中(一般为Postgresql)

1.数据处理

本节,将会产生统计学习问题的传统输入:候选夫妻关系,这些关系通过一系列特征集合表示。我们要预测候选夫妻关系是否为真实关系

有下面四个步骤:

  1. 加载原始输入数据
  2. 添加NLP标注
  3. 提取候选关系实体对
  4. 提取每个候选对的特征

1.1 加载原始输入数据

第一个任务是下载和加载语料库,并放到数据库中的articles表

最好保存每篇文章的id和内容。通过articles表中定义schema来实现

%%file -a app.ddlog## Input Data #################################################################
articles(id      text,content text
).

DeepDive使用一个脚本把原始语料库转换为一个名字转换的tsj文件中。
这个脚本会读取JSON格式的原始语料,然后分割成id和context两个部分,保存成TSJ形式

使用这个脚本会将原始语料库转换为数据库中的article表。由两列组成:id和content

加载到数据库中之后,可以查看数据库的数据

!deepdive query '|10 ?- articles(id, content).'

1.2 添加NLP标注

接下来使用Stanford的CoreNLP来为content添加有用的标注和结构。

这些步骤包括把文章分为句子以及单词。此外还有单词原型(lemma)、词性(POS)、实体识别(NER),句子依存关系等标注

这些在app.ddlog中定义输出的模式

%%file -a app.ddlog## NLP markup #################################################################
sentences(doc_id         text,sentence_index int,tokens         json,lemmas         json,pos_tags       json,ner_tags       json,doc_offsets    json,dep_types      json,dep_tokens     json
).

这里将会生成一个sentence表

接下来定义一个DDlog函数输入doc_id 和 content ,以上面的格式输出每一行.

这个函数作为一个脚本(nlp_markup.sh)来对articles中每一行来进行NLP标注,并且把结果附加到行的后面。

在执行这个脚本之前,需要启动CoreNLP服务器。

执行完之后,查看添加NLP标注后的一个样本。

1.3 提取候选关系集

抽取所有的people

首先定义person表的schema

%%file -a app.ddlog## Candidate mapping ##########################################################
person_mention(mention_id     text,mention_text   text,doc_id         text,sentence_index int,begin_index    int,end_index      int
).

把每一个person保存成一行,其中包含出现文档的id,出现句子的id,在句子的起始index和结束index。
这个功能通过map_person_mention.py文件实现。它会把标记为PERSON标签的连续token看做是一个实体PERSON(利用CoreNLP的工具包),保存成数据库中的一行

%%file udf/map_person_mention.py
#!/usr/bin/env python
from deepdive import *@tsj_extractor
@returns(lambdamention_id       = "text",mention_text     = "text",doc_id           = "text",sentence_index   = "int",begin_index      = "int",end_index        = "int",:[])
def extract(doc_id         = "text",sentence_index = "int",tokens         = "text[]",ner_tags       = "text[]",):"""Finds phrases that are continuous words tagged with PERSON."""num_tokens = len(ner_tags)# find all first indexes of series of tokens tagged as PERSONfirst_indexes = (i for i in xrange(num_tokens) if ner_tags[i] == "PERSON" and (i == 0 or ner_tags[i-1] != "PERSON"))for begin_index in first_indexes:# find the end of the PERSON phrase (consecutive tokens tagged as PERSON)end_index = begin_index + 1while end_index < num_tokens and ner_tags[end_index] == "PERSON":end_index += 1end_index -= 1# generate a mention identifiermention_id = "%s_%d_%d_%d" % (doc_id, sentence_index, begin_index, end_index)mention_text = " ".join(map(lambda i: tokens[i], xrange(begin_index, end_index + 1)))# Output a tuple for each PERSON phraseyield [mention_id,mention_text,doc_id,sentence_index,begin_index,end_index,]

上面的函数会把句子中所有NER标记为PERSON标签的单词以指定的格式保存成数据库中的一行。

注意上面的函数必须是生成器

最后对数据库中的sentence表使用上面的函数并且添加到person_mention表中去。

然后可以在person_mention表中查看PERSON

%%bash
deepdive query 'name, doc, sentence, begin, end | 20?- person_mention(p_id, name, doc, sentence, begin, end).
'

抽取候选配偶关系(pairs of people)

接下来在所有出现少于5个人名句子中,抽取那些有共同出现关系的人名对。并把这些人名对看做是配偶关系的候选集。

首先定义spouse_candidate表的schema

%%file -a app.ddlogspouse_candidate(p1_id   text,p1_name text,p2_id   text,p2_name text
).

这一步不使用python脚本,而是使用DDlog操作来完成。创建一个计算PERSON数目的表,通过过滤条件连接起来。

%%file -a app.ddlognum_people(doc_id, sentence_index, COUNT(p)) :-person_mention(p, _, doc_id, sentence_index, _, _).spouse_candidate(p1, p1_name, p2, p2_name) :-num_people(same_doc, same_sentence, num_p),person_mention(p1, p1_name, same_doc, same_sentence, p1_begin, _),person_mention(p2, p2_name, same_doc, same_sentence, p2_begin, _),num_p < 5,p1 < p2,p1_name != p2_name,p1_begin != p2_begin.

接下来执行上面的DDLog来生成spouse_candidate表

查询spouse_candidate表

%%bash
deepdive query 'name1, name2, doc, sentence | 20?- spouse_candidate(p1, name1, p2, name2),person_mention(p1, _, doc, sentence, _, _).
'

1.4 提取每个候选点的特征

首先定义每个候选点的特征集合。生成一个spouse_feature表

%%file -a app.ddlog## Feature Extraction ########################################################## Feature extraction (using DDLIB via a UDF) at the relation level
spouse_feature(p1_id   text,p2_id   text,feature text
).

目的是用特征集合重新表示每一对spouse集合。特征可以用来表示mention的主要方面。然后让机器学习方法学习特征和结果() 之间的关联程度。

这里使用one-hot向量表示来学习对应的关系。可以想象把候选spouse存储在长度为L的数组中,只有当前的关系为1,其余为0。

DeepDive包括一个自动的特征提取库DDLib。这里使用其中的get_generic_features_relation函数来学习特征。

%%file udf/extract_spouse_features.py
#!/usr/bin/env python
from deepdive import *
import ddlib@tsj_extractor
@returns(lambdap1_id   = "text",p2_id   = "text",feature = "text",:[])
def extract(p1_id          = "text",p2_id          = "text",p1_begin_index = "int",p1_end_index   = "int",p2_begin_index = "int",p2_end_index   = "int",doc_id         = "text",sent_index     = "int",tokens         = "text[]",lemmas         = "text[]",pos_tags       = "text[]",ner_tags       = "text[]",dep_types      = "text[]",dep_parents    = "int[]",):"""Uses DDLIB to generate features for the spouse relation."""# Create a DDLIB sentence object, which is just a list of DDLIB Word objectssent = []for i,t in enumerate(tokens):sent.append(ddlib.Word(begin_char_offset=None,end_char_offset=None,word=t,lemma=lemmas[i],pos=pos_tags[i],ner=ner_tags[i],dep_par=dep_parents[i] - 1,  # Note that as stored from CoreNLP 0 is ROOT, but for DDLIB -1 is ROOTdep_label=dep_types[i]))# Create DDLIB Spans for the two person mentionsp1_span = ddlib.Span(begin_word_id=p1_begin_index, length=(p1_end_index-p1_begin_index+1))p2_span = ddlib.Span(begin_word_id=p2_begin_index, length=(p2_end_index-p2_begin_index+1))# Generate the generic features using DDLIBfor feature in ddlib.get_generic_features_relation(sent, p1_span, p2_span):yield [p1_id, p2_id, feature]

需要联合person_mentionsentences 表来生成spouse_feature

%%file -a app.ddlogfunction extract_spouse_features over (p1_id          text,p2_id          text,p1_begin_index int,p1_end_index   int,p2_begin_index int,p2_end_index   int,doc_id         text,sent_index     int,tokens         text[],lemmas         text[],pos_tags       text[],ner_tags       text[],dep_types      text[],dep_tokens     int[]) returns rows like spouse_featureimplementation "udf/extract_spouse_features.py" handles tsj lines.spouse_feature += extract_spouse_features(p1_id, p2_id, p1_begin_index, p1_end_index, p2_begin_index, p2_end_index,doc_id, sent_index, tokens, lemmas, pos_tags, ner_tags, dep_types, dep_tokens
) :-person_mention(p1_id, _, doc_id, sent_index, p1_begin_index, p1_end_index),person_mention(p2_id, _, doc_id, sent_index, p2_begin_index, p2_end_index),sentences(doc_id, sent_index, tokens, lemmas, pos_tags, ner_tags, _, dep_types, dep_tokens).

现在查看spouse_feature中的特征。

现在我们有了输入机器学习问题的标准输入。这就是特征的集合,用特征来进行分类(是否是对偶关系)。

然而我们并没有带标签的数据来让机器学习模型进行学习,这样大部分的机器学习问题就没法用。

在DeepDive中使用远程监督(distant supervision)的思想。
主要是从混合有次要的数据集和其他启发式规则中来产生一个带有噪声的label集合。

DeepDive教程第一部分相关推荐

  1. Deepdive 教程--数据准备

    Deepdive 教程–数据准备 教程列表 DeepDive教程1 数据准备 DeepDive教程2 模型构建 DeepDive教程3 模块与细节 文章目录 Deepdive 教程--数据准备 教程列 ...

  2. javascript进阶教程第一章案例实战

    javascript进阶教程第一章案例实战 一.学习任务 通过几个案例练习回顾学过的知识 通过练习积累JS的使用技巧 二.实例 练习1:删除确认提示框 实例描述: 防止用户小心单击了"删除& ...

  3. 微信公众号开发入门教程第一篇

    微信公众号开发入门教程第一篇 关键字:微信公众平台开发 作者:方倍工作室 在这篇微信公众平台开发教程中,我们假定你已经有了PHP语言程序.MySQL数据库.计算机网络通讯.及HTTP/XML/CSS/ ...

  4. Spring Data JPA教程第一部分:配置

    Spring Data JPA是一个旨在简化基于JPA的存储库的创建并减少与数据库通信所需的代码量的项目. 在我的工作和个人爱好项目中,我已经使用了一段时间,确实使事情变得更加简单和整洁. 现在是时候 ...

  5. 北大青鸟c语言课后答案,北大青鸟C语言教程--第一章 C语言基础.ppt

    <北大青鸟C语言教程--第一章 C语言基础.ppt>由会员分享,可在线阅读,更多相关<北大青鸟C语言教程--第一章 C语言基础.ppt(20页珍藏版)>请在人人文库网上搜索. ...

  6. android 教程概要,Android精通教程-第一节Android入门简介

    前言 大家好,我是 Vic,今天给大家带来Android精通教程-第一节Android入门简介的概述,希望你们喜欢 每日一句 If life were predictable it would cea ...

  7. MVC教程第一篇:准备工作

    MVC教程第一篇:准备工作   2010-01-28 作者:张洋 来源:张洋的BLOG   摘要 本文将简要介绍这个文章系列的目的.形式及大体内容.并且完成开始学习这个系列前所必要的准备工作. 前言 ...

  8. SpringCloud 教程 | 第一篇: 服务的注册与发现Eureka

    SpringCloud 教程 | 第一篇: 服务的注册与发现Eureka(Finchley版本) 原文首发于:https://www.fangzhipeng.com/springcloud/2018/ ...

  9. 会说话的狗狗本电脑版_一看就会用!Fotor 电脑版 图片后期处理详解系列教程 第一节...

    Fotor 电脑版 图片后期处理详解系列教程 第一节 这节课我们先来了解一下 Fotor 电脑版的界面功能,为了能用 Fotor 电脑版修图处理打基础. 如图示,启动 Fotor 以后出面界面,有编辑 ...

最新文章

  1. 程序性能监控分析工具
  2. 接口有class类对象吗
  3. Golang undefined: strings.ReplaceAll解决
  4. linux 客户机中不支持 unity_婚姻中的不理解,来源于夫妻双方情感支持的不同
  5. SIFT特征检测算子和sift = cv2.xfeatures2d.SIFT_create出错的解决办法
  6. Vuex之理解Modules
  7. html能转换成mp3,网易云音乐ncm格式怎么转换成mp3格式
  8. Nodejs+express+vue网上零食购物网站系统
  9. pixi 小游戏_关于PIXI引擎制作页面小游戏的几个总结
  10. 翻译-你必须知道的28个HTML5特征、窍门和技术
  11. 台式电脑脑计算机没法启动怎么办,台式机主机电源灯不亮,开不了机怎么办? 台式电脑无法开机什么原因...
  12. 智慧畜牧养殖系统的感知设备
  13. Jenkins服务器磁盘空间管理策略
  14. python制作一个计时器_用Python制作一个猫咪小秒表
  15. 嵌入式硬件(四)常用模拟集成电路
  16. 深富策略:传统蓝筹与成长股跷跷板效应明显
  17. Unity个人开发中的踩坑记录(混沌式更新)
  18. MBA案例分析: 美国西南航空的十年发展战略规划
  19. ThinkPHP 新建数据表
  20. Macbook, fn 键, 启用 f1~f12 用作标准功能键

热门文章

  1. Vue:如何制作表格数据分页查询
  2. 求整型矩阵主对角线元素之和
  3. 【毕业设计/课程设计】智能会议室
  4. Android Toolbar设置向上箭头,标题等
  5. 新AlphaGo首度揭秘:单机运行,4个TPU,算法更强(专访+演讲)
  6. abp修改默认返回格式
  7. MySQL增删改查常用语句命令
  8. 广东工业大学计算机研究生学硕就业,广州大学与广东工业大学2018年MPAcc就业平均薪资解析!...
  9. python——简单通讯录
  10. FFmpeg命令(二)、 从视频中提取音频