自然语言处理关系抽取:数据处理第二阶段

一、前言:
在数据处理的第一阶段中,我们主要运用train.txt, test.txt, vec.bin 和extract.cpp得到了三个文件:
(1):vector.txt:存放有1+114042个单词以及其embedding向量的txt文件
(2):bags_train.txt,bags_test.txt :存放了训练数据。包括实体id,实体名,关系种类,句子数量,句子id表示向量,相对位置表示向量,以及用于pcnn的mask向量。


二、数据预处理第二阶段:生成embedding,解析句子所需要的数据结构,并存储到self.xxx中。

1、根据vector.txt得到word embedding矩阵(用于初始化模型的word_embedding层),word2id、id2word字典。最后生成的数据格式如下

x = np.array(vecs, dtype=np.float32)
x.shape
->(114043, 50)   #一共1+114042个单词
x[0]
->$array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
      dtype=float32)   #对应BLANK的embedding向量,维度为50
id2word[0]
->'BLANK'
word2id[’BLANK']
->0

调用代码生成所需数据结构:

self.w2v, self.word2id, self.id2word = self.load_w2v()

其中分别为word_embedding向量,以及两个字典。

*2、然后生成用于初始化position embedding向量的两个矩阵。调用语句如下

self.p1_2v, self.p2_2v = self.load_p2v()

(再思考了一下,感觉这一步应该放在模型中)

3、然后是处理relation和entity的type信息(entity type信息在有时候会用到)。最后得到self.type2id, self.id2type, self.ent2type.

–处理entity type
(1):原数据从Freebase中得到,存储在ent_mid_types.json文件中。使用json.load读出文件,格式如下:

import json
x = json.load(open('ent_mid_types.json','r'))
len(x)
->68920
x[0]
->['michael_foley', 'm.0fnkvz', ['Person', 'Thing']]

注意:这里只是得到了68920个实体的类型,但是一共有63696(训练集)+5817(测试集) = 69513个实体。因此还有一些实体类型并没有得到。

(2):将type信息存储到字典中(self.ent2type) ,代码如下:

ent_types = json.load(open(‘ent_mid_types.json'),'r')
ent_types = {m: list(map(lambda x: type2id.get(x, 0), t)) for e, m, t in ent_types} #其中dict.get(x, 0)表示获取键值为x的值,若失败则返回0
 ->{...... 'm.0110lv': [0, 2, 3], 'm.088zs': [0], 'm.0204w9': [5, 22, 0, 4], 'm.025bb2': [0, 1] ......}

–处理relation type:
利用relation2id.txt,其中包含了53种关系以及其对应id,格式如下:

NA 0
/location/neighborhood/neighborhood_of 1
/location/fr_region/capital 2
/location/cn_province/capital 3
......

最后得到self.type2id, self.id2type两个字典

4、有时候会想到将RE和FreeBase的信息结合起来, 结合方式主要是使用TransE
4.1、训练TransE训练时需要三个文件。
(1):entity2id.txt:含有63696个训练集实体的freebase id,格式如下:

63696      #第一行为数量,训练时数据格式要求
m.0gfh8q 0
m.01xq3c 1
m.07hvzd 2
......

(2):relation2id.txt:含有58个关系(注意,train.txt中提取出的关系比分类的关系要多5个), 但是前53个关系顺序相同。数据格式如下:

58
NA 0
/location/neighborhood/neighborhood_of 1
/location/fr_region/capital 2
/location/cn_province/capital 3
/location/in_state/administrative_capital 4
......

(3):train2id.txt:含有两个实体以及其对应的关系id,一行作为一条正训练数据。数据格式如下:

19601
7867 30748 48
811 25542 48
17698 6615 29
......

(4):这三个文件是从train.txt抽取出来的,代码如下:

train2id_t = []
entity = []
relation = []
"""
get entitys and relations
"""
with open(train_path, 'r') as f:
    lines = f.readlines()
    for line in lines:
        try:
            text = line.strip().split()
            entity.extend([text[0], text[1]])
            if 'NA' not in text[4]:
                relation.append(text[4])
                e1_e2_r = "{}#{}#{}".format(text[0], text[1], text[4])
                train2id_t.append(e1_e2_r)
        except:
            print(text)

train2id_t[1]
->'m.0ccvx#m.05gf08#/location/location/contains'

4.2、将数据训练后,得到位json文件kb_embedding.json。存储了entity和relatioin的embedding向量,数据格式如下:

x = json.load(open('kb_embedding.json'))
x.keys()
->dict_keys(['ent_embeddings.weight', 'rel_embeddings.weight'])
len(x['ent_embeddings.weight'])
->63696
len(x['rel_embeddings.weight'])
58

得到了embedding向量后,存储到self.kb_entity2v, self.kb_r2v中

三、总结
在本节中,生成了:
1、self.w2v: word_embedding初始化权重所需np矩阵。
2、self.kbe_2v, self.kbr_2v: REKA实体、关系embedding权重初始化所需np矩阵。
3、self.word2id, self.id2word:处理相关句子所需字典。
4、self.type2id, self.id2type:处理相关关系所需字典。
5、self.ent2type:得到实体类型所需字典。
5、self.kb2id:给freebase里id编号。

四、在下一节中,我们将解析句子,然后将所有数据存为npy文件,以让模型读取。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值