NLTK提取人名结果不准确,寻求Python更优解决方案
人名提取优化方案(替代NLTK的更优选择)
问题背景
用NLTK提取文本人名时出现以下问题:
- 常见人名
Elon Musk被拆分为Elon(PERSON)和Musk(GPE) Reshma Saujani未被识别为人名Barkevious Mingo被误判为ORGANIZATION
期望得到的正确输出:
Type: PERSON Name: Elon Musk Type: PERSON Name: Jeff Bezos Type: PERSON Name: Reshma Saujani Type: PERSON Name: Barkevious Mingo
更优方案:使用spaCy
spaCy的命名实体识别(NER)模型训练更充分,在人名提取的准确率上远高于NLTK默认模型。
1. 安装依赖
pip install spacy python -m spacy download en_core_web_sm
2. 提取人名代码
import spacy # 加载预训练的英文NER模型 nlp = spacy.load("en_core_web_sm") text = "Elon Musk 889-888-8888 elonpie@tessa.net Jeff Bezos (345)123-1234 bezzi@zonbi.com Reshma Saujani example.email@email.com 888-888-8888 Barkevious Mingo" # 处理文本生成文档对象 doc = nlp(text) # 遍历识别到的实体,筛选出PERSON类型 for ent in doc.ents: if ent.label_ == "PERSON": print(f'Type: {ent.label_} Name: {ent.text}')
输出结果
Type: PERSON Name: Elon Musk Type: PERSON Name: Jeff Bezos Type: PERSON Name: Reshma Saujani Type: PERSON Name: Barkevious Mingo
更高精度可选方案:Hugging Face Transformers
如果对准确率要求极高,可以用大语言模型做NER任务,比如dbmdz/bert-large-cased-finetuned-conll03-english模型,缺点是运行速度稍慢:
from transformers import pipeline # 初始化NER流水线,设置聚合策略合并连续的人名实体 ner_pipeline = pipeline("ner", model="dbmdz/bert-large-cased-finetuned-conll03-english", aggregation_strategy="simple") text = "Elon Musk 889-888-8888 elonpie@tessa.net Jeff Bezos (345)123-1234 bezzi@zonbi.com Reshma Saujani example.email@email.com 888-888-8888 Barkevious Mingo" results = ner_pipeline(text) # 筛选出PER类型(对应人名)的结果 for result in results: if result['entity_group'] == 'PER': print(f'Type: PERSON Name: {result["word"]}')
NLTK效果差的原因
NLTK的maxent_ne_chunker基于旧的最大熵模型训练,数据集规模和模型复杂度都远不如现代的spaCy或Transformer模型,因此在人名识别这类任务中容易出现误判、漏判。
内容的提问来源于stack exchange,提问作者getintoityuh
相关产品推荐
相关产品推荐

