写点什么

手把手教学构建农业知识图谱:农业领域的信息检索 + 智能问答,命名实体识别,关系抽取,实体关系查询

  • 2023-07-07
    浙江
  • 本文字数:5226 字

    阅读完需:约 17 分钟

手把手教学构建农业知识图谱:农业领域的信息检索+智能问答,命名实体识别,关系抽取,实体关系查询

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.csvLOAD 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 lineCREATE (: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 lineMATCH (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 lineMATCH (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 lineMATCH (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 lineMATCH (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 lineMATCH (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 lineMATCH (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 lineMERGE (: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 lineMATCH (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 lineMATCH (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 工具进行分词,词性标注,命名实体识别(仅人名,地名,机构名) 为了识别农业领域特定实体,我们需要:


  1. 分词,词性标注,命名实体识别

  2. 以识别为命名实体(person,location,organzation)的,若实体库没有,可以标注出来

  3. 对于非命名实体部分,采用一定的词组合和词性规则,在 O(n)时间扫描所有分词,过滤掉不可能为农业实体的部分(例如动词肯定不是农业实体)

  4. 对于剩余词及词组合,匹配知识库中以分好类的实体。如果没有匹配到实体,或者匹配到的实体属于 0 类(即非实体),则将其过滤掉。

  5. 实体的分类算法见下文。

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:(命名实体的分类)

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


更多优质内容请关注公号 &知乎:汀丶人工智能;会提供一些相关的资源和优质文章,免费获取阅读。


项目码源见文章顶部或文末

项目码源点击跳转


发布于: 刚刚阅读数: 4
用户头像

本博客将不定期更新关于NLP等领域相关知识 2022-01-06 加入

本博客将不定期更新关于机器学习、强化学习、数据挖掘以及NLP等领域相关知识,以及分享自己学习到的知识技能,感谢大家关注!

评论

发布
暂无评论
手把手教学构建农业知识图谱:农业领域的信息检索+智能问答,命名实体识别,关系抽取,实体关系查询_人工智能_汀丶人工智能_InfoQ写作社区