OpenNER关系抽取代码阅读

继上文阅读了论文Neural Relation Extraction with Selective Attention over Instances后,就找源码来修修改改以完成关系抽取的任务。
论文源码是C++实现,在其github上面找到另一个整合了几篇论文更好的框架OpenNER

遇到的坑

no module named framework

这不是少包,这是包在目录下没找到,只需要在import framework的地方修改为from . import framework即可

NYT数据准备

readme提供的数据链接下载下来后还要运行它提供的py文件才可以。而Py文件注意是python2.x的版本(强行转3有点坑)。

json格式

json需要用代码生成,如果直接手写内容的,会报编码错误

载入文件

如果训练文件发生修改,则需要把process_data下的文件删除干净,否则默认读取上一次预处理好的文件

需要调整参数

  • batchsize:如果样本集很少的时候要把batchsize调整到合适的位置(默认160)
  • word_embeddingsize:词向量的维度(默认50)

中文数据格式

由于里面提供的是英文格式,关系抽取需要做中文的,所以这里记录一下中文的格式。词向量现在是随机,到时候肯定要用预模型。

import thulac
import numpy as np
import json
# 生成词向量
thu1 = thulac.thulac(seg_only=True)  #默认模式
text = thu1.cut("工商注册地、税务征管关系及统计关系在广州市南沙区范围内", text=True)  #进行一句话分词
print(text)
text1 = thu1.cut("工商注册地、税务征管关系及统计关系在广州市南沙区范围内", text=True)  #进行一句话分词
print(text1)
text2 = thu1.cut("企业具有独立法人资格", text=True)  #进行一句话分词
print(text2)
words=text.split(" ")
word_list=[]
for w in words:
    word_vec={}
    w2v=np.random.rand(1,300)
    word_vec['word']=w
    word_vec['vec']=list(w2v[0])
    word_list.append(word_vec)
words=text1.split(" ")
for w in words:
    word_vec={}
    w2v=np.random.rand(1,300)
    word_vec['word']=w
    word_vec['vec']=list(w2v[0])
    word_list.append(word_vec)
words=text2.split(" ")
for w in words:
    word_vec={}
    w2v=np.random.rand(1,300)
    word_vec['word']=w
    word_vec['vec']=list(w2v[0])
    word_list.append(word_vec)
jsonArr = json.dumps(word_list, ensure_ascii=False)
with open('word_vec.json','w')as f:
    f.write(jsonArr)
### 生成训练集
import  json
thu1 = thulac.thulac(seg_only=True)  #默认模式
text = thu1.cut("工商注册地、税务征管关系及统计关系在广州市南沙区范围内", text=True)  #进行一句话分词
print(text)
text1 = thu1.cut("工商注册地、税务征管关系及统计关系在广州市南沙区范围内", text=True)  #进行一句话分词
print(text1)
text2 = thu1.cut("企业具有独立法人资格", text=True)  #进行一句话分词
print(text2)
word_list=[
  {
    "sentence": text,
    "head": {"word": "工商注册地","id":"1"},
    "tail": {"word": "广州市南沙区","id":"2"},
    "relation": "范围内"
  },
    {
    "sentence": text1,
    "head": {"word": "税务征管关系","id":"3"},
    "tail": {"word": "广州市南沙区","id":"2"},
    "relation": "范围内"
  },
    {
    "sentence": text2,
    "head": {"word": "企业","id":"4"},
    "tail": {"word": "独立法人资格","id":"5"},
    "relation": "具有"
  }
]
jsonArr = json.dumps(word_list, ensure_ascii=False)
with open('train.json','w')as f:
    f.write(jsonArr)
with open('test.json','w')as f:
    f.write(jsonArr)
word_list={"NA": 0, "范围内": 1,"具有":2}
jsonArr = json.dumps(word_list, ensure_ascii=False)
with open('rel2id.json','w')as f:
    f.write(jsonArr)

感觉有问题

计算AUC
flag表示0/1正负
但是没看懂的是为什么prec和recall的底数。然后auc的是根据阈值计算面积的,这里为什么直接就计算auc了。

        for i, item in enumerate(sorted_test_result[::-1]):
            # 我觉得这个指标有问题
            correct += item['flag']
            prec.append(float(correct) / (i + 1))
            recall.append(float(correct) / self.test_data_loader.relfact_tot)
auc = sklearn.metrics.auc(x=recall, y=prec)
所以AUC一般都是偏低的,哪怕准确率比较高的情况下

你可能感兴趣的:(NLP)