【Python机器学习】NLP信息提取——提取人物/事物关系

目录

词性标注

实体名称标准化

实体关系标准化和提取

单词模式

文本分割

断句

断句的方式

使用正则表达式进行断句


词性标注

词性(POS)标注可以使用语言模型来完成,这个语言模型包含词及其所有可能词性组成的字典。然后,该模型可以使用已经正确标注好词性的句子进行训练,从而识别由该字典中其他词组成的新句子中所有词的词性。NLTK和spaCy都具备词性标注功能。这里使用spaCy,因为它更快,更精确:

import spacyen_model=spacy.load('en_core_web_md')
sentence=("In 1541 Desoto wrote in his journal that the Pascagoula people ranged as far north as the confluence of the Leaf and Chickasawhay rivers at 30.4,-88.5.")
parsed_sent=en_model(sentence)
print(parsed_sent.ents)print(' '.join(['{}_{}'.format(tok,tok.tag_)for tok in parsed_sent]))

这里spaCy一开始没有识别出经纬度对中的经度,后来使用了“OntoNotes 5”词性标注标签体系。

要构建知识图谱,需要确定哪些对象(名词短语)应该配对。我们想把日期“1554年3月15日”与命名实体Desoto配对。然后可以解析这两个字符串(名词短语)以指向我们知识库中的对象。这里可以将1554年3月15日转换为规范化的datetime.date对象

spaCy解析的句子还包含嵌套字典表示的依存树。同时,spacy.displacy可以生成可缩放的矢量图形SVG字符串(或完整的HTML页面),然后在浏览器中以图像的方式查看。上述可视化方式可以帮助我们找到通过依存树创建用于关系提取的标签模式的方法:

from spacy.displacy import render
sentence="In 1541 Desoto wrote in his journal that the Pascagoula."
parsed_sent=en_model(sentence)
with open('pascagoula.html','w') as f:f.write(render(docs=parsed_sent,page=True,options=dict(compact=True)))

上述短句的依存树表明,名称短语“the Pascagoula”是主语“Desoto”的“met”关系的宾语。这两个名词都被标注为专有名词:

要为spacy.matcher.Matcher创建词性和词属性的模式,以表格形式列出所有的词条标签会很有帮助,下面是一些辅助函数,会使上述过程更容易:

import pandas as pd
from collections import OrderedDict
def token_dict(token):return OrderedDict(ORTH=token.orth_,LEMMA=token.lemma_,POS=token.pos_,TAG=token.tag_,DEP=token.dep_)
def doc_dataframe(doc):return pd.DataFrame([token_dict(tok) for tok in doc])
print(doc_dataframe(en_model("In his journal that the Pascagoula.")))

从上例中,可以看到POS或TAG特征值组成的序列构成了一个正确的模式。如果我们查找人与组织的“has-met”关系,我们可能希望引入诸如“PROPN met PROPN”、“PROPN met the PROPN”、“PROPN met with the PROPN”等模式。我们可以单独指定每个模式,或者在专有名词之间尝试使用“任何词”加上*会?操作符的模式来捕获它们:

'PROPN ANYWORD? met ANYWORD?ANYWORD? PROPN'

spaCy中的模式比上述伪代码更强大更灵活,因此必须更加详细的阐述我们想要匹配的词的特征。在spaCy的模式规范中,我们使用字典为每个词或词条去捕获想要匹配的所有标签:

pattern=[{'TAG':'NNP','OP':'+'},{'IS_ALPHA':True,'OP':'*'},{'LEMMA':'meet'},{'IS_ALPHA':True,'OP':'*'},{'TAG':'NNP','OP':'+'}]

然后,可以从解析的句子中提取想要的带标签的词条:

from spacy.matcher import Matcher
doc=en_model("In 1541 Desoto met the Pascagoula.")
matcher=Matcher(en_model.vocab)
matcher.add('met',patterns=[pattern])
m=matcher(doc)
print(m)

通过上述模式就可以从原始句子中提取一个匹配项。下面看对于类似句子的效果:

doc=en_model("October 24: Lewis and Clark met their first Mandan Chief, Big White.")
m=matcher(doc)[0]
print(m)
print(doc[m[1]:m[2]])

我们需要再添加一个模式,,允许动词在主语和宾语名词之后出现:

doc=en_model("On 11 October 1986, Gorbachev and Reagan met at a house.")
pattern=[{'TAG':'NNP','OP':'+'},{'LEMMA':'and'},{'TAG':'NNP','OP':'+'},{'IS_ALPHA':True,'OP':'*'},{'LEMMA':'meet'}]
matcher.add('met',[pattern])
m=matcher(doc)
print(m)
print(doc[m[-1][1]:m[-1][2]])

现在得到了实体和关系。我们甚至可以构建一个对中间动词(“met”)的限制更少、对两侧的人祸组织的名称限制更严格的模式。这样做可能帮助我们识别出更多类似的动词,这些动词也表示一个人或组织和另一个人或组织相遇,例如动词“knows”,甚至包括被动短语,然后我们可以基于这些新的动词给两侧新的专有名词添加关系。

对于如何偏离初始关系模式的原本含义,这被称为语义漂移。幸运的是,spaCy在对被解析文档中的词打标签时,不仅包含词性和依存树信息,还提供了Word2vec词向量。我们可以利用该向量来避免动词和任何一侧的专有名词的连接关系偏离初始模式的原本含义太远。

实体名称标准化

实体的标准化表示通常是一个字符串,即使对于日期之类的数字信息也是如此。日期的标准化ISO格式为“1541-01-01”。实体的标准化表示使我们的知识库能够将图谱中在同一天世界上发生的所有不同事情连接到同一节点(实体)。

我们对其他类型的命名实体也采用标准化,更正单词的拼写,并尝试处理物体、动物、人物、地点等名称的歧义。特别是对于代词或依赖上下文的其他“名称”,标准化命名实体和解决歧义问题通常也被成为共指消解指代消解。命名实体的标准化确保拼写和命名实体不会产生混淆的、有冗余的名称,从而污染命名实体表。

例如,“Desoto”可能至少以5种不同的方式在特定文档中出现:

  • “de Soto”;
  • “Hernando de Soto”;
  • “Hernando de Soto(约1496/1497-1542),相西班牙征服者”;
  • https://.../.../Hernando de Soto(一个URL);
  • 著名历史人物数据库的数字ID。

类似的,标准化算法可以选择上述任何一种形式。知识图谱应该以相同的方式对每种实体进行标准化,以防止同一类型的多个不同实体使用了相同的名称。我们不希望多个人的名字都指向同一个人。更重要的是,标准化应该一以贯之的使用——无论是在向知识库写入新的事实,还是在读取或者查询知识库时都应如此。

如果打算在填充知识库之后更改标准化的方法,那么应该“迁移”或更新知识库中已有实体的数据,以符合新的标准化模式。用于存储知识图谱或知识库的无模式数据库(键值存储),也会受到关系数据库迁移的影响。毕竟,无模式数据库实际上就是关系数据库的接口封装器。

实体标准化之后,还需要“is-a”关系将它们连接到实体类别,这些实体类别定义了实体的类别或类型。因为每个实体可以具有多个“is-a”关系,所以这些“is-a”关系可以被认为是标签。类似于人名或词性标签,如果想要在知识库中使用日期和其他离散数字对象,也需要对其进行标准化。

实体关系标准化和提取

现在需要一种标准化实体关系的方法,从而确定实体之间的关系类型。通过标准化,我们可以找到日期和人之间的所有生日关系,或历史事件发生的日期,类似与“Hernando de Soto”和“Pascagoula people”相遇的时间。我们需要编写算法来选择上述关系中的正确标签。

此外,这些关系可以采用层次化的命名方式,例如“发生于/近似地”和“发生于/精确地”,从而让我们采用特定的关系或者关系类别。还可以使用一个数字属性来标记这些关系的“置信度”、概率、权重或者标准化频率(类似于词项/单词的TF-IDF)。每次从新文本中提取的事实证实了知识库中存在的事实或该事实矛盾时,都可以调整这些置信度的值。

现在需要一种方法来匹配可以找到这些关系的模式。

单词模式

单词模式就像正则表达式一样,但它用于单词而不是字符。我们使用单词类,而不使用字符类。例如,我们不是通过匹配小写字符,而是通过单词模式判定方法来匹配所有的单数名词(词性标注为“NN”)。这往往通过机器学习来实现。一些种子句利用从句子中提取的正确关系(事实)来进行标注,然后可以通过词性标注模式查找类似的句子,即使句子中的主语词和宾语词甚至关系有所变化。

无论先要匹配多少个模式,都可以使用spaCy包以两种不同的方式在O(1)(常数时间)时间内匹配这些模式:

  • 用于任何单词/标签序列模式的PhraseMatcher;
  • 用于词性标签序列模式的Matcher。

为了确保在新句子中找到的新关系真正类似于原始的种子(例子)关系,我们通常需要新句子中的主语词、关系词和宾语词的含义与种子句子中的类似。实现上述目标的最好方法是使用词义的向量表示。词向量有助于尽可能减少语义漂移的发生。

使用单词和短语的语义向量表示使自动信息提取精确到能够自动构建大型知识库。不过仍然需要人工监督和管理来处理自然语言文本中的大量歧义。

文本分割

文档“组块”有助于创建关于文档的半结构化数据,从而让文档在信息检索场景中更加容易搜索、过滤和排序。对于信息提取,如果从中提取关系以创建知识库(如NELL或Freebase),则需要将文档拆分成可能包含一到两个事实的多个部分。我们把自然语言文本划分为有意义的各部分的过程,称为文本分割。得到的分割结果可以是短语、句子、引文、段落甚至是长文档的整个章节。

对于大多数信息提取问题,句子是最常见的块。句子之间通常使用一些符号(.、?、\、!或换行符)作为标点。语法正确的英文句子必须包含一个主语(名词)和一个动词,这意味着它们之间通常至少有一个关系或事实值得提取。句子的意义通常是自包含的,不会过多依赖前面的文本来传达句子的大部分信息。

幸运的是,包含英语在内的大多数语言都有句子的概念,即一个单独的语句,包含一个主语和一个表达了某些内容的动词。对于NLP知识提取流水线,句子正是所需要的文本块。对于聊天机器人流水线,我们的目标是将文档划分成句子和语句。

除了便于信息提取,我们还可以将其中一些语句和句子进行标记,然后作为对话的一部分或者对话中的适当回复。通过短句,可以在较长的文本上训练聊天机器人。相比于单纯在聊天记录上训练,选择合适的数据可以使聊天机器人具有更文艺、智慧的风格。这些书籍使聊天机器人可以使用范围更广的训练文档,从而获得关于世界的常识性知识。

断句

断句通常是信息提取流水线的第一步,它有助于将事实彼此隔离,以便于可以在“The Babel fish cost $42.42 cents for the stamp”这个字符串中,将正确的价格与正确的事物相关联。上述字符串是表明断句很难的一个很好的例子——中间的句号可以被解释为小数点或句号结束符。

我们从文档中提取的最简单的“信息”是包含逻辑性连贯语句的词序列。在自然语言文档中,重要性排在词之后的是句子。句子包含了关于世界的逻辑连贯语句。这些语句包含我们要从文本中提取的信息。句子描述事实的时候,常常描述事物之间的关系以及世界运行的原理,因此我们可以基于句子进行知识提取。句子通常用来解释过去的某个时间、地点,事情是怎么发生的,一般会怎么发展,或者将来怎么发展。因此,还应该能够用句子作为知道,提取有关时间、地点、人、甚至事件或任务序列的事实。而且,最重要的是,所有自然语言都有句子或某种逻辑连贯的文本部分,并且所有语言都有一个广泛认同的步骤来生成它们(一套语法规则或习惯)。

但是断句即识别句子边界,是很复杂的。例如在英语中没有哪个标点符号或字符序列可以始终标记句子的结尾。

断句的方式

即使是人也可能无法在每个句子中找到合适的句子边界。对于一些疑难例子,错误率可能都接近100%。

即使文档特别难以断句,因为对工程师、科学家和数学家来说,句子和感叹号除了可以用来表示句子结尾外,还会被用来表示很多其他内容,对于这些情况,需要一些更复杂的NLP方法,而不仅仅是split('.!?)。这些方法分别是:

  • 手动编程算法(正则表达式和模式匹配);
  • 统计模型(基于数据的模型或机器学习)。

使用正则表达式进行断句

正则表达式知识描述“if...then”规则树(正则语法规则)的简写方法,用于查找字符串中的字符模式。正则表达式(正则语法)是指定有限状态机规则的一种特别简明的方法,使用正则表达式或有限状态机只有一个目的:识别句子边界。

有一些搜索断句工具,它们通过组合和增强提供快速、通用的断句表达式。以下正则表达式适用于一些“正常”句子:

import reprint(re.split(r'[!.?]+[ $]',"Hello World.... Are you there?!?! I'm going to Mars!"))

但是上面的re.split方法消耗了句子的分隔符,只有该分隔符是文档或者字符串的最后一个字符时才会被保留。但该方法确实正确地忽略了双层嵌套引号中句号的问题:

print(re.split(r'[!.?] ',"The author wrote \"'I don't think it's conscious.'Turing said."))

但是该方法也忽略了引号中真实句子的分隔符。这可能是好事也是坏事,取决于断句之后的信息提取步骤:

print(re.split(r'[!.?] ',"The author wrote \"'I don't think it's conscious.'Turing said.\" But I stopped readin."))

缩写文本的效果呢?有时人们着急会把句子写到一起,句号周围没有留空。以下正则表达式职能处理在任何一侧都有字母的短消息中的句号,并且它可以安全地跳过数值:

print(re.split(r'(?<!\d)\.|\.(?!\d)',"I went to GT.You?"))

即使合并上面两个正则表达式,也无法在nlpia.data的疑难测试用例中获得较好的效果:

from nlpia.data.loaders import get_data
regex=re.compile(r'(?<!\d)\.|\.(?!\d)|([!.?]+)[ $]+')
examples=get_data('sentence_tm_town')
wrong=[]
for i,(challenge,text,sents) in enumerate(examples):if tuple(regex.split(text))!=tuple(sents):print('wrong{}:{}{}'.format(i,text[:50],'...'if len(text)>50 else ''))wrong=wrong+[i]
print(len(wrong),len(examples))

必须添加“前向环视”和“后向环视”来提高正则表达式断句工具的精确性。更好的断句方法是使用在标记好的句子集合上训练的机器学习算法(通常是单层神经网络或对率回归)。有些软件包含这样的模型,大家可以使用它来改进断句工具:

  • DetectorMorse;
  • spaCy;
  • SyntaxNet;
  • NLTK;
  • StandfordCoreNLP。

对于大多数关键任务的应用程序,可以使用spaCy断句工具(内置于解析器中)。spaCy依赖少,并且在精确率和速度方面与其他工具相当。纯Python实现中,Kyle Gorman的DetectorMorse也是一个不错的选择。

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

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

相关文章

http增删改查四种请求方式操纵数据库

注意&#xff1a;在manage.py项目入口文件中的路由配置里&#xff0c;返回响应的 return语句后面的代码不会执行&#xff0c;所以路由配置中每个模块代码要想都执行&#xff0c;不能出现return 激活虚拟环境&#xff1a;venv(我的虚拟环境名称&#xff09;\Scripts\activate …

java项目发布后到Tomcat时,总是带一层路径解决方案

java项目发布后到Tomcat时,总是带一层路径 参考文章&#xff1a;java 线上项目访问项目 会多一层项目根路径 根据参考文章写的这篇文章&#xff0c;部分文章细节有完善和改动 在Java Web应用中&#xff0c;当你把应用发布到Tomcat时&#xff0c;如果应用的web.xml配置文件中的&…

Karmada新版本发布,支持联邦应用跨集群滚动升级

摘要&#xff1a;本次升级支持联邦应用跨集群滚动升级&#xff0c;使用户版本发布流程更加灵活可控&#xff1b;透明同事karmadactl 新增了多项运维能力&#xff0c;提供独特的多集群运维体验。 本文分享自华为云社区 《Karmada v1.11 版本发布&#xff01;新增应用跨集群滚动升…

柔性数组 初学版

1.定义 结构中的最后⼀个元素允许是未知⼤⼩的数组&#xff0c;这就叫做『柔性数组』成员 有些编译器会报错⽆法编译可以改成&#xff1a; typedef struct st_type { int i; int a[]; // 柔性数组成员 }type_a; 2.柔性数组的特点&#xff1a; • 结构中的柔性数组成员前…

ReadWriteLock读写锁

读写锁基本概念 ReadWriteLock是Java并发包中的一个接口&#xff0c;它定义了两种锁&#xff1a;读锁&#xff08;Read Lock&#xff09;和写锁&#xff08;Write Lock&#xff09;&#xff0c;真正的实现类是ReentrantReadWriteLock。读锁允许多个线程同时读取共享资源&#…

JAVA开源项目 体育馆管理系统 计算机毕业设计

本文项目编号 T 048 &#xff0c;文末自助获取源码 \color{red}{T048&#xff0c;文末自助获取源码} T048&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 用例设计 六、核…

记一次Mac 匪夷所思终端常用网络命令恢复记录

一天莫名奇妙发现ping dig 等基础命令都无法正常使用。还好能浏览器能正常访问&#xff0c;&#xff0c;&#xff0c;&#xff0c; 赶紧拿baidu试试^-^ ; <<>> DiG 9.10.6 <<>> baidu.com ;; global options: cmd ;; connection timed out; no serve…

美业门店怎么提升业绩?连锁美业门店管理系统收银系统拓客系统源码

美业门店想要提升业绩&#xff0c;需要考虑多方面的因素&#xff0c;并采取综合性的方法。以下是一些可以考虑的因素和建议&#xff1a; 产品与服务优化&#xff1a; 提供高质量的美容产品和服务&#xff0c;确保顾客满意度。不断更新产品线&#xff0c;引入新的时尚趋势&#…

pycharm 使用 translation 插件通过openai进行翻译

pycharm 使用 translation 插件通过openai进行翻译 1. 安装插件2. 配置插件3. 翻译 1. 安装插件 2. 配置插件 3. 翻译 调用 openai 时使用的提示词如下&#xff1a; <|im_start|>system\nYou are a translation engine that can only translate text and cannot interpr…

【大模型实战篇】一种关于大模型高质量数据的处理方法-无标注数据类别快速识别及重复数据检测(加权向量-卷积神经网络-聚类算法结合)

1. 背景介绍 大模型的能力很大程度上依赖于高质量的数据&#xff0c;在之前的一篇文章《高质量数据过滤及一种BoostedBaggingFilter处理方法的介绍》中&#xff0c;我们介绍了大模型的数据处理链路&#xff0c;本文继续关注在高质量数据的模块。 本文所要介绍的处理方法&…

第18届全国热管会议举办,积鼎科技分享「环路热管相变传热仿真」前沿实践

第18届全国热管会议于9月20日至22日在海滨城市日照举行&#xff0c;该会议由中国工程热物理学会热管专业组主办&#xff0c;山东大学和日照市科学技术协会联合承办&#xff0c;汇聚了全国热管技术领域的专家学者及企业代表。在该会议上&#xff0c;积鼎科技在热管仿真方面的成果…

移动剧院:流动艺术空间的声学革命—轻空间

在当今多元化的文化环境中&#xff0c;移动剧院作为一种新兴的演出形式&#xff0c;正在迅速崛起。它不仅提供了灵活多变的演出场地&#xff0c;更以其卓越的声学性能&#xff0c;为观众带来了沉浸式的视听体验。移动剧院的声学优势&#xff0c;使其成为各种艺术活动的理想选择…

TomCat乱码问题

TomCat控制台乱码问题 乱码问题解决&#xff1a; 响应乱码问题 向客户端响应数据&#xff1a; package Servlet;import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servl…

C++中的IO流

1. C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是scanf ()与printf()。 scanf(): 从标准输入设备(键盘)读取数据&#xff0c;并将值存放在变量中。printf(): 将指定的文字/字符串输出到标准输出设备(屏幕)。注意宽度输出和精度输出控制。C语言借助了相应的缓冲…

DELPHI编译软件时带上当前IDE的版本号

如果通过 CompilerVersion 得到的也只是编译器的版本号。 比如&#xff1a;delphi XE12 是 36 &#xff0c;也仅此而己。 我想得到的是IDE的版本号&#xff0c;比如当前最新版本的DELPHI是&#xff1a;Embarcadero RAD Studio 12 Version 29.0.53571.9782 我想得到 29.0.53…

轰!天文学家刚刚目睹了三年来最大的太空爆炸

天文学家目睹了太空中最大的一次爆炸。 被标记为 AT2021lwx 的这次爆炸事件被观测到比任何已知的超新星都要亮十倍&#xff0c;超新星爆炸发生在大质量恒星死亡之时。而且超新星爆炸只持续几个月&#xff0c;而这次爆炸事件已经持续了至少三年。 AT2021lwx 也比恒星被超大质量…

聊一下cookie,session,token的区别

cookie cookie是存放在客户端的,主要用于会话管理和用户数据保存;cookie通过http报文的请求头部分发送给服务器,服务器根据cookie就可以获取到里面携带的session id(用于获取服务器中对应的session数据),因为http是无状态协议,我们通常就是通过cookie去维护状态的 cookie是在…

LabVIEW提高开发效率技巧----使用状态机架构

状态机架构&#xff08;State Machine Architecture&#xff09;是LabVIEW编程中的一种常见且高效的设计模式&#xff0c;特别适合用于处理具有多个操作状态的复杂系统。通过这种架构&#xff0c;程序能够根据不同的输入条件或事件&#xff0c;在多个状态之间切换&#xff0c;从…

守护您的数字世界:IObit Malware Fighter 11 PRO,您的全能电脑卫士

在这个数字化时代&#xff0c;我们的电脑和个人数据面临着前所未有的威胁。病毒、恶意软件、黑客攻击&#xff0c;这些词汇听起来或许遥远&#xff0c;但它们无时无刻不在威胁着我们的网络安全。幸运的是&#xff0c;IObit Malware Fighter 11 PRO&#xff0c;这款屡获殊荣的杀…

【Python】数据可视化之点线图

目录 散点图 气泡图 时序图 关系图 散点图 Scatterplot&#xff08;散点图&#xff09;是一种用于展示两个变量之间关系的图表类型。在散点图中&#xff0c;每个观测值&#xff08;或数据点&#xff09;都被表示为一个点&#xff0c;其中横轴&#xff08;X轴&#xff09;代…