CausalityEventExtraction/causality_extract.py

272 lines
13 KiB
Python
Raw Permalink Normal View History

2018-03-17 19:55:17 +08:00
#!/usr/bin/env python3
# coding: utf-8
# File: causality_pattern.py
# Author: lhy<lhy_in_blcu@126.com,https://huangyong.github.io>
# Date: 18-3-12
import re, jieba
import jieba.posseg as pseg
from pyltp import SentenceSplitter
class CausalityExractor():
def __init__(self):
pass
'''1由果溯因配套式'''
def ruler1(self, sentence):
'''
conm2:[]所以,因为[]所以,由于 <[]所以,缘于
conm2_model:<Conj>{Effect},<Conj>{Cause}
'''
datas = list()
word_pairs =[['之?所以', '因为'], ['之?所以', '由于'], ['之?所以', '缘于']]
for word in word_pairs:
pattern = re.compile(r'\s?(%s)/[p|c]+\s(.*)(%s)/[p|c]+\s(.*)' % (word[0], word[1]))
result = pattern.findall(sentence)
data = dict()
if result:
data['tag'] = result[0][0] + '-' + result[0][2]
data['cause'] = result[0][3]
data['effect'] = result[0][1]
datas.append(data)
if datas:
return datas[0]
else:
return {}
'''2由因到果配套式'''
def ruler2(self, sentence):
'''
conm1:因为,从而因为,为此[],所以因为,为此由于,为此只有|除非,由于,以至[]>[],>
如果,那么|<由于,从而<[],[],因此如果,只要,因为,所以 <由于,于是因为,因此
<由于, 因为,以致[]因为,因而由于,因此<因为,于是由于,致使因为,致使由于,以致[] >
因为,[],以至[]>,由于,所以因为,故而由于,因而
conm1_model:<Conj>{Cause}, <Conj>{Effect}
'''
datas = list()
word_pairs =[['因为', '从而'], ['因为', '为此'], ['既然?', '所以'],
['因为', '为此'], ['由于', '为此'], ['除非', ''],
['只有', ''], ['由于', '以至于?'], ['既然?', ''],
['如果', '那么'], ['如果', ''], ['由于', '从而'],
['既然?', ''], ['既然?', '因此'], ['如果', ''],
['只要', ''], ['因为', '所以'], ['由于', '于是'],
['因为', '因此'], ['由于', ''], ['因为', '以致于?'],
['因为', '以致'], ['因为', '因而'], ['由于', '因此'],
['因为', '于是'], ['由于', '致使'], ['因为', '致使'],
['由于', '以致于?'], ['因为', ''], ['因为?', '以至于?'],
['由于', '所以'], ['因为', '故而'], ['由于', '因而']]
for word in word_pairs:
pattern = re.compile(r'\s?(%s)/[p|c]+\s(.*)(%s)/[p|c]+\s(.*)' % (word[0], word[1]))
result = pattern.findall(sentence)
data = dict()
if result:
data['tag'] = result[0][0] + '-' + result[0][2]
data['cause'] = result[0][1]
data['effect'] = result[0][3]
datas.append(data)
if datas:
return datas[0]
else:
return {}
'''3由因到果居中式明确'''
def ruler3(self, sentence):
'''
cons2:于是所以致使以致[]因此以至[]从而因而
cons2_model:{Cause},<Conj...>{Effect}
'''
pattern = re.compile(r'(.*)[,]+.*(于是|所以|故|致使|以致于?|因此|以至于?|从而|因而)/[p|c]+\s(.*)')
result = pattern.findall(sentence)
data = dict()
if result:
data['tag'] = result[0][1]
data['cause'] = result[0][0]
data['effect'] = result[0][2]
return data
'''4由因到果居中式精确'''
def ruler4(self, sentence):
'''
verb1:牵动导向使动导致勾起引入指引使予以产生促成造成引导造就促使酿成
引发渗透促进引起诱导引来促发引致诱发推进诱致推动招致影响致使滋生归于
作用使得决定攸关令人引出浸染带来挟带触发关系渗入诱惑波及诱使
verb1_model:{Cause},<Verb|Adverb...>{Effect}
'''
pattern = re.compile(r'(.*)\s+(牵动|已致|导向|使动|导致|勾起|引入|指引|使|予以|产生|促成|造成|引导|造就|促使|酿成|引发|渗透|促进|引起|诱导|引来|促发|引致|诱发|推进|诱致|推动|招致|影响|致使|滋生|归于|作用|使得|决定|攸关|令人|引出|浸染|带来|挟带|触发|关系|渗入|诱惑|波及|诱使)/[d|v]+\s(.*)')
result = pattern.findall(sentence)
data = dict()
if result:
data['tag'] = result[0][1]
data['cause'] = result[0][0]
data['effect'] = result[0][2]
return data
'''5由因到果前端式模糊'''
def ruler5(self, sentence):
'''
prep:为了依据按照[]依赖凭借由于
prep_model:<Prep...>{Cause},{Effect}
'''
pattern = re.compile(r'\s?(为了|依据|按照|因为|因|按|依赖|凭借|由于)/[p|c]+\s(.*)[,]+(.*)')
result = pattern.findall(sentence)
data = dict()
if result:
data['tag'] = result[0][0]
data['cause'] = result[0][1]
data['effect'] = result[0][2]
return data
'''6由因到果居中式模糊'''
def ruler6(self, sentence):
'''
adverb:以免以便为此
adverb_model:{Cause},<Verb|Adverb...>{Effect}
'''
pattern = re.compile(r'(.*)(以免|以便|为此|才)\s(.*)')
result = pattern.findall(sentence)
data = dict()
if result:
data['tag'] = result[0][1]
data['cause'] = result[0][0]
data['effect'] = result[0][2]
return data
'''7由因到果前端式精确'''
def ruler7(self, sentence):
'''
cons1:[][]如果由于只要
cons1_model:<Conj...>{Cause},{Effect}
'''
pattern = re.compile(r'\s?(既然?|因|因为|如果|由于|只要)/[p|c]+\s(.*)[,]+(.*)')
result = pattern.findall(sentence)
data = dict()
if result:
data['tag'] = result[0][0]
data['cause'] = result[0][1]
data['effect'] = result[0][2]
return data
'''8由果溯因居中式模糊'''
def ruler8(self, sentence):
'''
3
verb2:根源于取决来源于出于取决于缘于在于出自起源于来自发源于发自源于根源于立足[]
verb2_model:{Effect}<Prep...>{Cause}
'''
pattern = re.compile(r'(.*)(根源于|取决|来源于|出于|取决于|缘于|在于|出自|起源于|来自|发源于|发自|源于|根源于|立足|立足于)/[p|c]+\s(.*)')
result = pattern.findall(sentence)
data = dict()
if result:
data['tag'] = result[0][1]
data['cause'] = result[0][2]
data['effect'] = result[0][0]
return data
'''9由果溯因居端式精确'''
def ruler9(self, sentence):
'''
cons3:因为由于
cons3_model:{Effect}<Conj...>{Cause}
'''
pattern = re.compile(r'(.*)是?\s(因为|由于)/[p|c]+\s(.*)')
result = pattern.findall(sentence)
data = dict()
if result:
data['tag'] = result[0][1]
data['cause'] = result[0][2]
data['effect'] = result[0][0]
return data
'''抽取主函数'''
def extract_triples(self, sentence):
infos = list()
# print(sentence)
if self.ruler1(sentence):
infos.append(self.ruler1(sentence))
elif self.ruler2(sentence):
infos.append(self.ruler2(sentence))
elif self.ruler3(sentence):
infos.append(self.ruler3(sentence))
elif self.ruler4(sentence):
infos.append(self.ruler4(sentence))
elif self.ruler5(sentence):
infos.append(self.ruler5(sentence))
elif self.ruler6(sentence):
infos.append(self.ruler6(sentence))
elif self.ruler7(sentence):
infos.append(self.ruler7(sentence))
elif self.ruler8(sentence):
infos.append(self.ruler8(sentence))
elif self.ruler9(sentence):
infos.append(self.ruler9(sentence))
return infos
'''抽取主控函数'''
def extract_main(self, content):
sentences = self.process_content(content)
datas = list()
for sentence in sentences:
subsents = self.fined_sentence(sentence)
subsents.append(sentence)
for sent in subsents:
sent = ' '.join([word.word + '/' + word.flag for word in pseg.cut(sent)])
result = self.extract_triples(sent)
if result:
for data in result:
if data['tag'] and data['cause'] and data['effect']:
datas.append(data)
return datas
'''文章分句处理'''
def process_content(self, content):
return [sentence for sentence in SentenceSplitter.split(content) if sentence]
'''切分最小句'''
def fined_sentence(self, sentence):
return re.split(r'[]', sentence)
'''测试'''
def test():
content1 = """
截至2008年9月18日12时5·12汶川地震共造成69227人死亡374643人受伤17923人失踪是中华人民共和国成立以来破坏力最大的地震也是唐山大地震后伤亡最严重的一次地震
"""
content2 = '''
2015年1月4日下午3时39分左右贵州省遵义市习水县二郎乡遵赤高速二郎乡往仁怀市方向路段发生山体滑坡发生规模约10万立方米,导致多辆车被埋造成交通双向中断此事故引起贵州省委省政府的高度重视省长陈敏尔作出指示要求迅速组织开展救援工作千方百计实施救援减少人员伤亡和财物损失遵义市立即启动应急救援预案市应急办公安交通卫生等救援力量赶赴现场救援目前灾害已造成3人遇难1人受伤一辆轿车被埋
当地时间2010年1月12日16时53分加勒比岛国海地发生里氏7.3级大地震震中距首都太子港仅16公里这个国家的心脏几成一片废墟25万人在这场骇人的灾难中丧生此次地震中的遇难者有联合国驻海地维和部队人员其中包括8名中国维和人员虽然国际社会在灾后纷纷向海地提供援助但由于尸体处理不当导致饮用水源受到污染灾民喝了受污染的水后引发霍乱已致至少2500多人死亡
'''
content3 = '''
American Eagle 四季度符合预期 华尔街对其毛利率不满导致股价大跌
我之所以考试没及格是因为我没有好好学习
因为天晴了所以我今天晒被子
因为下雪了所以路上的行人很少
我没有去上课是因为我病了
因为早上没吃的缘故所以今天还没到放学我就饿了.
因为小华身体不舒服所以她没上课间操
因为我昨晚没睡好所以今天感觉很疲倦
因为李明学习刻苦所以其成绩一直很优秀
雨水之所以不能把石块滴穿是因为它没有专一的目标也不能持之以恒
他之所以成绩不好是因为他平时不努力学习
你之所以提这个问题是因为你没有学好关联词的用法
减了税,因此怨声也少些了
他的话引得大家都笑了室内的空气因此轻松了很多
他努力学习因此通过了考试
既然明天要下雨就不要再出去玩
既然他还是那么固执就不要过多的与他辩论
既然别人的事与你无关你就不要再去过多的干涉
既然梦想实现不了就换一个你自己喜欢的梦想吧
既然别人需要你你就去尽力的帮助别人
既然生命突显不出价值就去追求自己想要的生活吧
既然别人不尊重你就不要尊重别人 因果复句造句
既然题目难做就不要用太多的时间去想问一问他人也许会更好
既然我们是学生就要遵守学生的基本规范
'''
extractor = CausalityExractor()
datas = extractor.extract_main(content1)
for data in datas:
print('******'*4)
print('cause', ''.join([word.split('/')[0] for word in data['cause'].split(' ') if word.split('/')[0]]))
print('tag', data['tag'])
print('effect', ''.join([word.split('/')[0] for word in data['effect'].split(' ') if word.split('/')[0]]))
test()