中文人名识别属于命名实体识别的范畴,解决问题的思路很多,但是在实际的应用过程中各种库做的参差不齐,下面是3个开源库的使用方法与效果展示:
在我的项目中,需要做的是在一个几乎没有逻辑可言的句子里识别人名,因此命名实体识别的效果很差,使用词法分析来提取人名,然后依据业务逻辑删减。因此越依赖上下文的方法,越会有问题,整体的效果是:智能云词法分析
>LTP
>LAC
>自然语言处理词法分析
>hanlp
其中:
LTP
中规中矩LAC
提取的量最少,但是只要提取出来,几乎是正确的hanlp
提取出来的量是最多的,但是一多半不是人名。
(这和下面的示例结果相反,很神奇)
示例
from LAC import LAC
def hanlp_username(sentences: str) -> list:
from pyhanlp import HanLP
segment = HanLP.newSegment().enableNameRecognize(True)
seg_words = segment.seg(sentences)
user_list = []
for value in seg_words:
split_words = str(value).split('/') # check //m
word, tag = split_words[0], split_words[-1]
if tag == 'nr':
user_list.append(word)
return user_list
def ltp_username(sentences: str) -> list:
from ltp import LTP
ltp = LTP() # 默认加载 Small 模型,下载的路径是:~/.cache/torch/ltp
seg, hidden = ltp.seg([sentences]) # 分词
nh_user_list = []
pos_index_values = ltp.pos(hidden)
# seg 是 list to list 的格式
for index, seg_i in enumerate(seg):
pos_values = pos_index_values[index]
for _index, _pos in enumerate(pos_values):
if _pos == "nh":
nh_user_list.append(seg_i[_index])
return nh_user_list
def lac_username(sentences: str) -> list:
# 装载LAC模型
user_name_list = []
lac = LAC(mode="lac")
lac_result = lac.run(sentences)
for index, lac_label in enumerate(lac_result[1]):
if lac_label == "PER":
user_name_list.append(lac_result[0][index])
return user_name_list
if __name__ == '__main__':
text = "周树人(1881年9月25日-1936年10月19日),原名周樟寿,字豫山、豫亭,后改字豫才,以笔名鲁迅聞名於世,浙江紹興人"
hanlp_user = hanlp_username(text)
lac_user = lac_username(text)
ltp_user = ltp_username(text)
print("hanlp:", hanlp_user)
print("LAC:", lac_user)
print("LTP:", ltp_user)
结果:
hanlp: ['周樟寿', '鲁迅']
LAC: ['周树人', '周樟寿', '鲁迅']
LTP: ['周树人', '周樟寿', '豫才', '鲁迅']