文章目录
2构建农业类型树/demo/toolkit/tree_API.py
1编写get_leaf get_father get_branch函数/demo/toolkit
7.24
农业实体百科
在实体识别后,点击被识别出的实体可以进入实体的详细信息页,即农业实体百科。
1展示实体的基本信息,在之前实体识别中已经爬取相应数据存入hudong_pedia.csv、hudong_pedia2.csv,从数据库中获取即可。
2获取相关概念以词云形式展现。
3农业类型从树中获得。
其中2使用词向量技术,3使用dfs等算法。
经过思考,将农业实体百科细化为以下步骤:
1detail_view.py接收GET请求数据
2连接数据库获取提前加载好的实体基本信息。
3调用vec_API.py获取与当前实体相似度最高的十个实体的title。
4调用tree_API.py返回农业类型。返回根到叶子节点的路径。
例如:农业 / 可以食用的植物 / 水果 / 西瓜
5还需要调用NER.py获取label和detail explain。
1构建词云/demo/toolkit/vec_API.py
使用之前生成的15维的命名实体title的向量vector_15.txt,
词云采用词向量技术,这里根据输入命名实体向量计算其他命名实体向量与他的余弦相似度,获取固定数量的相似度从高到低的命名实体返回。
vec_API.py
def get_simi_top(self, word , top_num):
top_num += 1
vec = self.wv[word]
curword = []
cursimi = []
for key,value in self.wv.items():
if len(key) > 12:
continue
if random.randint(0,100) < 70: #留百分8数据
continue
if key == word:
continue
simi = cos_simi(vec, value)
curword.append(key)
cursimi.append(simi)
continue
p = len(curword)-1
if p <= 0:
curword.append(key)
cursimi.append(simi)
continue
while p>=0 :
if simi < cursimi[p]:
curword.insert(p+1, key)
cursimi.insert(p+1, simi)
break
if p == 0:
curword.insert(p, key)
cursimi.insert(p, simi)
break
p-=1
if len(curword) > top_num:
curword = curword[:top_num]
cursimi = cursimi[:top_num]
answord = []
vis = set()
top_num -= 1
for t in range(top_num):
maxx = -9999999
maxword = ''
for i in range(len(curword)):
if curword[i] in vis:
continue
if cursimi[i]>maxx:
maxx = cursimi[i]
maxword = curword[i]
answord.append(maxword)
vis.add(maxword)
return answord
2构建农业类型树/demo/toolkit/tree_API.py
1爬取百科中农业实体树形结构,存储为叶子结点leaf_list.txt,边micropedia_tree.txt。
2预加载需要读取农业层次树。编写根据上面两个txt文件构建农业层次树的方法。
tree_API.py
def read_edge(self, src):
self.edge = {} # 层次树邻接表
vis = set() # 去重
with open(src,'r',encoding="utf-8") as f:
for line in f.readlines():
if line in vis:
continue
vis.add(line)
cur = line.strip().split(' ')
u = str(cur[0])
v = str(cur[1])
if u not in self.edge:
self.edge[u] = []
self.edge[u].append(v)
def read_leaf(self, src):
self.leaf = {} # 记录叶子节点
vis = set() # 去重
with open(src,'r',encoding="utf-8") as f:
for line in f.readlines():
if line in vis:
continue
vis.add(line)
cur = line.strip().split(' ')
u = str(cur[0])
v = str(cur[1])
if u not in self.leaf:
self.leaf[u] = []
self.leaf[u].append(v)
3遍历农业层次树返回农业类型。即返回根到叶子节点的路径,可能存在多条路径,所以返回二维数组[路径数][路径]。使用dfs算法从根开始遍历树,遍历到叶子结点是title,则将该路径加入答案。
tree_API.py
def DFS(self, word, u):
#print(u)
self.curpath.append(u)
if u not in self.leaf or word not in self.leaf[u]: # 如果叶节点儿子中没有目标
pass
else: #返回路径
path = []
for p in self.curpath:
path.append(p)
path.append(word)
self.anspath.append(path) # 把该路径加入答案
if u not in self.edge: #儿子只有叶节点了
pass
else: # 递归儿子
for v in self.edge[u]:
self.DFS(word, v)
self.curpath.pop()
#返回根到叶子节点的路径
def get_path(self, word, unique): # 可能存在多条路径,所以返回二维数组[路径数][路径]
self.anspath = [] #unique 为true 代表筛选路径,去除过多重复的路径
self.curpath = []
self.DFS(word, self.root)
random.shuffle(self.anspath)
if unique == True :
for i in range(len(self.anspath)):
j = i + 1
while j < len(self.anspath):
seti = set(self.anspath[i])
setj = set(self.anspath[j])
unum = len(seti & setj)
if unum > 2:
del self.anspath[j]
else:
j += 1
return self.anspath
7.25
农业知识概览
能够列出某一农业分类下的词条列表,这些概念以树形结构组织在一起。之前实现农业实体百科的农业类型时已经构建了农业类型树,这里只需要获取这棵树即可。但是之前编写的tree_API.py已经不能满足需求,这里需要再增加几个新函数实现功能。
1overview_view.py调用tree_API.py中的get_leaf函数获得当前分类的所有实体即所有叶子结点并按字母顺序排序显示,这里使用了pinyin获取中文首字母小工具。
2overview_view.py调用tree_API.py中的get_father函数从而可显示当前分类专题的上级分类,调用get_branch函数从而可显示下级分类。
3 overview_view.py调用tree_API.py中的create_UI函数通过dfs算法构建树结构显示出来。
1编写get_leaf get_father get_branch函数/demo/toolkit
def get_father(self, word): # 获得word结点的所有父节点
ansList = []
for k,v in self.edge.items():
if word in v:
ansList.append(k)
return ansList
def get_branch(self, word): # 获得word结点的非叶儿子结点
ansList = []
for k,v in self.edge.items():
if k == word:
ansList = v
break
return ansList
def get_leaf(self, word): # 获得word结点的所有叶子儿子
if word not in self.leaf:
return []
return self.leaf[word]
2 dfs算法生成树形结构/demo//toolkit
tree_API.py
def DFS_create_UI(self, u, depth): # 通过dfs生成树形结构代码
cur = ''
if len(self.anspath) > depth and u == self.anspath[depth]:
self.UI_str += ' <li> <span>'
cur = '<i class="fa fa-minus-square" aria-hidden="true"></i> '
if len(self.anspath) == depth + 1:
cur = '<i class="fa fa-plus-square" aria-hidden="true"></i> '
else:
self.UI_str += ' <li style="display: none;"> <span>'
cur = '<i class="fa fa-plus-square" aria-hidden="true"></i> '
if u in self.edge and len(self.edge[u]) > 0:
self.UI_str += cur
else:
pass
self.UI_str += str(u) + '</span>'
if str(u) == self.anspath[len(self.anspath)-1]:
self.UI_str += ' 当前分类'
else:
self.UI_str += ' <a href="overview?node=' + str(u) + '"> [进入分类]</a>'
if u in self.edge and len(self.edge[u]) > 0:
self.UI_str += '<ul>'
for v in self.edge[u]:
self.DFS_create_UI(v, depth+1)
self.UI_str += '</ul>'
self.UI_str += '</li>'
def DFS2(self, theme, u):
n = len(self.anspath)
if n>0 and self.anspath[n-1] == theme:
return
self.anspath.append(u)
if u in self.edge:
for v in self.edge[u]:
self.DFS2(theme, v)
n = len(self.anspath)
if n>0 and self.anspath[n-1] == theme:
return
self.anspath.pop()
def create_UI(self,theme): # 生成UI代码
self.anspath = []
self.DFS2(theme, self.root) # 此时self.anspath为目标路径(一条)
self.UI_str = "<ul>"
self.DFS_create_UI(self.root,0)
self.UI_str += "</ul>"
return self.UI_str