目录
7.21
实体识别
2构造训练集/demo/label_data
1 确定命名实体的分类:
Label | NE Tags | Example |
0 | Invalid(不合法) | “色调”,“文化”,“景观”,“条件”,“A”,“234年”(不是具体的实体,或一些脏数据) |
1 | Person(人物,职位) | “袁隆平”,“副市长” |
2 | Location(地点,区域) | “福建省”,“三明市”,“大明湖” |
3 | Organization(机构,会议) | “华东师范大学”,“上海市农业委员会” |
4 | Political economy(政治经济名词) | “惠农补贴”,“基本建设投资” |
5 | Animal(动物学名词,包括畜牧类,爬行类,鸟类,鱼类,等) | “绵羊”,“淡水鱼”,“麻雀” |
6 | Plant(植物学名词,包括水果,蔬菜,谷物,草药,菌类,植物器官,其他植物) | “苹果”,“小麦”,“生菜” |
7 | Chemicals(化学名词,包括肥料,农药,杀菌剂,其它化学品,术语等) | “氮”,“氮肥”,“硝酸盐”,“吸湿剂” |
8 | Climate(气候,季节) | “夏天”,“干旱” |
9 | Food items(动植物产品) | “奶酪”,“牛奶”,“羊毛”,“面粉” |
10 | Diseases(动植物疾病) | “褐腐病”,“晚疫病” |
11 | Natural Disaster(自然灾害) | “地震”,“洪水”,“饥荒” |
12 | Nutrients(营养素,包括脂肪,矿物质,维生素,碳水化合物等) | “维生素A”,"钙" |
13 | Biochemistry(生物学名词,包括基因相关,人体部位,组织器官,细胞,细菌,术语) | “染色体”,“血红蛋白”,“肾脏”,“大肠杆菌” |
14 | Agricultural implements(农机具,一般指机械或物理设施) | “收割机”,“渔网” |
15 | Technology(农业相关术语,技术和措施) | “延后栽培",“卫生防疫”,“扦插” |
16 | other(除上面类别之外的其它名词实体,可以与农业无关但必须是实体) | “加速度",“cpu”,“计算机”,“爱鸟周”,“人民币”,“《本草纲目》”,“花岗岩” |
2将有效的页面内容中的title存到word_list.txt。
3将word_list.txt作为输入,将一些关键字作为筛选条件编写Tagging_seed.py标注一些很明显的实体和一些不合法的数据,共5000+。
7.22
实体识别
3预测lebal实现实体分类/KNN_predict
fasttext是由facebook在2016年推出的一个训练词向量的模型。相比于之前Google的word2vec,fasttext可以解决out of vocabulary的问题,能够用于有监督的文本分类。
facebook提供了200多种语言的预训练模型和词向量。
1使用预训练好的中文词向量模型wiki.zh.bin,将csv转化为词向量。训练15维的词向量嵌入模型。
create_vec.py
def create_predict(HudongItem_csv):
# 读取neo4j内容
db = Neo4j()
db.connectDB()
predict_List = readCSVbyColumn(HudongItem_csv, 'title')
file_object = open('vector.txt','a')
model = FastText('wiki.zh.bin')
count = 0
vis = set()
for p in predict_List:
cur = HudongItem(db.matchHudongItembyTitle(p))
count += 1
title = cur.title
if title in vis:
continue
vis.add(title)
wv_list = model[title]
strr = str(title)
for p in wv_list:
strr += ' '+str(p)[:7]
file_object.write(strr+"\n")
print(str(count)+' / '+str(len(predict_List)))
file_object.close()
2根据页面内容提取特征,构造相似度的比较方法。
title名称:求出title之间词向量的余弦相似度,避免out of vocabulary。
openTypeList开放分类:求出两组openTypeList中的词向量的余弦相似度,再求平均值
baseInfoKeyList基本信息关键字:baseInfoKeyList之间的逆文本频率指数(Inverse Document Frequency)值之和
baseInfoValueList基本信息值:相同baseInfoKey下baseInfoValue相同的个数
对于没有openTypeList的,赋予平均值。
对title和openTypeList进行高斯归一。
对后面两项进行maxmin归一。
计算各项相似度的加权和,权值通过交叉验证和网格搜索求得。
classifier.py
for p in self.labeled_hudongList: # 预先计算存储各分量相似度
if p.title == item.title: # 如果训练集已经有,直接返回label
return p.label
title_simi.append(self.get_title_simi(p, item))
openTypeList_simi.append(self.get_openTypeList_simi(p, item))
baseInfoKeyList_simi.append(self.get_baseInfoKeyList_simi(p, item))
baseInfoValueList_simi.append(self.get_baseInfoValueList_simi(p, item))
mean[0] += title_simi[i]
mean[1] += openTypeList_simi[i]
mean[2] += baseInfoKeyList_simi[i]
maxx[2] = max(maxx[2],baseInfoKeyList_simi[i])
minn[2] = min(minn[2],baseInfoKeyList_simi[i])
mean[3] += baseInfoValueList_simi[i]
maxx[3] = max(maxx[3],baseInfoValueList_simi[i])
minn[3] = min(minn[3],baseInfoValueList_simi[i])
i += 1
for i in range(4):
mean[i] /= len(self.labeled_hudongList)
for p in self.labeled_hudongList: # 计算方差
var[0] += (title_simi[i]-mean[0])*(title_simi[i]-mean[0])
var[1] += (openTypeList_simi[i]-mean[1])*(openTypeList_simi[i]-mean[1])
var[2] += (baseInfoKeyList_simi[i]-mean[2])*(baseInfoKeyList_simi[i]-mean[2])
var[3] += (baseInfoValueList_simi[i]-mean[3])*(baseInfoValueList_simi[i]-mean[3])
for i in range(4):
if var[i] ==0.0:
var[i] = 0.000000001
for i in range(4):
stand[i] = sqrt(var[i])
# 对于没有openTypeList的 ,赋予平均值
# 对title和openTypeList进行高斯归一,对后面两项进行maxmin归一
i = 0
for p in self.labeled_hudongList:
title_simi[i] = (title_simi[i]-mean[0])/stand[0]
if openTypeList_simi[i] == 0.0: #对于没有出现的,赋予平均值
openTypeList_simi[i] = mean[1]
openTypeList_simi[i] = (openTypeList_simi[i]-mean[1])/stand[1]
if baseInfoKeyList_simi[i] == 0.0: #对于没有出现的,赋予平均值
baseInfoKeyList_simi[i] = mean[2]
baseInfoKeyList_simi[i] = (baseInfoKeyList_simi[i]-mean[2])/stand[2]
baseInfoValueList_simi[i] = (baseInfoValueList_simi[i]-mean[3])/stand[3]
i+=1
i = 0
count = 0
for p in self.labeled_hudongList: # 计算各项相似度的加权和
s = self.weight[0]*title_simi[i] + self.weight[1]*openTypeList_simi[i] + self.weight[2]*baseInfoKeyList_simi[i] + self.weight[3]*baseInfoValueList_simi[i]
count += 1
if count < 2:
pass
# print(str(title_simi[i])+" "+str(openTypeList_simi[i])+" "+str(baseInfoKeyList_simi[i])+" "+str(baseInfoValueList_simi[i]))
i += 1
l = p.label
t = p.title
curList.append(Node(s,l,t))
3使用5000多个手工标注的实体类别labels.txt作为训练集,使用KNN算法通过对相似度进行排序,相似度最高的实体的lebal即为该实体的lebal。
4最后获取每个词条的所属类别,预测其他实体的类别存入predict_labels.txt。剔除不属于农业的无关词条。
predict.py
for p in predict_List:
cur = HudongItem(db.matchHudongItembyTitle(p))
count += 1
title = cur.title
if title in vis:
continue
vis.add(title)
label = classifier.KNN_predict(cur)
file_object.write(str(title)+" "+str(label)+"\n")
7.23
实体识别
4编写接口/demo/toolkit
编写接口NER.py放在toolkit子目录下。
功能:根据文本返回实体列表
逻辑如下:
1读取thulac,neo4j,使用thulac工具进行分词标注词性。
2读取实体类别
3 通过判断每个词是否在predict_labels.txt中来判断是否为实体,判断数据库中hudong_pedia是否存在该实体返回不同值,1~16代表数据库中存在的不同类别的命名实体,0代表非实体。
如果返回为1-16,再使用NER.py中的其他函数返回其解释及详细解释。返回的'np','ns'等英文代表返回的是数据库中不存在的命名实体,没有匹配到实体,或者匹配到的实体属于0类(即非实体),则将其过滤掉。
NER.py
def get_NE(text):
# 读取thulac,neo4j,分词
thu1 = pre_load_thu
db = neo_con
TagList = thu1.cut(text, text=False)
TagList.append(['===',None]) #末尾加个不合法的,后面好写
# 读取实体类别,注意要和predict_labels.txt一个目录
label = predict_labels
answerList = []
i = 0
length = len(TagList) - 1 # 扣掉多加的那个
while i < length:
p1 = TagList[i][0]
t1 = TagList[i][1]
p2 = TagList[i+1][0]
t2 = TagList[i+1][1]
p12 = p1 + TagList[i+1][0]
# 不但需要txt中有实体,还需要判断数据库中有没有
flag = db.matchHudongItembyTitle(p12)
if p12 in label and flag != None and preok(t1) and nowok(t2): # 组合2个词如果得到实体
answerList.append([p12,label[p12]])
i += 2
continue
flag = db.matchHudongItembyTitle(p1)
if p1 in label and flag != None and nowok(t1): # 当前词如果是实体
answerList.append([p1,label[p1]])
i += 1
continue
if temporaryok(t1):
answerList.append([p1,t1])
i += 1
continue
answerList.append([p1,0])
i += 1
return answerList