如何部署命名实体识别

编辑

您可以使用这些说明在 Elasticsearch 中部署命名实体识别 (NER)模型,测试模型,并将其添加到推理摄取管道。示例中使用的模型在 HuggingFace 上公开可用。

要求

编辑

要按照此页面上的流程进行操作,您必须拥有

  • 一个正确设置以使用机器学习功能的 Elasticsearch Cloud 集群。请参阅设置和安全
  • 适当的订阅级别或已激活的免费试用期。
  • 已安装Docker

部署 NER 模型

编辑

您可以使用Eland 客户端来安装自然语言处理模型。使用预构建的 Docker 镜像来运行 Eland 安装模型命令。使用以下命令拉取最新镜像

docker pull docker.elastic.co/eland/eland

拉取完成后,您的 Eland Docker 客户端即可使用。

第三方模型参考列表中选择一个 NER 模型。此示例使用一个不区分大小写的 NER 模型

通过在 Docker 镜像中运行 eland_import_model_hub 命令来安装模型

docker run -it --rm docker.elastic.co/eland/eland \
    eland_import_hub_model \
      --cloud-id $CLOUD_ID \
      -u <username> -p <password> \
      --hub-model-id elastic/distilbert-base-uncased-finetuned-conll03-english \
      --task-type ner \
      --start

您需要提供管理员用户名及其密码,并将 $CLOUD_ID 替换为您的 Cloud 部署的 ID。此 Cloud ID 可以从您的 Cloud 网站上的部署页面复制。

由于 Eland 导入命令的末尾使用了 --start 选项,因此 Elasticsearch 将部署该模型以供使用。如果您有多个模型,并且想要选择要部署的模型,则可以使用 Kibana 中的 机器学习 > 模型管理 用户界面来管理模型的启动和停止。

转到机器学习 > 训练模型页面并同步您的训练模型。页面顶部会显示一条警告消息,提示“需要 ML 作业和训练模型同步”。单击链接到“同步您的作业和训练模型”。然后单击同步。您也可以等待每小时发生的自动同步,或使用同步机器学习对象 API

测试 NER 模型

编辑

可以通过在 Kibana 中选择机器学习 > 训练模型,然后选择相应模型的测试模型操作来评估已部署的模型。

Test trained model UI
通过使用 _infer API 测试模型

您还可以使用_infer API评估您的模型。在以下请求中,text_field 是模型期望找到输入的字段名称,如模型配置中所定义。默认情况下,如果模型是通过 Eland 上传的,则输入字段为 text_field

POST _ml/trained_models/elastic__distilbert-base-uncased-finetuned-conll03-english/_infer
{
  "docs": [
    {
      "text_field": "Elastic is headquartered in Mountain View, California."
    }
  ]
}

该 API 返回类似于以下的响应

{
  "inference_results": [
    {
      "predicted_value": "[Elastic](ORG&Elastic) is headquartered in [Mountain View](LOC&Mountain+View), [California](LOC&California).",
      "entities": [
        {
          "entity": "elastic",
          "class_name": "ORG",
          "class_probability": 0.9958921231805256,
          "start_pos": 0,
          "end_pos": 7
        },
        {
          "entity": "mountain view",
          "class_name": "LOC",
          "class_probability": 0.9844731508992688,
          "start_pos": 28,
          "end_pos": 41
        },
        {
          "entity": "california",
          "class_name": "LOC",
          "class_probability": 0.9972361009811214,
          "start_pos": 43,
          "end_pos": 53
        }
      ]
    }
  ]
}

使用示例文本“Elastic is headquartered in Mountain View, California.”,该模型找到三个实体:一个组织“Elastic”和两个地点“Mountain View”和“California”。

将 NER 模型添加到推理摄取管道

编辑

您可以使用摄取管道中的推理处理器在摄取文档时对文档执行批量推理。维克多·雨果的小说《悲惨世界》用作以下示例中的推理示例。下载该小说文本(按段落分割)作为 JSON 文件,然后使用数据可视化工具上传。上传文件时,为新索引命名为 les-miserables

现在,可以在堆栈管理 UI中或通过 API 创建摄取管道

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 处理器提取实体并按类型进行分组。最终结果是在输入文本中检测到的人员、地点和组织的列表。此无痛脚本使您能够从创建的字段构建可视化。

on_failure 子句的目的是记录错误。它将 _index 元字段设置为一个新值,并且该文档现在存储在那里。它还设置了一个新字段 ingest.failure,并且错误消息将写入此字段。推理可能会因许多容易修复的原因而失败。也许该模型尚未部署,或者某些源文档中缺少输入字段。通过将失败的文档重定向到另一个索引并设置错误消息,这些失败的推理不会丢失,并且可以稍后查看。修复错误后,从失败的索引重新索引以恢复不成功的请求。

通过您创建的管道摄取小说文本 - 索引 les-miserables

POST _reindex
{
  "source": {
    "index": "les-miserables",
    "size": 50 
  },
  "dest": {
    "index": "les-miserables-infer",
    "pipeline": "ner"
  }
}

重新索引的默认批处理大小为 1000。将 size 减小到一个较小的数字会使重新索引过程的更新更快,这使您可以密切关注进度并及早检测到错误。

从源文档中随机选取一个段落作为示例

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

文本通过 NER 管道摄取后,查找存储在 Elasticsearch 中的结果文档

GET /les-miserables-infer/_search
{
  "query": {
    "term": {
      "line": 12700
    }
  }
}

请求返回的文档标记有一个已识别的人员

(...)
"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.000+01:00",
  "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.9452480789333386,
          "start_pos": 7,
          "end_pos": 19
        }
      ],
      "model_id": "elastic__distilbert-base-uncased-finetuned-conll03-english"
    }
  },
  "tags": {
    "PER": [
      "gillenormand"
    ]
  }
(...)

可视化结果

编辑

您可以创建一个标签云来可视化由推理管道处理的数据。标签云是一种可视化,它根据单词出现的频率来缩放单词的大小。它是查看数据中找到的实体的便捷工具。

在 Kibana 中,打开堆栈管理 > 数据视图,并从 les-miserables-infer 索引模式创建一个新的数据视图。

打开仪表板并创建一个新的仪表板。选择基于聚合类型的 > 标签云可视化。选择新的数据视图作为源。

添加一个带有术语聚合的新存储桶,选择 tags.PER.keyword 字段,并将大小增加到 20。

(可选)调整时间选择器以覆盖数据视图中的数据点(如果您在创建数据视图时选择了时间字段)。

更新并保存可视化。

Tag cloud created from Les Misérables