首页 >资讯 > > 正文

python实现Bi-GRU语义解析实现中文人物关系分析【文末源码】|焦点热讯

来源:哔哩哔哩 2023-04-25 20:03:42

Bi-GRU语义解析实现中文人物关系分析

引言语义解析作为自然语言处理的重要方面,其主要作用如下:在词的层次上,语义分析的基本任务是进行词义消歧;在句子层面上,语义角色标注是所关心的问题;在文章层次上,指代消解、篇章语义分析是重点。


(资料图)

而实体识别和关系抽取是构建知识图谱等上层自然语言处理应用的基础。关系抽取可以简单理解为一个分类问题:给定两个实体和两个实体共同出现的句子文本,判别两个实体之间的关系。

使用CNN或者双向RNNAttention的深度学习方法被认为是现在关系抽取stateofart的解决方案。已有的文献和代码,大都是针对英文语料,使用词向量作为输入进行训练。这里以实践为目的,介绍一个用双向GRU、字与句子的双重Attention模型,以天然适配中文特性的字向量(characterembedding)作为输入,网络爬取数据作为训练语料构建的中文关系抽取模型。代码主要是基于清华的开源项目thunlp/TensorFlow-NRE开发,其中效果如下:

一、实验前的准备:

首先我们使用的python版本是3.6.5所用到的模块如下:

tensorflow模块用来创建整个模型训练和保存调用以及网络的搭建框架等等。

numpy模块用来处理数据矩阵运算。

Sklearn模块是一些机器学习算法的集成模块。

二、模型的网络搭建

其中模型的网络图如下:

双向GRU加字级别attention的模型想法来自文章“Attention-BasedBidirectional Long Short-Term Memory Networks for RelationClassification” [Zhou etal.,2016]。这里将原文的模型结构中的LSTM改为GRU,且对句子中的每一个中文字符输入为characterembedding。这样的模型对每一个句子输入做训练,加入字级别的attention

句子级别attention的想法来自文章“NeuralRelation Extraction with Selective Attention over Instances”[Lin etal.,2016]。原文模型结构图如下,这里将其中对每个句子进行encodingCNN模块换成上面的双向GRU模型。这样的模型对每一种类别的句子输入做共同训练,加入句子级别的attention

建立network.py文件,定义词向量大小、步数、类别数等等:def__init__(self):   self.vocab_size= 16691   self.num_steps= 70   self.num_epochs= 10   self.num_classes= 12   self.gru_size= 230   self.keep_prob= 0.5   self.num_layers= 1   self.pos_size= 5   self.pos_num= 123   #the number of entity pairs of each batch during training or testing   self.big_num= 50

然后建立GRU网络。按照所给出的网络模型图,定义出网络基本框架作为具体参数的调用:

def__init__(self,is_training, word_embeddings, settings):    self.num_steps= num_steps = settings.num_steps    self.vocab_size= vocab_size=settings.vocab_size    self.num_classes= num_classes = settings.num_classes    self.gru_size= gru_size = settings.gru_size    self.big_num= big_num = settings.big_num    self.input_word= tf.placeholder(dtype=tf.int32,shape=[None,num_steps], name='input_word')   self.input_pos1= tf.placeholder(dtype=tf.int32,shape=[None,num_steps], name='input_pos1')   self.input_pos2= tf.placeholder(dtype=tf.int32,shape=[None,num_steps], name='input_pos2')   self.input_y= tf.placeholder(dtype=tf.float32,shape=[None,num_classes], name='input_y')   self.total_shape= tf.placeholder(dtype=tf.int32,shape=[big_num+ 1],name='total_shape')   total_num = self.total_shape[-1]   word_embedding = tf.get_variable(initializer=word_embeddings,name='word_embedding')   pos1_embedding = tf.get_variable('pos1_embedding',[settings.pos_num, settings.pos_size])    pos2_embedding =tf.get_variable('pos2_embedding',[settings.pos_num, settings.pos_size])    attention_w =tf.get_variable('attention_omega',[gru_size, 1])   sen_a = tf.get_variable('attention_A',[gru_size])    sen_r = tf.get_variable('query_r',[gru_size, 1])   relation_embedding = tf.get_variable('relation_embedding',[self.num_classes,gru_size])    sen_d = tf.get_variable('bias_d',[self.num_classes])   gru_cell_forward = tf.contrib.rnn.GRUCell(gru_size)   gru_cell_backward = tf.contrib.rnn.GRUCell(gru_size)    ifis_trainingandsettings.keep_prob< 1:       gru_cell_forward =tf.contrib.rnn.DropoutWrapper(gru_cell_forward,output_keep_prob=settings.keep_prob)       gru_cell_backward =tf.contrib.rnn.DropoutWrapper(gru_cell_backward,output_keep_prob=settings.keep_prob)   cell_forward = tf.contrib.rnn.MultiRNNCell([gru_cell_forward] *settings.num_layers)    cell_backward =tf.contrib.rnn.MultiRNNCell([gru_cell_backward] *settings.num_layers)    sen_repre = []    sen_alpha = []   sen_s = []    sen_out = []    self.prob= []    self.predictions= []    self.loss= []    self.accuracy= []    self.total_loss= 0.0   self._initial_state_forward= cell_forward.zero_state(total_num, tf.float32)   self._initial_state_backward= cell_backward.zero_state(total_num, tf.float32)    #embedding layer    inputs_forward= tf.concat(axis=2,values=[tf.nn.embedding_lookup(word_embedding,self.input_word),                                             tf.nn.embedding_lookup(pos1_embedding, self.input_pos1),                                             tf.nn.embedding_lookup(pos2_embedding, self.input_pos2)])   inputs_backward = tf.concat(axis=2,                              values=[tf.nn.embedding_lookup(word_embedding,tf.reverse(self.input_word,[1])),                                      tf.nn.embedding_lookup(pos1_embedding, tf.reverse(self.input_pos1,[1])),                                      tf.nn.embedding_lookup(pos2_embedding,                                                             tf.reverse(self.input_pos2,[1]))])   outputs_forward = []    state_forward =self._initial_state_forward   #Bi-GRU layer    withtf.variable_scope('GRU_FORWARD')asscope:       forstepinrange(num_steps):           ifstep> 0:               scope.reuse_variables()           (cell_output_forward, state_forward) = cell_forward(inputs_forward[:,step, :], state_forward)           outputs_forward.append(cell_output_forward)    outputs_backward= []    state_backward = self._initial_state_backward   withtf.variable_scope('GRU_BACKWARD')asscope:       forstepinrange(num_steps):           ifstep> 0:               scope.reuse_variables()           (cell_output_backward, state_backward) =cell_backward(inputs_backward[:, step, :], state_backward)          outputs_backward.append(cell_output_backward)   output_forward = tf.reshape(tf.concat(axis=1,values=outputs_forward),[total_num, num_steps, gru_size])    output_backward =tf.reverse(        tf.reshape(tf.concat(axis=1,values=outputs_backward),[total_num, num_steps, gru_size]), [1])   #word-level attention layer    output_h= tf.add(output_forward, output_backward)    attention_r =tf.reshape(tf.matmul(tf.reshape(tf.nn.softmax(       tf.reshape(tf.matmul(tf.reshape(tf.tanh(output_h), [total_num *num_steps, gru_size]), attention_w),                  [total_num, num_steps])), [total_num, 1,num_steps]), output_h), [total_num, gru_size])    

三、模型的训练和使用

其中用来训练的语料获取,由于中文关系抽取的公开语料比较少。我们从distantsupervision的方法中获取灵感,希望可以首先找到具有确定关系的实体对,然后再去获取该实体对共同出现的语句作为正样本。负样本则从实体库中随机产生没有关系的实体对,再去获取这样实体对共同出现的语句。

对于具有确定关系的实体对,我们从复旦知识工厂得到,感谢他们提供的免费API!一个小问题是,相同的关系label在复旦知识工厂中可能对应着不同的标注,比如“夫妻”,抓取到的数据里有的是“丈夫”,有的是“妻子”,有的是“伉俪”等等,需要手动对齐。

模型的训练:

建立train_GRU文件,通过训练已经经过处理后得到的npy文件进行训练。

其中训练的数据如下:

代码如下:

defmain(_):   #the path to save models    save_path= './model/'   print('readingwordembedding')   wordembedding = np.load('./data/vec.npy')   print('readingtraining data')   train_y = np.load('./data/train_y.npy')   train_word = np.load('./data/train_word.npy')   train_pos1 = np.load('./data/train_pos1.npy')   train_pos2 = np.load('./data/train_pos2.npy')   settings = network.Settings()    settings.vocab_size =len(wordembedding)   settings.num_classes = len(train_y[0])   big_num=settings.big_num    withtf.Graph().as_default():       sess = tf.Session()        withsess.as_default():           initializer = tf.contrib.layers.xavier_initializer()           withtf.variable_scope("model",reuse=None,initializer=initializer):               m = network.GRU(is_training=True,word_embeddings=wordembedding,settings=settings)           global_step = tf.Variable(0,name="global_step",trainable=False)           optimizer = tf.train.AdamOptimizer(0.0005)           train_op = optimizer.minimize(m.final_loss,global_step=global_step)           sess.run(tf.global_variables_initializer())          saver = tf.train.Saver(max_to_keep=None)           merged_summary = tf.summary.merge_all()           summary_writer = tf.summary.FileWriter(FLAGS.summary_dir +'/train_loss',sess.graph)            deftrain_step(word_batch,pos1_batch, pos2_batch, y_batch, big_num):               feed_dict = {}                total_shape = []              total_num = 0               total_word= []                total_pos1 = []               total_pos2 = []                foriinrange(len(word_batch)):                   total_shape.append(total_num)                  total_num += len(word_batch[i])                   forwordinword_batch[i]:                       total_word.append(word)                  forpos1inpos1_batch[i]:                       total_pos1.append(pos1)                  forpos2inpos2_batch[i]:                       total_pos2.append(pos2)               total_shape.append(total_num)                total_shape =np.array(total_shape)                total_word =np.array(total_word)                total_pos1 =np.array(total_pos1)                total_pos2 =np.array(total_pos2)                feed_dict[m.total_shape] =total_shape                feed_dict[m.input_word] =total_word                feed_dict[m.input_pos1] = total_pos1               feed_dict[m.input_pos2] = total_pos2               feed_dict[m.input_y] = y_batch                temp, step,loss, accuracy, summary, l2_loss, final_loss = sess.run(                  [train_op, global_step, m.total_loss, m.accuracy,merged_summary, m.l2_loss, m.final_loss],                   feed_dict)                time_str =datetime.datetime.now().isoformat()                accuracy =np.reshape(np.array(accuracy), (big_num))                acc =np.mean(accuracy)               summary_writer.add_summary(summary, step)                ifstep% 50==0:                   tempstr = "{}:step {}, softmax_loss {:g}, acc {:g}".format(time_str,step, loss, acc)                    print(tempstr)           forone_epochinrange(settings.num_epochs):               temp_order = list(range(len(train_word)))               np.random.shuffle(temp_order)                foriinrange(int(len(temp_order)/ float(settings.big_num))):                   temp_word = []                    temp_pos1= []                    temp_pos2 = []                   temp_y = []                    temp_input = temp_order[i *settings.big_num:(i + 1)* settings.big_num]                    forkintemp_input:                       temp_word.append(train_word[k])                      temp_pos1.append(train_pos1[k])                       temp_pos2.append(train_pos2[k])                       temp_y.append(train_y[k])                    num = 0                   forsingle_wordintemp_word:                       num += len(single_word)                   ifnum> 1500:                       print('outof range')                       continue                   temp_word= np.array(temp_word)                    temp_pos1 =np.array(temp_pos1)                    temp_pos2 =np.array(temp_pos2)                    temp_y =np.array(temp_y)                    train_step(temp_word,temp_pos1, temp_pos2, temp_y, settings.big_num)                   current_step = tf.train.global_step(sess, global_step)                   ifcurrent_step> 8000andcurrent_step% 100==0:                       print('savingmodel')                       path = saver.save(sess, save_path +'ATT_GRU_model',global_step=current_step)                       tempstr = 'havesaved model to ' +path                        print(tempstr)

训练过程:

2.模型的测试:

其中得到训练后的模型如下:

whileTrue:   #try:       #BUG: Encoding error if user input directly from commandline.        line= input('请输入中文句子,格式为"name1name2 sentence":')       #Readfile from test file        '''       infile = open('test.txt', encoding='utf-8')        line= ''        for orgline in infile:            line =orgline.strip()            break        infile.close()       '''        en1,en2, sentence = line.strip().split()        print("实体1:" +en1)        print("实体2:" +en2)        print(sentence)       relation=0       en1pos= sentence.find(en1)        ifen1pos== -1:           en1pos = 0       en2pos= sentence.find(en2)        ifen2pos== -1:           en2post=0       output= []        #length of sentence is 70        fixlen= 70       #max length of position embedding is 60 (-60~+60)        maxlen=60       #Encodingtest x        foriinrange(fixlen):           word = word2id['BLANK']           rel_e1 = pos_embed(i - en1pos)            rel_e2 =pos_embed(i - en2pos)            output.append([word, rel_e1,rel_e2])        foriinrange(min(fixlen,len(sentence))):           word=0           ifsentence[i]notin word2id:               #print(sentence[i])               #print('==')                word= word2id['UNK']               #print(word)           else:               #print(sentence[i])               #print('||')                word= word2id[sentence[i]]                #print(word)           output[i][0]= word        test_x = []        test_x.append([output])       #Encodingtest y        label= [0foriinrange(len(relation2id))]       label[0]= 1       test_y= []        test_y.append(label)        test_x =np.array(test_x)        test_y = np.array(test_y)       test_word = []        test_pos1 = []        test_pos2 =[]        foriinrange(len(test_x)):           word = []            pos1 = []            pos2= []            forjintest_x[i]:               temp_word = []                temp_pos1 = []               temp_pos2 = []                forkinj:                   temp_word.append(k[0])                   temp_pos1.append(k[1])                   temp_pos2.append(k[2])               word.append(temp_word)               pos1.append(temp_pos1)                pos2.append(temp_pos2)           test_word.append(word)           test_pos1.append(pos1)            test_pos2.append(pos2)      test_word = np.array(test_word)        test_pos1 =np.array(test_pos1)        test_pos2 = np.array(test_pos2)        prob,accuracy = test_step(test_word, test_pos1, test_pos2, test_y)       prob = np.reshape(np.array(prob), (1,test_settings.num_classes))[0]       print("关系是:")       #print(prob)       top3_id= prob.argsort()[-3:][::-1]       forn,rel_id inenumerate(top3_id):           print("No."+str(n+1)+ ":" +id2relation[rel_id] + ",Probability is " +str(prob[rel_id]))  测试效果:

完整代码:https://gitcode.net/qq_42279468/python-bi-gru.git

上一篇:季后赛大黑马诞生!浓眉12分也能赢,西部没对手,湖人剑指总决赛 下一篇:最后一页
x
推荐阅读

python实现Bi-GRU语义解析实现中文人物关系分析【文末源码】|焦点热讯

2023-04-25

季后赛大黑马诞生!浓眉12分也能赢,西部没对手,湖人剑指总决赛

2023-04-25

天天时讯:电气风电:2023年第一季度净利润亏损约1.67亿元

2023-04-25

张家口市生态环境局:“主动提醒办”助力企业行稳致远

2023-04-25

上海车展禁止派发冰激凌,抵制风波又起,宝马还卖的动吗?

2023-04-25

今日要闻!皇氏集团切入光伏产业赛道

2023-04-25

“疯狂”的大模型 谁来买单?警惕最终“一地鸡毛”

2023-04-25

国家发展改革委赴广东省开展新能源汽车产业高质量发展专题调研

2023-04-25

每日热议!上汽“春困”

2023-04-25

【环球新视野】平安人寿青岛分公司保护知识产权在行动

2023-04-25

大明嫔妃吧百度贴吧_大明嫔妃之登基|全球热门

2023-04-25

每日热议!从上海车展回来后核酸检测呈阳性?举办地工作人员:未接到疫情防控的通知

2023-04-25

4月25日华鲁恒升尿素价格暂稳 天天通讯

2023-04-25

我国首个封闭水域内面向智能无人船实景测试的专业测试场启用

2023-04-25

天天微头条丨涉案金额104万元,三亚吉阳警方打掉两个利用GOIP实施电信网络诈骗团伙

2023-04-25

银保监会:现阶段非法集资风险形势依然严峻复杂 存量风险仍将“水落石出”

2023-04-25

中超今日裁判安排:马宁吹罚山东泰山vs浙江 邢琦任梅州vs三镇主裁

2023-04-25

球迷订价值10万梅西签名世界杯金球被送丢,快递公司只赔90元|全球关注

2023-04-25

当前滚动:独立报:纳格尔斯曼如果来热刺执教,希望在引援方面有话语权

2023-04-25

温宿县一季度重大项目建设跑出“加速度”

2023-04-25

每日热点:“绿色吨半粮”!绿色增粮与乡村振兴大会战启动

2023-04-25

一季度我国黄金消费量291.58吨 同比增长12.03%-全球热讯

2023-04-25

最新快讯!火星全球彩色影像图发布 为探测和研究提供质量更好的基础底图

2023-04-25

每日快讯!三亚通报出租车司机嫌路近把怨气撒给乘客:开除并列入黑名单

2023-04-25

头条:智慧管控+精准治理 厦门水质再上全国“红榜”

2023-04-25

焦点消息!李忠双:近期钢材价格有望企稳

2023-04-25

世界首颗5G卫星上天,由SpaceX发射

2023-04-25

豪掷1.7亿!关注赛道股的企稳 天天热文

2023-04-25

中信建投:从投资角度看 超配家电板块将带来超额收益 当前热文

2023-04-25

“曹德旺炮轰特斯拉涨薪”“宁愿捐款也不涨薪”?福耀集团辟谣!曹德旺曾表示:乱加工资对社会有害… 当前通讯

2023-04-25

回迁小区物业要求一次性缴纳8个月物业费|世界热讯

2023-04-25

“三看”4.5%:这个数字不简单!

2023-04-25

焦点快报!罗马诺:波切蒂诺无限接近执教切尔西,他将在6月份上任

2023-04-25

当前讯息:高职播音主持专业报名条件是什么?

2023-04-25

找钢网数字化工具赋能钢贸行业转型

2023-04-25

绿工委:勇当企业绿色发展领跑者

2023-04-25

通讯!平安惠融纯债债券型证券投资基金基金经理变更公告

2023-04-25

美国对乌克兰军事支持产能不足 多个军工厂忙增产露隐患-每日热点

2023-04-25

五问信合:“被贷款”事件为何频发……快评:“被贷款”坑苦无辜者,后遗症何以久久难愈?

2023-04-25

运动手环哪个牌子好知乎_运动手环哪个牌子好

2023-04-25

世界观焦点:糊塌子的家常做法_糊塌子简单做法

2023-04-25

喜欢一个男生怎么追知乎_喜欢一个男生怎么追_天天动态

2023-04-25

安德利果汁(02218)购买2.8亿元理财产品

2023-04-25

廊坊印刷包装网-环球热点评

2023-04-25

五一档17部电影上映具体是什么情况

2023-04-25

4月24日基金净值:国投瑞银美丽中国混合最新净值1.444,跌0.96%

2023-04-25

钓系女生是什么意思(钓系是什么意思)

2023-04-25

天天百事通!福建省南平市2023-04-24 21:44发布雷电黄色预警

2023-04-25

大国基理丨福建三明:唤起“主人翁意识” 服务群众“零温差”|焦点精选

2023-04-25

今日热议:中国第一个飞行员是谁(中国第一个飞行员是谁教的)

2023-04-25

世界报道:“青年大学习”网上主题团课2023年第9期上线

2023-04-25

每日焦点!热点|“中国高铁舒适快速”,马斯克:确实

2023-04-25

天天微资讯!延庆区京银路沿线环境整治提升进行时,将打造成片公共绿色空间

2023-04-25

吉风碰蜀韵,一条横跨2800公里的“对角线”!

2023-04-24

全球新资讯:抖音小店后台商家后台_平安好医生商家后台

2023-04-24

赛为智能: 2022年度业绩预告修正公告

2023-04-24

【速看料】【官方推荐】赏花正当时!阿荣旗这些赏花路线任你选

2023-04-24

乌指挥官找到约500具俄士兵尸体_天天观焦点

2023-04-24

1.33亿!杭州“最贵法拍房”成交,原房东给朋友做担保欠下2个亿…… 当前热门

2023-04-24

红酒鸡翅的做法_红酒鸡翅怎么做好吃 环球快播

2023-04-24

全球今头条!强信心·开新局丨新引擎 新动能 新举措:老工业基地佳木斯谋转型促发展

2023-04-24

这样回复你消息的男人,多半不爱了,还是“断联”吧-速读

2023-04-24

卧室养花的风水禁忌有哪些(卧室养花的风水禁忌有哪些东西)

2023-04-24

【新视野】跟着专列游五一 | 熊猫专列:4980元套票半小时售罄 多家酒店涨价3倍

2023-04-24

今日聚焦!Yembo的安全基础设施

2023-04-24

每日快看:浙江一大坝挖出超百万只白蚁,三只蚁后已生长十几年

2023-04-24

凉山州住房公积金管理中心官网网址_凉山州住房公积金管理中心官网

2023-04-24

华尔兹基本舞步 旋转右锁步_华尔兹基本舞步 世界热点评

2023-04-24

全球今日报丨关于白酒的这几个问题你都知道多少

2023-04-24

天天报道:存在与自由:伦理学引论

2023-04-24

曝苹果AR/VR头显只能用外接电池,续航约2小时 天天短讯

2023-04-24

取消外籍华人子女加分!杭州市区中考加分政策调整 环球关注

2023-04-24

为期80天!武汉经开区开展出租汽车整治行动-今日关注

2023-04-24

世界关注:2023上海车展探馆:全新红旗L5、红旗H6、红旗E001等全新产品亮相,红旗到底有何看点?

2023-04-24

全球观速讯丨江苏“爱鸟周”|“科研鸢五号”重回大自然,前四只传回的数据显示……

2023-04-24

广交会增设孕婴童用品展区助力企业转内销 促进国内国际双循环|全球速讯

2023-04-24

玩得了电动增压,也hold得住网络安全,盖瑞特上海车展化身“多面手” 天天热闻

2023-04-24

Sensor Tower:3月全球手游下载量45亿次 《Subway Surfers 地铁跑酷》位列榜首 天天时讯

2023-04-24

网传老人云南旅游不买东西被导游辱骂,“一分钱没花,不让你上车,老臭流氓”,当地回应:会进行处理 当前速递

2023-04-24

2023年零售产业布局分析:我国零售行业布局不断变化 当前观点

2023-04-24

塞瓦斯托波尔市长:黑海舰队正在击退水面无人艇的攻击 今日播报

2023-04-24

《春晚》观后感600字 观《三傻大闹宝莱坞》有感_观后感60 全球观天下

2023-04-24

简讯:迅雷下载 肌肤之亲第一季迅雷下载

2023-04-24

全球快看:吉利银河L7量产版正式下线 将于第二季度交付

2023-04-24

【世界聚看点】浦发银行青岛分行举办第二期“浦发企明星” 暨2023年经济与资本市场展望投研论坛

2023-04-24

华商基金周海栋旗下华商新趋势一季报最新持仓,重仓紫金矿业

2023-04-24

拜祖大典经贸洽谈,新郑市累计签约26个项目369.5亿元

2023-04-24

我国已有20个省份、40余条线路开展车路协同智慧高速公路建设_环球关注

2023-04-24

传奇投资人拉响警报:美股恐暴跌超50%、银行业动荡还未结束

2023-04-24

新概念英语第一册原文精讲 (68)

2023-04-24

中年好声音决赛周吉佩成功夺冠,低潮期险两度寻死

2023-04-24

饼状图怎么制作 电脑饼状图怎么制作

2023-04-24

nor flash(nor)

2023-04-24

当前速讯:舒肝和胃丸能治疗乳腺结节吗 舒肝和胃丸和舒肝健胃丸的区别

2023-04-24

环球速讯:泾县:强化“三茶”统筹 做好“茶叶+”文章

2023-04-23

仙境海岸丨枣山、鱼花、面虎……看崂山面塑的百变造型

2023-04-23

大连地铁12号线周六运营时间(2023年4月22日-9月1日)

2023-04-23

深圳市民坐毛驴拉车一小时被收费800元,当事人:事前说好每小时400元_可到最后竟变了卦!

2023-04-23

回头鱼照片_回头鱼 世界百事通

2023-04-23

重阳节是祝安康还是快乐_重阳节是快乐还是安康_全球播报

2023-04-23