手把手教学构建农业知识图谱:农业畛域的信息检索+智能问答,命名实体辨认,关系抽取,实体关系查问
1.我的项目介绍:
成果展现:
- 目录构造:
.
├── MyCrawler // scrapy爬虫我的项目门路(已爬好)
│ └── MyCrawler
│ ├── data
│ └── spiders
├── data\ processing // 数据荡涤(已无用)
│ └── data
├── demo // django我的项目门路
│ ├── Model // 模型层,用于封装Item类,以及neo4j和csv的读取
│ ├── demo // 用于写页面的逻辑(View)
│ ├── label_data // 标注训练集页面的保留门路
│ │ └── handwork
│ ├── static // 动态资源
│ │ ├── css
│ │ ├── js
│ │ └── open-iconic
│ ├── templates // html页面
│ └── toolkit // 工具库,包含预加载,命名实体辨认
│ └── KNN_predict
├── KNN_predict // KNN算法预测标签
├── dfs_tree_crawler // 爬取互动百科农业实体树形构造的爬虫
└── wikidataSpider // 爬取wiki中的关系
- 可复用资源
- hudong_pedia.csv : 曾经爬好的农业实体的百科页面的结构化csv文件
- labels.txt: 5000多个手工标注的实体类别
- predict_labels.txt: KNN算法预测的15W多个实体的类别
- /wikidataSpider/wikidataProcessing/wikidata_relation.csv: predict_labels.txt中实体在wikidata中对应的三元组关系
- attributes.csv: 局部实体的属性(互动百科页面中间接失去)
- wikidataSpider/weatherData/static_weather_list.csv: 气象类型列表
- wikidataSpider/weatherData/weather_plant.csv:气象与动物的种植关系
- wikidataSpider/weatherData/city_weather.csv:城市与气象的关系
我的项目码源见文章顶部或文末
我的项目码源点击跳转
2.我的项目配置
0.装置根本环境:
确保装置好python3和Neo4j(任意版本)
装置一系列pip依赖: cd至我的项目根目录,运行 sudo pip3 install -r requirement.txt
1.导入数据:
将hudong_pedia.csv导入neo4j:开启neo4j,进入neo4j控制台。将hudong_pedia.csv放入neo4j装置目录下的/import目录。在控制台顺次输出:
// 将hudong_pedia.csv 导入
LOAD CSV WITH HEADERS FROM "file:///hudong_pedia.csv" AS line
CREATE (p:HudongItem{title:line.title,image:line.image,detail:line.detail,url:line.url,openTypeList:line.openTypeList,baseInfoKeyList:line.baseInfoKeyList,baseInfoValueList:line.baseInfoValueList})
// 新增了hudong_pedia2.csv
LOAD CSV WITH HEADERS FROM "file:///hudong_pedia2.csv" AS line
CREATE (p:HudongItem{title:line.title,image:line.image,detail:line.detail,url:line.url,openTypeList:line.openTypeList,baseInfoKeyList:line.baseInfoKeyList,baseInfoValueList:line.baseInfoValueList})
// 创立索引
CREATE CONSTRAINT ON (c:HudongItem)
ASSERT c.title IS UNIQUE
以上两步的意思是,将hudong_pedia.csv导入neo4j作为结点,而后对titile属性增加UNIQUE(惟一束缚/索引)
(如果导入的时候呈现neo4j jvm内存溢出,能够在导入前,先把neo4j下的conf/neo4j.conf中的dbms.memory.heap.initial_size 和dbms.memory.heap.max_size调大点。导入实现后再把值改回去)
进入/wikidataSpider/wikidataProcessing中,将new_node.csv,wikidata_relation.csv,wikidata_relation2.csv三个文件放入neo4j的import文件夹中(运行relationDataProcessing.py能够失去这3个文件),而后别离运行
// 导入新的节点
LOAD CSV WITH HEADERS FROM "file:///new_node.csv" AS line
CREATE (:NewNode { title: line.title })
//增加索引
CREATE CONSTRAINT ON (c:NewNode)
ASSERT c.title IS UNIQUE
//导入hudongItem和新退出节点之间的关系
LOAD CSV WITH HEADERS FROM "file:///wikidata_relation2.csv" AS line
MATCH (entity1:HudongItem{title:line.HudongItem}) , (entity2:NewNode{title:line.NewNode})
CREATE (entity1)-[:RELATION { type: line.relation }]->(entity2)
LOAD CSV WITH HEADERS FROM "file:///wikidata_relation.csv" AS line
MATCH (entity1:HudongItem{title:line.HudongItem1}) , (entity2:HudongItem{title:line.HudongItem2})
CREATE (entity1)-[:RELATION { type: line.relation }]->(entity2)
导入实体属性(数据起源: 互动百科)
将attributes.csv放到neo4j的import目录下,而后执行
LOAD CSV WITH HEADERS FROM "file:///attributes.csv" AS line
MATCH (entity1:HudongItem{title:line.Entity}), (entity2:HudongItem{title:line.Attribute})
CREATE (entity1)-[:RELATION { type: line.AttributeName }]->(entity2);
LOAD CSV WITH HEADERS FROM "file:///attributes.csv" AS line
MATCH (entity1:HudongItem{title:line.Entity}), (entity2:NewNode{title:line.Attribute})
CREATE (entity1)-[:RELATION { type: line.AttributeName }]->(entity2);
LOAD CSV WITH HEADERS FROM "file:///attributes.csv" AS line
MATCH (entity1:NewNode{title:line.Entity}), (entity2:NewNode{title:line.Attribute})
CREATE (entity1)-[:RELATION { type: line.AttributeName }]->(entity2);
LOAD CSV WITH HEADERS FROM "file:///attributes.csv" AS line
MATCH (entity1:NewNode{title:line.Entity}), (entity2:HudongItem{title:line.Attribute})
CREATE (entity1)-[:RELATION { type: line.AttributeName }]->(entity2)
//咱们建索引的时候带了label,因而只有应用label时才会应用索引,这里咱们的实体有两个label,所以一共做2*2=4次。当然,能够建设全局索引,即对于不同的label应用同一个索引
导入气象名称:
将wikidataSpider/weatherData/static_weather_list.csv放在指定的地位(import文件夹下)
//导入节点
LOAD CSV WITH HEADERS FROM "file:///static_weather_list.csv" AS line
MERGE (:Weather { title: line.title })
//增加索引
CREATE CONSTRAINT ON (c:Weather)
ASSERT c.title IS UNIQUE
导入气象与动物的关系
将wikidataSpider/weatherData/weather_plant.csv放在指定的地位(import文件夹下)
//导入hudongItem和新退出节点之间的关系
LOAD CSV WITH HEADERS FROM "file:///weather_plant.csv" AS line
MATCH (entity1:Weather{title:line.Weather}) , (entity2:HudongItem{title:line.Plant})
CREATE (entity1)-[:Weather2Plant { type: line.relation }]->(entity2)
导入城市的气象
将city_weather.csv放在指定的地位(import 文件夹下)
(这步大概须要15分钟左右)
//导入城市对应的气象
LOAD CSV WITH HEADERS FROM "file:///city_weather.csv" AS line
MATCH (city{title:line.city}) , (weather{title:line.weather})
CREATE (city)-[:CityWeather { type: line.relation }]->(weather)
以上步骤是导入爬取到的关系
2.下载词向量模型:(如果只是为了运行我的项目,步骤2能够不做,预测后果曾经离线解决好了)
3.批改Neo4j用户
进入demo/Model/neo_models.py,批改第9行的neo4j账号密码,改成你本人的
4.启动服务
进入demo目录,而后运行脚本:
sudo sh django_server_start.sh
这样就胜利的启动了django。咱们进入8000端口主页面,输出文本,即可看到以下命名实体和分词的后果(确保django和neo4j都处于开启状态)
2.1农业知识问答
2.2关系查问
- 批改局部配置信息
- 关系查问中,增加了2个实体间的最短路查问,从而挖掘出实体之间一些奇怪的隐含关系
2.3农业实体辨认+实体分类
点击实体的超链接,能够跳转到词条页面(词云采纳了词向量技术):
2.3.1实体查问
实体查问局部,咱们可能搜寻出与某一实体相干的实体,以及它们之间的关系:
2.3.2关系查问
关系查问即查问三元组关系entity1-[relation]->entity2 , 分为如下几种状况:
- 指定第一个实体entity1
- 指定第二个实体entity2
- 指定第一个实体entity1和关系relation
- 指定关系relation和第二个实体entity2
- 指定第一个实体entity1和第二个实体entity2
- 指定第一个实体entity1和第二个实体entity2以及关系relation
下图所示,是指定关系relation和第二个实体entity2的查问后果
2.4常识的树形构造
农业知识概览局部,咱们可能列出某一农业分类下的词条列表,这些概念以树形构造组织在一起:
农业分类的树形图:
2.5训练集标注
咱们还制作了训练集的手动标注页面,每次会随机的跳出一个未标注过的词条。链接:http://localhost:8000/tagging-get , 手动标注的后果会追加到/label_data/labels.txt文件开端:
咱们将这部分做成了小工具,可复用:https://github.com/qq547276542/LabelMarker
(update 2018.04.07) 同样的,咱们制作了标注关系提取训练集的工具,如下图所示
如果Statement的标签是对的,点击True按钮;否则抉择一个关系,或者输出其它关系。若以后句子无奈判断,则点击Change One按钮换一条数据。
阐明: Statement是/wikidataSpider/TrainDataBaseOnWiki/finalData中train_data.txt中的数据,咱们将它转化成json,导入到mongoDB中。标注好的数据同样存在MongoDB中另一个Collection中。对于Mongo的应用办法能够参考官网tutorial,或者利用这篇文章简略理解一下MongoDB
咱们在MongoDB中应用两个Collections,一个是train_data,即未经人工标注的数据;另一个是test_data,即人工标注好的数据。
应用办法: 启动neo4j,mongodb之后,进入demo目录,启动django服务,进入127.0.0.1:8000/tagging即可应用
3.命名实体辨认:
应用thulac工具进行分词,词性标注,命名实体辨认(仅人名,地名,机构名)
为了辨认农业畛域特定实体,咱们须要:
- 分词,词性标注,命名实体辨认
- 以辨认为命名实体(person,location,organzation)的,若实体库没有,能够标注进去
- 对于非命名实体局部,采纳肯定的词组合和词性规定,在O(n)工夫扫描所有分词,过滤掉不可能为农业实体的局部(例如动词必定不是农业实体)
- 对于残余词及词组合,匹配知识库中以分好类的实体。如果没有匹配到实体,或者匹配到的实体属于0类(即非实体),则将其过滤掉。
- 实体的分类算法见下文。
3.1实体分类:
3.1.1特征提取:
3.1.2分类器:KNN算法
- 无需示意成向量,比拟类似度即可
- K值通过网格搜寻失去
-
定义两个页面的类似度sim(p1,p2):
- title之间的词向量的余弦类似度(利用fasttext计算的词向量可能防止out of vocabulary)
- 2组openType之间的词向量的余弦类似度的平均值
- 雷同的baseInfoKey的IDF值之和(因为‘中文名’这种属性奉献应该比拟小)
- 雷同baseInfoKey下baseInfoValue雷同的个数
- 预测一个页面时,因为KNN要将该页面和训练集中所有页面进行比拟,因而每次预测的复杂度是O(n),n为训练集规模。在这个过程中,咱们能够统计各个分类似度的IDF值,均值,方差,标准差,而后对4个类似度进行标准化:(x-均值)/方差
- 下面四个局部的类似度的加权和为最终的两个页面的类似度,权值由向量weight管制,通过10折叠穿插验证+网格搜寻失去
3.2 Labels:(命名实体的分类)
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”,“计算机”,“爱鸟周”,“人民币”,“《本草纲目》”,“花岗岩” |
4.农业知识图谱关系抽取
应用近程监督办法构建数据集,利用tensorflow训练PCNN模型
4.1关系主动抽取
农业知识图谱关系抽取
- data
解决数据集,失去关系抽取须要用到的json文件
步骤:
- 如果以后文件夹下没有
filter_train_data_all_deduplication.txt
, 那么进入wikidataSpider目录,依据TrainDataBaseOnWiki/readme.md中所述办法,取得filter_train_data_all_deduplication.txt
(生成数据工夫比拟长,倡议用公开数据集测试。应用公开数据集,间接从进入Algorithm,疏忽之后所有的操作) - 运行
python dosomething.py filter_dataset
失去filtered_data.txt
- 运行
python preprocessing.py rel2id
失去rel2id.json - 运行
python preprocessing.py dataset.json
失去dataset.json - 运行
python preprocessing.py word2vecjson
失去word2vec.json - 运行
python preprocessing.py entity2id
失去entity2id.json - 运行
python preprocessing.py dataset_split
失去train_dataset.json和test_dataset.json
失去的rel2id.json,word2vec.json,entity2id.json,train_dataset.json和test_dataset.json为关系提取算法所需的数据,将其放在algorithm的data/agriculture目录下
4.2 关系提取的算法
关系提取的算法局部,tensorflow实现,代码框架以及PCNN的实现参照https://github.com/thunlp/OpenNRE
更多优质内容请关注公号&知乎:汀丶人工智能;会提供一些相干的资源和优质文章,收费获取浏览。
我的项目码源见文章顶部或文末
我的项目码源点击跳转
本文参加了 SegmentFault 思否写作挑战「摸索编码世界之旅 – 记我的第一份编程工作」,欢送正在浏览的你也退出。
发表回复