一、概念
命名实体识别(Named Entity Recognition,简称 NER)是自NLP中的一项重要任务,它的目标是从文本中识别并分类出具有特定意义的实体。其中,实体通常包括但不限于人名、地名、组织名、日期、时间、货币、百分比等,具体取决于我们的任务需求。
-
实体(Entity): 实体是指文本中具有特定意义的词或短语。例如,在句子 "Barack Obama was born in Hawaii." 中,"Barack Obama" 是一个人名实体,"Hawaii" 是一个地名实体。
-
实体类别(Entity Type): 实体类别是对识别出的实体进行分类的标签。例如,人名(Person)、地名(Location)、组织名(Organization)、日期(Date)等。
-
标注(Annotation): 标注是指对文本中的实体进行标记和分类的过程。例如,将 "Barack Obama" 标注为人名(Person),将 "Hawaii" 标注为地名(Location)。此外,NER序列标注有多种方式,常见的是BIO标注(Begin、Inside、Outside)和BIOES(Begin、Inside、Outside、End、Single)标注。
# 例如这里我们进行地名识别,那么BIO标注格式如下:
今 O
天 O
我 O
来 O
到 O
了 O
北 B-Location
京 I-Location
, O
这 O
里 O
的 O
气 O
温 O
比 O
广 B-Location
州 I-Location
低 O
不 O
少 O
二、实现方法
NER 的方法可以分为基于规则的方法、基于统计的方法和基于深度学习的方法。下面我们逐个介绍每种方法的基本概念。
1、基于规则的方法
基于规则的方法使用预定义的规则和词典来识别和分类实体。这些规则通常包括正则表达式、模式匹配等。例如,可以使用正则表达式识别日期格式,使用词典匹配人名和地名。这种方法简单直观,易于理解和实现,且对特定领域的实体识别效果较好(当我们有一个庞大的领域词典时)。当然,规则的编写和维护成本相对较高,需要多次调整和探索才能得到一个符合预期的规则,但一旦应用到新领域和新实体,其适应性就会大打折扣。在实现上,基于规则的方法也比较简单直观,使用re库即可。
import re
# 示例文本
text = """
Barack Obama was born in Honolulu, Hawaii. He was the 44th President of the United States.
Apple Inc. is an American multinational technology company headquartered in Cupertino, California.
"""
# 预定义的词典
person_names = ["Barack Obama"]
location_names = ["Honolulu", "Hawaii", "United States", "Cupertino", "California"]
organization_names = ["Apple Inc."]
# 正则表达式模式
person_pattern = re.compile(r'\b(?:' + '|'.join(re.escape(name) for name in person_names) + r')\b')
location_pattern = re.compile(r'\b(?:' + '|'.join(re.escape(name) for name in location_names) + r')\b')
organization_pattern = re.compile(r'\b(?:' + '|'.join(re.escape(name) for name in organization_names) + r')\b')
# 识别实体
def recognize_entities(text):
entities = []
# 识别人名
for match in person_pattern.finditer(text):
entities.append((match.group(), "PERSON", match.start(), match.end()))
# 识别地名
for match in location_pattern.finditer(text):
entities.append((match.group(), "LOCATION", match.start(), match.end()))
# 识别组织名
for match in organization_pattern.finditer(text):
entities.append((match.group(), "ORGANIZATION", match.start(), match.end()))
return entities
# 识别并打印实体
entities = recognize_entities(text)
for entity in entities:
print(f"Entity: {entity[0]}, Type: {entity[1]}, Start: {entity[2]}, End: {entity[3]}")
2、基于统计的方法
基于统计的方法使用机器学习算法,通过训练数据学习实体识别和分类的模型,实际上就是传统的机器学习算法。常用的机器学习算法包括隐马尔可夫模型(HMM)、条件随机场(CRF)等。基于统计学习的方法能够自动学习和适应不同领域的实体识别,具有较好的泛化能力。当然,这需要大量的标注数据来进行训练。
3、基于深度学习的方法
基于深度学习的方法使用神经网络模型进行实体识别和分类。传统的神经网络模型包括循环神经网络(RNN)、长短期记忆网络(LSTM)、双向 LSTM(BiLSTM)、卷积神经网络(CNN)等。近年来,基于 Transformer 的模型(如 BERT等)在 NER 任务中也取得了显著的效果。此外,为了使得基于神经网络的NER输出符合逻辑,一般也会在最后的分类层加入一个诸如CRF的机器学习模型,例如我们再熟悉不过的Bert-BiLSTM-CRF、Bert-CRF模型等。基于深度学习的方法能够自动提取特征,减少特征工程的工作量,且在大规模数据上训练后具有很强的泛化能力和鲁棒性。基于深度学习的算法将在后续的实战篇章中进行python实操。