Pyltp安装以及利用Pyltp进行命名实体识别
pyltp环境的搭建:
在终端安装pyltp时一般会报错:
使用wheel方法:
-
下载wheels
下面两个文件针对不同的python版本下载一个即可
python-3.5: pyltp-0.2.1-cp35-cp35m-win_amd64.whl
https://pan.baidu.com/s/1Ekx3dHVzt5raXtiuH-S9qwpython-3.6: pyltp-0.2.1-cp36-cp36m-win_amd64.whl
https://pan.baidu.com/s/19ND7L6baJoAKNQtfSDXEZA -
安装wheel
下载好以后,在命令行下,cd到wheel文件所在目录,
然后使用命令 pip install wheel文件名 进行安装 -
测试
安装好了以后,使用一下: -
下载model数据
下载地址:
https://pan.baidu.com/share/link?shareid=1988562907&uk=2738088569#list/path=%2F
在文件夹Itp_data_v3.4.0中存放在分句,分词,词性标注,命名实体识别等的model文件,将该文件夹放到任意方便调用的地方即可,因为程序里需要自己主动调用
pyltp进行命名实体识别:
利用pyltp进行命名实体识别,首先需要对所操作的文本进行分词和词性标注,官方对于命名实体识别的实例如下:
LTP 采用 BIESO标注体系。B 表示实体开始词,I表示实体中间词,E表示实体结束词,S表示单独成实体,O表示不构成命名实体。
LTP 提供的命名实体类型为:人名(Nh)、地名(Ns)、机构名(Ni)。
B、I、E、S位置标签和实体类型标签之间用一个横线 - 相连;O标签后没有类型标签。
命名实体识别程序:
# coding=UTF-8
#打开需要命名实体识别的文本
with open(r'chn.txt', encoding="UTF-8", errors='ignore') as file_object:
sss = file_object.read()
#分词
import os
LTP_DATA_DIR = 'C:\python_work\ltp_data_v3.4.0' # ltp模型目录的路径
cws_model_path = os.path.join(LTP_DATA_DIR, 'cws.model') # 分词模型路径,模型名称为`cws.model`
from pyltp import Segmentor
segmentor = Segmentor() # 初始化实例
segmentor.load(cws_model_path) # 加载模型
words = segmentor.segment(sss) # 分词
words_list = list(words) #words_list列表保存着分词的结果
segmentor.release() # 释放模型
#词性标注
import os
LTP_DATA_DIR = 'C:\python_work\ltp_data_v3.4.0' # ltp模型目录的路径
pos_model_path = os.path.join(LTP_DATA_DIR, 'pos.model') # 词性标注模型路径,模型名称为`pos.model`
from pyltp import Postagger
postagger = Postagger() # 初始化实例
postagger.load(pos_model_path) # 加载模型
postags = postagger.postag(words) # 词性标注
postags_list = list(postags) #postags_list保存着词性标注的结果
postagger.release() # 释放模型
#命名实体识别
import os
LTP_DATA_DIR = 'C:\python_work\ltp_data_v3.4.0' # ltp模型目录的路径
ner_model_path = os.path.join(LTP_DATA_DIR, 'ner.model') # 命名实体识别模型路径,模型名称为`pos.model`
from pyltp import NamedEntityRecognizer
recognizer = NamedEntityRecognizer() # 初始化实例
recognizer.load(ner_model_path) # 加载模型
netags = recognizer.recognize(words, postags) # 命名实体识别
netags_list = list(netags) #netags_list保存着命名实体识别的结果
recognizer.release() # 释放模型
#去除非命名实体
a = len(words_list)
words_list_1=[]
postags_list_1=[]
netags_list_1=[]
i = 0
while i < a:
if netags_list[i] != 'O':
words_list_1.append(words_list[i])
postags_list_1.append(postags_list[i])
netags_list_1.append(netags_list[i])
i += 1
a1 = len(words_list_1)
#提取机构名
i = 0
orignizations=[]
while i<a1:
if netags_list_1[i] == 'S-Ni':
orignizations.append(words_list_1[i])
elif netags_list_1[i] == 'B-Ni':
temp_s = ''
temp_s += words_list_1[i]
j = i+1
while j<a1 and (netags_list_1[j]=='I-Ni' or netags_list_1[j]=='E-Ni'):
temp_s += words_list_1[j]
j += 1
orignizations.append(temp_s)
i += 1
#删除重重出现的机构名
orignizations_1 = set(orignizations)
orignizations_2 = list(orignizations_1)
f_4=open('C:\python_work\pyltp\orignizations.txt','w', encoding='UTF-8',errors='ignore')
for orignization in orignizations_2:
f_4.write(orignization+'\r\n')
#提取地名
i = 0
places=[]
while i<a1:
if netags_list_1[i] == 'S-Ns':
places.append(words_list_1[i])
elif netags_list_1[i] == 'B-Ns':
temp_s = ''
temp_s += words_list_1[i]
j = i+1
while j<a1 and (netags_list_1[j]=='I-Ns' or netags_list_1[j]=='E-Ns'):
temp_s += words_list_1[j]
j += 1
places.append(temp_s)
i += 1
#删除重复出现的地名
places_1 = set(places)
places_2 = list(places_1)
f_5=open('C:\python_work\pyltp\places.txt','w', encoding='UTF-8',errors='ignore')
for place in places_2:
f_5.write(place+'\r\n')
#设计一些规则去除一些不符合要求的实体
places_len2 = len(places_2)
j = 0
places_3 = [] #places_3存在最终的地名
while j <places_len2:
flag = 0
len_2 = len(places_2[j])
if len_2 <= 1 or len_2 >3:
flag = 1
else:
i = 0
len_2 = len(places_2[j])
while i < len_2:
if places_2[j][i] =='。' or places_2[j][i]=='.' or places_2[j][i] == '\n':
flag = 1
if places_2[j][i]>='a' and places_2[j][i]<='z':
flag = 1
if places_2[j][i]>='0' and places_2[j][i]<='9':
flag = 1
i += 1
if flag == 0:
places_3.append(places_2[j])
j += 1
f_72=open('C:\python_work\pyltp\place_2.txt','w', encoding='UTF-8',errors='ignore')
for place3 in places_3:
f_72.write(place3+'\n')
#提取人名
i = 0
names=[]
while i<a1:
if netags_list_1[i] == 'S-Nh':
names.append(words_list_1[i])
elif netags_list_1[i] == 'B-Nh':
temp_s3 = ''
temp_s3 += words_list_1[i]
j = i+1
while (j<a1) and (netags_list_1[j]=='I-Nh' or netags_list_1[j]=='E-Nh'):
temp_s3 += words_list_1[j]
j += 1
names.append(temp_s3)
i += 1
#去除重复的人名
names_1 = set(names)
names_2 = list(names_1)
f_6=open('C:\python_work\pyltp\mingzi.txt','w', encoding='UTF-8',errors='ignore')
for name in names_2:
f_6.write(name+'\n')
#设计一些规则去除一些不符合要求的实体
names_len2 = len(names_2)
j = 0
names_3 = []
while j <names_len2:
flag = 0
len_2 = len(names_2[j])
if len_2 <= 1 or len_2 >3:
flag = 1
else:
i = 0
len_2 = len(names_2[j])
while i < len_2:
if names_2[j][i] =='。' or names_2[j][i]=='.' or names_2[j][i] == '\n':
flag = 1
if names_2[j][i]>='a' and names_2[j][i]<='z':
flag = 1
if names_2[j][i]>='0' and names_2[j][i]<='9':
flag = 1
i += 1
if flag == 0:
names_3.append(names_2[j])
j += 1
f_7=open('C:\python_work\pyltp\mingzi_2.txt','w', encoding='UTF-8',errors='ignore')
for name3 in names_3:
f_7.write(name3+'\n')
#将三个列表整合到一个字典中,写入文件
shiti = {}
for name in names_3:
shiti[name] = '人名'
for place in places_3:
shiti[place] = '地名'
for orignization in orignizations_2:
shiti[orignization] = '机构名'
f_shiti=open('C:\python_work\pyltp\shiti_2.txt','w', encoding='UTF-8',errors='ignore')
for key, value in shiti.items():
f_shiti.write(key+ '\t' + value + '\n')
识别结果:
程序说明:
-
首先调用模型进行分词,词性标注和命名实体识别,结果保存如下:
在调用模型是需要注意写入自己的model存放路径: -
去除非命名实体识别的部分:
-
然后分别提取出机构名,地名,和人名
注意去掉重复的实体:
并且设计一些设计一些规则,滤掉一部分噪声 -
最后将三个实体种类的列表整合到一个字典中去,写入文件