自然语言处理实战第二版(MEAP)(六)(5)

简介: 自然语言处理实战第二版(MEAP)(六)

自然语言处理实战第二版(MEAP)(六)(4)https://developer.aliyun.com/article/1519696

实体和关系名称类似于 Python 中的变量名称。你希望能够像数据库中的字段名称那样查询它们,因此它们不应该有歧义的拼写。原始的 NELL 数据集每行包含一个三元组(事实)。三元组可以被读作简洁、明确定义的句子。知识三元组描述了世界上的一个单独事实。它们给出了关于世界中一个实体(对象)的一条信息。

至少,知识三元组由实体、关系和值组成。知识三元组的第一个元素给出了关于事实的实体名称。第二列“关系”包含与世界中某些其他性质(形容词)或对象(名词)的关系,称为它的值。关系通常是以“是”或“有”等词开始或暗示的动词短语。第三列“值”包含该关系的某个质量的标识符。该“值”是关系的对象,并且与三元组的主语(“实体”)一样是一个命名实体。

因为 NELL 众包了知识库的管理,所以你还有一个概率或置信度值,可以用来推断冲突信息。而且 NELL 还有关于事实的 9 个更多信息列。它列出了用于引用特定实体、关系或值的所有替代短语。NELL 还识别了创建该事实的迭代(遍历 Twitter)。最后一列提供了数据的来源 - 创建事实的所有文本列表。

NELL 包含有关 800 多种唯一关系和超过 200 万个实体的事实。因为 Twitter 主要涉及人物、地点和企业,所以它是一个很好的知识库,可用于增强常识知识库。它对于对名人或企业以及经常是错误信息宣传目标的地点进行事实核查也可能很有用。甚至有一个 “latitudelongitude” 关系,您可以使用它来验证与事物位置相关的任何事实。

>>> islatlon = df['relation'] == 'latlon'
>>> df[islatlon].head()
               entity relation                 value
241          cheveron   latlon      40.4459,-79.9577
528        licancabur   latlon   -22.83333,-67.88333
1817             tacl   latlon     13.53333,37.48333
2967            okmok   latlon  53.448195,-168.15472
2975  redoubt_volcano   latlon   60.48528,-152.74306

现在你已经学会了如何将事实组织成知识图谱。但是当我们需要使用这些知识时 - 例如,用于回答问题时,我们该怎么办?这将是本章最后一节要处理的内容。

11.9 在知识图谱中查找答案

现在我们的事实都组织在一个图形数据库中,我们如何检索那些知识呢?与任何数据库一样,图形数据库有特殊的查询语言来从中提取信息。就像 SQL 及其不同的方言用于查询关系数据库一样,一系列语言,如 SPARQL(SPARQL 协议和 RDF 查询语言),Cypher 和 AQL 存在用于查询图数据库。在本书中,我们将专注于 SPARQL,因为它已被开源社区采用为标准。其他语言,如 Cypher 或 AQL,用于查询特定的图知识库,如 Neo4j 和 ArangoDB。

我们将使用一个比 NELL 更大的知识图谱作为我们的知识基础:Wikidata,维基百科的知识数据库版本。它包含超过 1 亿个数据项(实体和关系),由志愿编辑和机器人维护,就像所有其他维基媒体项目一样。

在 Wikidata 中,实体之间的关系被称为 属性。Wikidata 系统中有超过 11,000 个属性,每个属性都有其 “P-id”,这是一个用于在查询中表示该属性的唯一标识符。同样,每个实体都有其自己独特的 “Q-id”。您可以通过使用 Wikidata 的 REST API 轻松检索任何维基百科文章的 Q-id:

>>> def get_wikidata_qid(wikiarticle, wikisite="enwiki"):
...     WIKIDATA_URL='https://www.wikidata.org/w/api.php'
...     resp = requests.get(WIKIDATA_URL, timeout=5, params={
...         'action': 'wbgetentities',
...         'titles': wikiarticle,
...         'sites': wikisite,
...         'props': '',
...         'format': 'json'
...     }).json()
...     return list(resp['entities'])[0]
>>> tg_qid = get_wikidata_qid('Timnit Gebru')
>>> tg_qid
'Q59753117'

您可以通过前往 (www.wikidata.org/entity/Q59753117) 确认您的发现,并在那里找到该实体的更多属性,将其链接到不同的实体。正如您所看到的,这是一个简单的 “GET” 查询,只有在我们已经有了实体名称并且想要找到 Q-id(或反之)时才有效。对于更复杂的查询,我们将需要使用 SPARQL。那么我们来写你的第一个查询吧!

假设你想知道谁是 Timnit Gebru 的关于 Stochastic Parrots 的著名论文的合著者。如果你不记得论文的名称确切,你实际上可以通过一个简单的查询找到它。为此,你需要一些属性和实体 ID - 为简单起见,我们只在代码中列出它们。

>>> NOTABLE_WORK_PID = 'P800'     # #1
>>> INSTANCE_OF_PID = 'P31'       # #2
>>> SCH_ARTICLE_QID= 'Q13442814'  # #3
>>> query = f"""  ... SELECT ?article WHERE {{  ... wd:{tg_qid} wdt:{NOTABLE_WORK_PID} ?article.  ... ?article wdt:{INSTANCE_OF_PID} wd:Q13442814.  ...  ... SERVICE wikibase:label {{ bd:serviceParam  ... wikibase:language "en". }}  ... }}  ... """
重要提示

不要忘记在 f-strings 中双重转义大括号!而且你不能在 f-strings 中使用反斜杠作为转义字符。 错误:f"{“,而应该是双大括号。 正确:f”{{"

如果你熟悉jinja2包,请注意混合使用 Python f-strings 来填充 jinja2 模板时,你需要四个花括号来创建一个文字双花括号。

乍一看,这个查询看起来有些神秘,它的意思是“找到一个实体 A,使得 Timnit Gebru 有 A 作为知名作品,并且 A 是学术文章的一个实例”。你可以看到每个关系条件在 SPARQL 中是如何编码的,操作数 wd: 在实体 Q-id 前面,操作数 wdt: 在属性 P-id 前面。每个关系约束都有一个“实体有-属性-实体”的形式。

现在让我们使用 WIKIDATA 的 SPARQL API 来检索我们查询的结果。为此,我们将使用一个专门的SPARQLWrapper包,它将简化我们的查询过程。首先,让我们设置我们的包装器:

>>> from SPARQLWrapper import SPARQLWrapper, JSON
>>>
>>> endpoint_url = "https://query.wikidata.org/sparql"
>>> sparql = SPARQLWrapper(endpoint_url)
>>> sparql.setReturnFormat(JSON)  # #1

一旦设置好,你就可以执行你的查询并检查响应:

>>> sparql.setQuery(query)
>>> result = sparql.queryAndConvert()
>>> result
{'head': {'vars': ['article', 'articleLabel']},
 'results': {'bindings': [{'article': {'type': 'uri',
     'value': 'http://www.wikidata.org/entity/Q105943036'},
    'articleLabel': {'xml:lang': 'en',
     'type': 'literal',
     'value': 'On the Dangers of Stochastic Parrots:
     Can Language Models Be Too Big?🦜'}}]}}

看起来没问题!现在你已经得到了文章的 Q-id - 你可以通过使用文章的 ‘author’ 属性来检索它的作者:

>>> import re
>>> uri = result['results']['bindings'][0]['article']['value']
>>> match_id = re.search(r'entity/(Q\d+)', uri)
>>> article_qid = match_id.group(1)
>>> AUTHOR_PID = 'P50'
>>>
>>> query = f"""  ... SELECT ?author ?authorLabel WHERE {{  ... wd:{article_qid} wdt:{AUTHOR_PID} ?author.  ... SERVICE wikibase:label {{ bd:serviceParam wikibase:language "en". }}  ... }}  ... """
>>> sparql.setQuery(query)
>>> result = sparql.queryAndConvert()['results']['bindings']
>>> authors = [record['authorLabel']['value'] for record in result]
>>> authors
['Timnit Gebru', 'Margaret Mitchell', 'Emily M. Bender']

现在你有了你问题的答案!

我们可以通过将查询嵌套在彼此内部来完成相同的结果,而不是执行两个查询,就像这样:

>>> query = """  ... SELECT ?author ?authorLabel WHERE {  ... {  ... SELECT ?article WHERE {  ... wd:Q59753117 wdt:P800 ?article.  ... ?article wdt:P31 wd:Q13442814.  ... }  ... }  ... ?article wdt:P50 ?author.  ... SERVICE wikibase:label {  ... bd:serviceParam wikibase:language "en".  ... }  ... }  ... """

SPARQL 是一种功能齐全的语言,其功能不仅限于简单的查询。Wikidata 本身对 SPARQL 有一个相当不错的手册。你挖掘 Wikidata 使用 SPARQL 的深度越深,你将在你的 NLP 应用中找到越多的用途。这是你可以自动评估你的 NLP 流水线对用户断言的事实的质量和正确性的唯一方式之一。

11.9.1 从问题到查询

因此,你成功在知识数据库中找到了一个相当复杂的问题的答案。如果你的数据库是关系型的,或者你只有非结构化的文本,那几乎是不可能做到的。

然而,寻找答案花费了我们相当多的工作和两个 SPARQL 查询。如何将自然语言问题转化为像 SPARQL 这样的结构化语言的查询?

你以前已经做过这种转换,在第九章的时候。将人类语言翻译成机器语言比在人类语言之间进行翻译要困难一些,但对于机器来说,这仍然是同一个基本问题。现在你知道了转换器擅长将一种语言转换成另一种语言。作为庞大的转换器,LLMs 尤其擅长此类操作。Sachin Charma 创建了一个很好的示例,使用另一个图数据库 ArangoDB 构建知识图谱。他使用 OpenAI 的模型来使数据库上的自然语言问答成为可能。

11.10 自我测试

  • 给出一个问题的例子,这个问题比使用关系数据库更容易回答。
  • 使用 networkx 的有向图将其转换为一个 Pandas DataFrame 的边列表,其中包含两列 source_nodetarget_node。对于单个源节点,检索所有目标节点 ID 需要多长时间?对于这些新的源节点的所有目标节点呢?如何通过索引加速 Pandas 图查询?
  • 创建一个 Spacy Matcher,可以从关于 Timnit Gebru 的维基百科文章中提取更多的工作地点。您能够检索到多少个?
  • 图数据库能做到的事情有关系数据库不能做到的吗?关系数据库能做到图数据库不能做到的事情吗?
  • 使用大型语言模型从自然语言生成 SPARQL wikidata 查询。在没有编辑代码的情况下,它是否正确工作?对于需要在您的知识图谱中进行五次关系(边)遍历的查询,它是否有效?
  • 使用 nlpia2.text_processing 中的 extractors.pyheatmaps.py 为从您自己的长文档(可能是一系列关于自然语言处理的 Mastodon 微博帖子)中提取的句子创建 BERT 相似度热图。编辑 heatmaps.py 代码以改进它,以便您可以专注于非常相似的行。提示:您可以使用非线性函数来缩放余弦相似度值,并使用阈值将相似度值重置为零。

11.11 总结

  • 知识图谱可以用来存储实体之间的关系。
  • 您可以使用基于规则的方法(如正则表达式)或基于神经网络的方法来隔离和提取非结构化文本中的信息。
  • 词性标注和依赖分析允许您提取句子中提到的实体之间的关系。
  • 像 SPARQL 这样的语言可以帮助您在知识图谱中找到所需的信息。

[1] Wikipedia 上的“Symbolic AI”文章(en.wikipedia.org/wiki/Symbolic_artificial_intelligence

[2] 参见名为“自然语言处理:TM-Town”的网页(www.tm-town.com/natural-language-processing#golden_rules)。

[3] “PyPi 上的 Rstr 包”(pypi.org/project/rstr/)。

[4] 参见名为“在 DuckDuckGo 上搜索 Python 句子分段”的网页(duckduckgo.com/?q=Python+sentence+segment&t=canonical&ia=qa)。

[5] GitLab 上的手稿源代码(gitlab.com/tangibleai/nlpia2/-/tree/main/src/nlpia2/data/manuscript/adoc

[6] 单层神经网络或感知器中的每个神经元,在数学上等同于逻辑回归。

[7] 参见名为“Facts & Figures:spaCy 使用文档”的网页(spacy.io/usage/facts-figures)。

[8] 参见名为“nltk.tokenize 包 — NLTK 3.3 文档”的网页(www.nltk.org/api/nltk.tokenize.html#module-nltk.tokenize.punkt)。

[9] SpaCy 是迄今为止我们发现的最准确、最高效的 NLP 解析器,并由欧洲的一个出色的、超级合作的 NLP 工程师团队在 Explosion.ai 定期维护和更新(explosion.ai/about)。

[10] GitLab 上 nlpia2 包中的heatmaps.py模块(gitlab.com/tangibleai/nlpia2/-/blob/main/src/nlpia2/heatmaps.py)。

[11] GitLab 上 nlpia2 包中的extractors.extract_lines()函数(gitlab.com/tangibleai/nlpia2/-/blob/main/src/nlpia2/text_processing/extractors.py#L69)。

[12] 官方 AsciiDoc 解析器是 Ruby。根据文档,目前还没有 Python 包(gitlab.eclipse.org/eclipse-wg/asciidoc-wg/asciidoc.org/-/blob/main/awesome-asciidoc.adoc#convert)。

[13] 斯坦福大学 AI 指数上有关 AI 研究的统计数据(AIIndex.org)。

[14] spaCy 使用“OntoNotes 5”词性标签:(spacy.io/api/annotation#pos-tagging)。

[15] 查看名为“代码示例:spaCy 使用文档”的网页(spacy.io/usage/examples#phrase-matcher)。

[16] 查看名为“匹配器:spaCy API 文档”的网页(spacy.io/api/matcher)。

[17] 这是一项积极研究的课题:nlp.stanford.edu/pubs/structuredVS.pdf

[18] “实现用于关系抽取的自定义可训练组件”:(explosion.ai/blog/relation-extraction)。

[19] 有一些硬编码的常识知识库供您使用。Google Scholar 是您在知识图谱搜索中的好朋友。

[20] Wikidata SPARQL 教程:(www.wikidata.org/wiki/Wikidata:SPARQL_tutorial)。

[21] 如何使用 ChatGPT 和 ArangoDB 构建知识图谱增强的聊天机器人(archive.today/fJB7H)。

相关文章
|
30天前
|
机器学习/深度学习 人工智能 自然语言处理
自然语言处理实战第二版(MEAP)(六)(1)
自然语言处理实战第二版(MEAP)(六)
28 2
|
14天前
|
机器学习/深度学习 人工智能 自然语言处理
Python自然语言处理实战:文本分类与情感分析
本文探讨了自然语言处理中的文本分类和情感分析技术,阐述了基本概念、流程,并通过Python示例展示了Scikit-learn和transformers库的应用。面对多义性理解等挑战,研究者正探索跨域适应、上下文理解和多模态融合等方法。随着深度学习的发展,这些技术将持续推动人机交互的进步。
18 1
|
16天前
|
自然语言处理 监控 数据挖掘
NLP实战:Python中的情感分析
6月更文挑战第6天
31 2
|
30天前
|
机器学习/深度学习 自然语言处理 机器人
自然语言处理实战第二版(MEAP)(六)(4)
自然语言处理实战第二版(MEAP)(六)
25 2
|
30天前
|
机器学习/深度学习 人工智能 自然语言处理
自然语言处理实战第二版(MEAP)(六)(2)
自然语言处理实战第二版(MEAP)(六)
28 2
|
30天前
|
机器学习/深度学习 自然语言处理 机器人
自然语言处理实战第二版(MEAP)(六)(3)
自然语言处理实战第二版(MEAP)(六)
29 1
|
13天前
|
机器学习/深度学习 自然语言处理 PyTorch
【从零开始学习深度学习】48.Pytorch_NLP实战案例:如何使用预训练的词向量模型求近义词和类比词
【从零开始学习深度学习】48.Pytorch_NLP实战案例:如何使用预训练的词向量模型求近义词和类比词
|
16天前
|
机器学习/深度学习 人工智能 自然语言处理
探索未来AI技术的前沿——自然语言处理的发展与应用
本文将深入探讨自然语言处理技术在人工智能领域中的重要性和应用前景。通过分析当前自然语言处理技术的发展趋势和实际应用案例,揭示了其在改善用户体验、提升工作效率以及推动产业创新方面的巨大潜力。
|
17天前
|
自然语言处理 前端开发 Java
探索自然语言生成技术的进展与应用
本文将介绍自然语言生成技术在不同领域的进展和应用。从前端到后端,从Java到Python,从C到PHP,从Go到数据库,我们将深入探讨这些技术的发展趋势和应用场景,并展示它们在实际项目中的价值。
|
25天前
|
机器学习/深度学习 人工智能 自然语言处理
技术探索:人工智能在自然语言处理中的挑战与机遇
在当今数字化时代,人工智能技术的快速发展对各行各业都带来了巨大的变革与机遇。特别是在自然语言处理领域,人工智能的应用已经深入到了我们日常生活的方方面面。本文将探讨人工智能在自然语言处理中所面临的挑战,并分析其中蕴藏的机遇,以及未来发展的方向。
25 1

热门文章

最新文章