【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.xdnf.cn/news/1540938.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Jboss Administration Console弱⼝令

漏洞描述 Administration Console管理⻚⾯存在弱⼝令&#xff0c;admin:admin&#xff0c;登陆后台上传war包 , getshell 影响版本 全版本 环境搭建 因为这⾥⽤的环境是CVE-2017-12149的靶机 cd vulhub-master/jboss/CVE-2017-12149 docker-compose up -d 密码⽂件 /j…

开发易忽视的问题:InnoDB 行锁设计与实现

开发易忽视的问题&#xff1a;InnoDB 行锁设计与实现 存储模型和锁机制 存储结构 数据页&#xff1a; InnoDB 将表的数据存储在数据页中&#xff0c;每个页默认大小为 16KB。数据页中存储多个行记录&#xff0c;行记录按照主键顺序存放。 行格式&#xff1a; InnoDB 支持多种…

VSCode开发ros程序无法智能提示的解决方法(二)

VSCode开发ros程序无法智能提示的解决方法&#xff08;二&#xff09; 说明解决 说明 在Ubuntu下使用vscode开发ros程序&#xff0c;无法进行智能提示。 解决 将C/C更换为v1.20.5版本&#xff0c;如下图

sheng的学习笔记-AI-强化学习(Reinforcement Learning, RL)

AI目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 基础知识 什么是强化学习 强化学习&#xff08;Reinforcement Learning, RL&#xff09;&#xff0c;又称再励学习、评价学习或增强学习&#xff0c;是机器学习的范式和方法论之一&#xff0c;用于描述和解决智能体&#…

Trainer API训练属于自己行业的本地大语言模型 医疗本地问答大模型示例

Trainer API 是 Hugging Face transformers 库中强大而灵活的工具&#xff0c;简化了深度学习模型的训练和评估过程。通过提供高层次的接口和多种功能&#xff0c;Trainer API 使研究人员和开发者能够更快地构建和优化自然语言处理模型 文章目录 前言一、Trainer API它能做什么…

RNN的反向传播

目录 1.RNN网络&#xff1a;通过时间反向传播(through time back propagate TTBP) 2.RNN梯度分析 2.1隐藏状态和输出 2.2正向传播&#xff1a; 2.3反向传播&#xff1a; 2.4问题瓶颈&#xff1a; 3.截断时间步分类&#xff1a; 4.截断策略比较 5.反向传播的细节 ​编辑…

达梦数据库踩坑

提示&#xff1a;第一次接触达梦&#xff0c;是真的不好用&#xff0c;各种报错不提示详细信息&#xff0c;吐槽归吐槽&#xff0c;还是需要学习使用的。 前言 题主刚接触达梦数据库时&#xff0c;本来是想下载官网的连接工具进行数据库连接的&#xff0c;但是谁曾想&#xff…

监控易监测对象及指标之:全面监控GBase数据库

在数字化时代&#xff0c;数据库作为企业核心数据资产的管理中心&#xff0c;其稳定性和性能直接关系到业务的连续性和企业的运营效率。GBase数据库作为高性能的分布式数据库系统&#xff0c;广泛应用于各类业务场景。为了确保GBase数据库的稳定运行和高效性能&#xff0c;对其…

git安装包夸克网盘下载

git安装包夸克网盘下载 git夸克网盘 git网站上的安装包下载速度有点慢&#xff0c;因此为了方便以后下载就将文件保存到夸克网盘上&#xff0c;链接&#xff1a;我用夸克网盘分享了「git」&#xff0c;点击链接即可保存。 链接&#xff1a;https://pan.quark.cn/s/07c73c4a30…

C++速通LeetCode中等第12题-矩阵置零(空间O(1)含注释)

class Solution { public:void setZeroes(vector<vector<int>>& matrix) {int m matrix.size();int n matrix[0].size();int flag_col0 false, flag_row0 false;//先记录第一行和第一列是否有零for (int i 0; i < m; i) {if (!matrix[i][0]) {flag_col…

基于单片机的智能健康水杯设计

摘要&#xff1a;随着时代的发展&#xff0c;单片机领域不断扩张。人工智能产品的出现改变了人们的生活方式。智能产品不仅加快了人们的生活节奏&#xff0c;还为人们的安全提供了保障。在快节奏生活的同时&#xff0c;人们开始越来越关注自己的身体健康&#xff0c;基于 52 单…

高级java每日一道面试题-2024年9月20日-分布式篇-什么是CAP理论?

如果有遗漏,评论区告诉我进行补充 面试官: 什么是CAP理论&#xff1f; 我回答: 在Java高级面试中&#xff0c;CAP理论是一个经常被提及的重要概念&#xff0c;它对于理解分布式系统的设计和优化至关重要。CAP理论是分布式系统理论中的一个重要概念&#xff0c;它描述了一个分…

c++11右值引用和移动语义

一.左值引用和右值引用 什么是左值引用&#xff0c;什么是右值引用 左值是一个表示数据的表达式&#xff08;变量名解引用的指针&#xff09;&#xff0c;我们可以获取到它的地址&#xff0c;可以对它赋值&#xff0c;左值可以出现在符号的左边。使用const修饰后&#xff0c;…

通威股份半年报业绩巨降:销售费用大增,近一年股价跌四成

《港湾商业观察》施子夫 王璐 光伏领域龙头企业通威股份&#xff08;600438.SH&#xff09;交出的半年报延续了2023年营收和净利润双下滑趋势&#xff0c;幅度显得更大。 即便受行业波动影响&#xff0c;但如何重整及提升盈利能力&#xff0c;通威股份还需要给出解决方案。​…

vue项目关闭浏览器中的全屏错误提示

vue.config.js module.exports {devServer: {client: {overlay: false }} }

c++优先级队列自定义排序实现方式

1、使用常规方法实现 使用结构体实现自定义排序函数 2、使用lambda表达式实现 使用lambda表达式实现自定义排序函数 3、具体实现如下&#xff1a; #include <iostream> #include <queue> #include <vector>using namespace std; using Pair pair<in…

什么是大模型的泛化能力?

大模型的泛化能力指的是模型在未见过的数据上表现的能力&#xff0c;即模型不仅能在训练数据上表现良好&#xff0c;也能在新的、未知的数据集上保持良好的性能。这种能力是衡量机器学习模型优劣的重要指标之一。 泛化能力的好处包括但不限于&#xff1a; 提高模型的适应性&a…

Qt 构建目录

Qt Creator新建项目时&#xff0c;选择构建套件是必要的一环&#xff1a; 构建目录的默认设置 在Qt Creator中&#xff0c;项目的构建目录通常是默认设置的&#xff0c;位于项目文件夹内的一个子文件夹中&#xff0c;如&#xff1a;build-项目名-Desktop_Qt_版本号_编译器类型_…

电子烟智能化创新体验:WTK6900P语音交互芯片方案,融合频谱计算、精准语音识别与流畅音频播报

一&#xff1a;开发背景 在这个科技日新月异的时代&#xff0c;每一个细节的创新都是对传统的一次超越。今天&#xff0c;我们自豪地宣布一项革命性的融合——将先进的语音识别技术与电子烟相结合&#xff0c;通过WTK6900P芯片的卓越性能&#xff0c;为您开启前所未有的个性化…

稀疏向量 milvus存储检索RAG使用案例

参考&#xff1a; https://milvus.io/docs/hybrid_search_with_milvus.md milvus使用不方便&#xff1a; 1&#xff09;离线计算向量很慢BGEM3EmbeddingFunction 2&#xff09;milvus安装环境支持很多问题&#xff0c;不支持windows、centos等 在线demo&#xff1a; https://co…