ESRE 系列(二):如何部署自然语言处理 (NLP):命名实体识别 (NER) 示例

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 本文采用示例讲解的方式,介绍使用一个命名实体识别 (NER) NLP 模型来定位和提取非结构化文本字段中预定义类别的实体。我们将通过一个公开可用的模型向您展示如何完成以下几种操作:部署模型到 Elasticsearch 中,利用 new _infer API 查找文本中的命名实体,以及在 Ingest 管道中使用 NER 模型,在文档被采集到 Elasticsearch 中时提取实体。

作者 David Kyle

1691114927159-2ce054cd-0709-46fc-bded-becde48af926.png


作为自然语言处理 (NLP) 系列博文的一部分,本文将采用示例讲解的方式,介绍使用一个命名实体识别 (NER) NLP 模型来定位和提取非结构化文本字段中预定义类别的实体。我们将通过一个公开可用的模型向您展示如何完成以下几种操作:部署模型到 Elasticsearch 中,利用 new _infer API 查找文本中的命名实体,以及在 Ingest 管道中使用 NER 模型,在文档被采集到 Elasticsearch 中时提取实体。


在使用自然语言从全文本字段中提取人名、地名和组织机构名等实体的操作中,NER 模型可谓大有作为。


在本示例中,我们将以小说《悲惨世界》中的选段为运行对象,然后应用 NER 模型并使用该模型提取文本中的人物和地点,最后以可视化的方式展现两者之间的关系。


部署 NER 模型到 Elasticsearch 中

首先,我们需要选择一个 NER 模型,它可以从文本字段中提取人物名字和地点名称。幸运的是,我们可以从 Hugging Face 提供的几个 NER 模型中进行选择,然后在浏览 Elastic 文档 的过程中,我们发现了 Elastic 中有仅包含小写的 NER 模型,可以用来试试看。


现在,我们选好了要应用的 NER 模型,可以开始使用 Eland 安装该模型了。在本示例中,我们将通过 Docker 镜像运行 Eland 命令,但是必须先克隆ElandGitHub 存储库以构建 Docker 镜像,并在客户端系统上创建 Eland 的 Docker 镜像,如下所示:

git clone git@github.com:elastic/eland.git
cd eland
docker build -t elastic/eland .

此刻,Eland 的 Docker 客户端已经准备就绪,我们可以通过下方所示的命令在新的 Docker 镜像中执行eland_import_hub_model命令来安装 NER 模型:

docker run -it --rm elastic/eland \
    eland_import_hub_model \
      --url $ELASTICSEARCH_URL \
      --hub-model-id elastic/distilbert-base-uncased-finetuned-conll03-english \
      --task-type ner \
      --start

上方所示命令中的 ELASTICSEACH_URL 需要替换为您的 Elasticsearch 集群的 URL。为了进行身份验证,上述 URL 中需要包含管理员的用户名和密码,格式如下

https://username:password@host:port


由于我们在 Eland 导入命令的最后一行选择使用--start,因此 Elasticsearch 会将该模型部署到所有可用的 Machine Learning 节点中,并在内存中加载该模型。如果有多个模型且想要选择部署哪一模型,那么我们可以通过 Kibana 的“Machine Learning”>“Model Management(模型管理)”用户界面 (UI) 管理模型的启动和停止。



测试 NER 模型

已部署的模型可以通过新的_inferAPI 加以评估。输入内容则是我们希望分析的字符串。在下方请求中,text_field 是字段名称,模型应该会按照自身配置在该字段中查找输入内容。默认情况下,如果模型是通过 Eland 上传,则输入字段为 text_field


请在 Kibana 的开发工具控制台中,尝试运行以下示例:

POST _ml/trained_models/elastic__distilbert-base-uncased-finetuned-conll03-english/deployment/_infer
{
  "docs": [
    {
      "text_field": "Hi my name is Josh and I live in Berlin"
    }
  ]
}

模型找到了两个实体:人名“Josh”和地名“Berlin”。

{
  "predicted_value" : "Hi my name is [Josh](PER&Josh) and I live in [Berlin](LOC&Berlin)",   
    "entities" :     {
      "entity" : "Josh",
      "class_name" : "PER",
      "class_probability" : 0.9977303419824,
      "start_pos" : 14,
      "end_pos" : 18
    },
    {
      "entity" : "Berlin",
      "class_name" : "LOC",
      "class_probability" : 0.9992474323902818,
      "start_pos" : 33,
      "end_pos" : 39
    }
  ]
}

predicted_value注释文本 格式的输入字符串,class_name 是预测类别,而 class_probability 则表示预测的置信水平。start_posend_pos 分别为已识别实体的开头字符和结尾字符的位置。


添加 NER 模型到 Ingest 推理管道

_infer API 是一种简单而有趣的入门方法,但是它只接受单个输入,并且检测出的实体不会存储在 Elasticsearch 中。另一种方法则是借助推理处理器,在 Ingest 管道采集文档时对其执行批量推理。

您可以在“Stack Management(堆栈管理)”UI 中定义 Ingest 管道,也可以在 Kibana 控制台中进行配置;以下示例中包含多个 Ingest 处理器:

PUT _ingest/pipeline/ner
{
  "description": "NER pipeline",
  "processors": [
    {
      "inference": {
        "model_id": "elastic__distilbert-base-uncased-finetuned-conll03-english",
        "target_field": "ml.ner",
        "field_map": {
          "paragraph": "text_field"
        }
      }
    },
    {
      "script": {
        "lang": "painless",
        "if": "return ctx['ml']['ner'].containsKey('entities')",
        "source": "Map tags = new HashMap(); for (item in ctx['ml']['ner']['entities']) { if (!tags.containsKey(item.class_name)) tags[item.class_name] = new HashSet(); tags[item.class_name].add(item.entity);} ctx['tags'] = tags;"
      }
    }
  ],
  "on_failure": [
    {
      "set": {
        "description": "Index document to 'failed-<index>'",
        "field": "_index",
        "value": "failed-{{{ _index }}}"
      }
    },
    {
      "set": {
        "description": "Set error message",
        "field": "ingest.failure",
        "value": "{{_ingest.on_failure_message}}"
      }
    }
  ]
}

inference处理器开始作业,field_map的目的是将paragraph(源文档中要分析的字段)映射到 text_field(配置模型时要使用的字段名称)。target_field是要写入推理结果的字段名称。


script处理器会提取实体并按类型将其分组。最终结果会列出在输入文本中所检测出的人名、地名和组织机构名。我们要添加该 painless 脚本,以便我们可以在创建的字段中构建可视化。


此处的 on_failure 语句用于捕捉错误。它定义了两种操作。第一种,将 _index 元字段设为新值,并且文档届时会存储于此。第二种,将错误消息写入新字段:ingest.failure。导致推理失败的原因中有很多都可以轻松避免。例如,可能是因为还没有部署模型,或是某些源文档中缺失了输入字段。将推理失败的文档重定向到另一个索引并设置错误消息,而那些失败的推理也并未丢失,还可以稍后进行审查。修复错误后,在推理失败的索引中进行重新索引,以便恢复未成功的请求。



选择用于推理的文本字段

NER 可以应用于许多数据集。在此,我们以维克多·雨果 (Victor Hugo) 1862 年发表的经典小说《悲惨世界》为例。您可以使用 Kibana 的文件上传 功能,上传《悲惨世界》选段的 JSON 文件样例。该文本被拆分为 14,021 个 JSON 文档,每个文档均包含一个段落。随机选取一个段落为例:

{
    "paragraph": "Father Gillenormand did not do it intentionally, but inattention to proper names was an aristocratic habit of his.",
    "line": 12700
}

通过 NER 管道采集段落后,存储在 Elasticsearch 中的结果文档会由一个已识别的人名进行标注。

{
    "paragraph": "Father Gillenormand did not do it intentionally, but inattention to proper names was an aristocratic habit of his.",
    "@timestamp": "2020-01-01T17:38:25",
    "line": 12700,
    "ml": {
        "ner": {
            "predicted_value": "Father [Gillenormand](PER&Gillenormand) did not do it intentionally, but inattention to proper names was an aristocratic habit of his.",
            "entities": [{
                "entity": "Gillenormand",
                "class_name": "PER",
                "class_probability": 0.9806354093873283,
                "start_pos": 7,
                "end_pos": 19
            }],
            "model_id": "elastic__distilbert-base-cased-finetuned-conll03-english"
        }
    },
    "tags": {
        "PER": [
            "Gillenormand"
        ]
    }
}

标签云图是一种可视化方法,它会根据单词出现的频率对单词进行加权,对查看在《悲惨世界》中找到的实体而言,是再理想不过的信息图。打开 Kibana,创建新的基于聚合的可视化,然后选取标签云图。选择包含 NER 结果的索引,在 tags.PER.keyword 字段添加术语聚合。

image.png


从可视化结果中可以轻松看出,Cosette、Marius、和 Jean Valjean 是这部小说中出现频率最高的人物。


调整部署

返回到“Model Management(模型管理)”UI,在“Deployment(部署)”统计下,您将找到“Avg Inference Time(平均推理时间)”。这是原生进程对单个请求进行推理所测得的时间。开始部署时,有两个控制着 CPU 资源使用方式的参数:inference_threadsmodel_threads


inference_threads代表每个请求中用于运行模型的线程个数。增加inference_threads将直接缩短平均推理时间。并行评估的请求个数则由model_threads控制。该设置不会缩短平均推理时间,但是会提高吞吐量。


因而一般情况下,我们会通过增加inference_threads的个数来调整延迟,通过增加model_threads的个数来提高吞吐量。两个参数的默认设置均为一个线程,修改这些设置便可大幅提升性能。我们可以使用 NER 模型,证明这种性能影响。


要更改其中一个线程设置,必须停止然后重启部署。运行 ?force=true 参数传递这一操作是为了停止 API,原因在于该部署是由 Ingest 管道引用,通常会阻止停止。

POST _ml/trained_models/elastic__distilbert-base-uncased-finetuned-conll03-english/deployment/_stop?force=true

然后,使用四个推理线程进行重启。平均推理时间会在部署重启后重置。

POST _ml/trained_models/elastic__distilbert-base-uncased-finetuned-conll03-english/deployment/_start?inference_threads=4

在处理《悲惨世界》选段时,相较于一个线程的 173.86 毫秒,现在每个请求的平均推理时间缩短为 55.84 毫秒。



立即动手

纵观目前可使用的 NLP 任务,NER 只是其中一种。其他可用的任务还包括文本分类、零样本分类和文本嵌入。NLP 文档 中还有更多可供使用的示例,此外还有一个 模型清单,其中列出了可部署到 Elastic Stack 的模型,当然该清单并非详尽无遗。

NLP 是 Elastic Stack 8.0 中的一项重要新功能,它为我们展开了一幅令人兴奋的路线图。目前阿里云检索分析服务Elasticsearch版已经支持8.5版本,您可以开通产品立即尝试以上示例内容,数据节点规格建议4C8G以上。详情了解:https://www.aliyun.com/product/bigdata/elasticsearch


  • 配套实验

基于 Elasticsearch 向量检索的以文搜图

通过简易快速的阿里云相关组件和开源模型部署,通过1小时的动手实操,搭建基于Elasticsearch向量检索的以文搜图的搜索服务原型。



  • 活动推荐

《Elasticsearch 训练营:搜文本搜位置搜图片,1小时玩转Elasticsearch》

由浅入深带您上手实操【基础检索】,搭建高频业务场景应用;进阶体验【向量检索】,构建基于算法模型的向量检索应用,晋升Elasticsearch搜索实战派,超多参营好礼等你拿~

新建项目 (58).png


Reference:
ESRE 系列(一):如何部署自然语言处理 (NLP):文本嵌入和矢量搜索
How to deploy NLP sentiment analysis
How to deploy natural language processing:Getting started



Elasticsearch 技术社区钉钉交流群

image.png

相关文章
|
2月前
|
自然语言处理 算法 Python
自然语言处理(NLP)在文本分析中的应用:从「被动收集」到「主动分析」
【10月更文挑战第9天】自然语言处理(NLP)在文本分析中的应用:从「被动收集」到「主动分析」
55 4
|
2月前
|
机器学习/深度学习 存储 人工智能
大数据中自然语言处理 (NLP)
【10月更文挑战第19天】
167 60
|
25天前
|
机器学习/深度学习 人工智能 自然语言处理
自然语言处理(Natural Language Processing,简称NLP)
自然语言处理(NLP)是人工智能的分支,旨在让计算机理解、解释和生成人类语言。NLP的关键技术和应用包括语言模型、词嵌入、文本分类、命名实体识别、机器翻译、文本摘要、问答系统、情感分析、对话系统、文本生成和知识图谱等。随着深度学习的发展,NLP的应用日益广泛且效果不断提升。
|
28天前
|
机器学习/深度学习 人工智能 自然语言处理
自然语言处理(NLP)是AI的重要分支,旨在让计算机理解人类语言
自然语言处理(NLP)是AI的重要分支,旨在让计算机理解人类语言。本文探讨了深度学习在NLP中的应用,包括其基本任务、优势、常见模型及具体案例,如文本分类、情感分析等,并讨论了Python的相关工具和库,以及面临的挑战和未来趋势。
55 1
|
1月前
|
人工智能 自然语言处理 语音技术
利用Python进行自然语言处理(NLP)
利用Python进行自然语言处理(NLP)
44 1
|
2月前
|
人工智能 自然语言处理 语音技术
利用Python进行自然语言处理(NLP)
利用Python进行自然语言处理(NLP)
32 3
|
2月前
|
机器学习/深度学习 存储 自然语言处理
【NLP自然语言处理】探索注意力机制:解锁深度学习的语言理解新篇章(下)
【NLP自然语言处理】探索注意力机制:解锁深度学习的语言理解新篇章(下)
【NLP自然语言处理】探索注意力机制:解锁深度学习的语言理解新篇章(下)
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
AI技术在自然语言处理中的应用与挑战
【10月更文挑战第3天】本文将探讨AI技术在自然语言处理(NLP)领域的应用及其面临的挑战。我们将分析NLP的基本原理,介绍AI技术如何推动NLP的发展,并讨论当前的挑战和未来的趋势。通过本文,读者将了解AI技术在NLP中的重要性,以及如何利用这些技术解决实际问题。
|
1月前
|
自然语言处理 API C++
阿里通义推出SmartVscode插件,自然语言控制VS Code,轻松开发应用,核心技术开源!
SmartVscode插件深度解析:自然语言控制VS Code的革命性工具及其开源框架App-Controller
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
探索AI在自然语言处理中的创新应用
【10月更文挑战第7天】本文将深入探讨人工智能在自然语言处理领域的最新进展,揭示AI技术如何改变我们与机器的互动方式,并展示通过实际代码示例实现的具体应用。
49 1