一、面向法律领域的罪名预测、问题分类与FAQ问答模型设计与实现【NLP】
目前NLP技术在各个行业中应用逐步打开,尤其在金融,医疗,法律,旅游方面,NLP技术助力法律智能,能够在一定程度上利用现有大数据以及机器学习/深度学习与自然语言处理技术,提供一些智能的解决方案。
面向法律领域的罪名预测、问题分类与FAQ问答模型设计与实现【NLP】
2、数据来源
本次项目的数据来源于两个,一个是罪名预测数据集,一个是法律问答数据集:
1)罪名预测数据集
CAIL 2018年设置了罪名预测、法条推荐、刑期预测三个任务,并提供了包含268万刑事法律文书的数据集,数据集地址参见:
数据集论文 CAIL2018: A Large-Scale Legal Dataset for Judgment Prediction 已公布。
数据集下载地址: https://cail.oss-cn-qingdao.aliyuncs.com/CAIL2018_ALL_DATA.zip
使用该数据集请引用 CAIL2018: A Large-Scale Legal Dataset for Judgment Prediction 和 Overview of CAIL2018: Legal Judgment Prediction Competition。
2)罪名问句数据集
主要来自于公开数据整理,格式为一个问题下多个答案集合的QA对集合;
数据地址:https://github.com/liuhuanyong/CrimeKgAssitant/blob/master/data/qa_corpus.json.zip
二、罪名预测任务
1、问题类型
罪名一共包括202种罪名,文件放在dict/crime.txt中, 详细内容举例如下:
2、模型实验
3、模型效果
执行 python crime_classify.py
crime desc:这宗案情凶残的案件中,受害人樊敏仪是一名夜总会舞女,1997年因筹措祖母的医药费,偷取任职皮条客的首被告陈文乐数千元港币及其他财物(另一说是指毒品债)。首被告陈文乐于是吩咐次被告梁胜祖及第三被告梁伟伦向女受害人追债。女受害人为求还清债项,怀孕后仍继续接客,3名被告将欠款不断提高,受害人因无力偿还,因而触怒三人。1999年3月17日梁胜祖及梁伟伦按照首被告要求,将受害人从葵涌丽瑶邨富瑶楼一单位押走,禁锢于尖沙咀加连威老道31号3楼一单位。当回到单位后,梁伟伦质问受害人为何不还钱、为何不肯回电话,连踢受害人超过50次。3名被告用木板封着该单位的玻璃窗,以滚油泼向受害人的口腔,在伤口上涂上辣椒油,逼她吞吃粪便及喝尿。被告之后把烧溶的塑胶吸管滴在她的腿上,并命令受害人发出笑声。受害人开始神志不清,并不时挑起伤口上的焦疤,被告于是以电线紧紧捆缠受害人双手多个小时,之后又用铁棍殴打她双手。
crime label: 非法拘禁
*********************************************************
crime desc:有很多人相信是莉齐进行了这次谋杀,虽然她始终没有承认,陪审团也得出了她无罪的结论。莉齐·鲍顿是一个32岁的老姑娘,她被指控用刀杀死了自己的父亲和继母。虽然她最后无罪获释,但人们知道,她对继母一直怀恨在心,而在谋杀发生的前一天,她曾预言了将要发生的事。凶杀案发生时她已30岁。1892年8月4日中午,莉齐·鲍顿叫唤她的邻居说,她的父亲被杀了,警察到来时,发现她的母亲也死了。母亲被斧子砍了18下,父亲被砍了10下。消息立即被传开了,媒体认为莉齐本人极有谋杀嫌疑。然而次年六月,法庭宣判莉齐无罪。此后,她的故事广为流传,被写成了小说,芭蕾,百老汇,歌剧。最后是日本的教科书将她的童谣作为鹅妈妈童话收录的。
crime label: 故意杀人
*********************************************************
crime desc:017年5月26日11时许,被告人陈某、李某林与一同前去的王某,在信阳市羊山新区中级人民法院工地南大门门口,拦住被害人张某军,对其进行殴打,致其右手受伤,损伤程度属轻伤一级。2017年7月22日,李某林主动到信阳市公安局羊山分局投案。在审理过程中,被告人陈某、李某林与被害人张某军自愿达成赔偿协议,由陈某、李某林赔偿张祖军全部经济损失共计10万元,张某军对二被告人予以谅解。
crime label: 故意伤害
*********************************************************
crime desc:被告人赵某某于1999年5月起在某医院眼科开展医师执业活动,2010年11月其与医院签订事业单位聘用合同,从事专业技术工作,并于2011年取得临床医学主任医师职称。2014年3月起其担任眼科主任,在院长、分管院长和医务科领导下负责本科医疗、教学、科研和行政管理等工作。赵某某担任眼科主任期间,利用职务之便,收受人工晶体供货商给付的回扣共计37万元。赵某某作为眼科主任,在医院向供货商订购进口人工晶体过程中,参与了询价、谈判、合同签订和采购的过程。2015年4月12日,赵某某接受检察院调查,如实供述了收受人工晶体销售商回扣的事实。
crime label: 受贿
*********************************************************
crime desc:金陵晚报报道 到人家家里偷东西,却没发现可偷之物,丧尽天良的小偷为了报复竟将屋内熟睡的老太太强奸。日前,卢勇(化名) 在潜逃了一年后因再次出手被抓获。 31岁的卢勇是安徽枞阳县人,因家境贫寒,到现在仍是单身。今年6月份,他从老家来到南京,连续作案多起。7月1日凌晨,当他窜至莫愁新村再次作案时,当场被房主抓获。 经审讯又查明,去年8月30日清晨4时许,卢勇来宁行窃未遂后,贼心不死。又到附近的另一户人家行窃。他在房内找了一圈都没找到任何值钱的东西,只有个女人在床上睡觉。卢勇觉得没偷到东西亏了,想报复一下这户人家,就走到床边捂住女人的嘴,不顾反抗将其强奸后逃跑。 据卢勇供述,他当时并没注意女人的年纪,直到事后他才发现对方竟然是个早已上了年纪的老太太。日前,卢勇因涉嫌盗窃和强奸被检方审查起诉。
crime label: 强奸
三、法务咨询问题分类任务
2、模型实验
法务咨询数据库一共有20万条训练数据,要做的是13类型咨询问题多分类问题.本项目采用的方式为LSTM与CNN:
训练数据规模 | 测试集规模 | 模型 | 训练时长 | 训练集准确率 | 测试集准确率 |
---|---|---|---|---|---|
4W | 1W | CNN | 15*20s | 0.984 | 0.959 |
4W | 1W | LSTM | 51*20s | 0.838 | 0.717 |
3、模型效果
执行 python question_classify.py
question desc:他们俩夫妻不和睦,老公总是家暴,怎么办
question_type: 婚姻家庭 0.9994359612464905
*********************************************************
question desc:我们老板总是拖欠工资怎么办,怎么起诉他
question_type: 劳动纠纷 0.9999903440475464
*********************************************************
question desc:最近p2p暴雷,投进去的钱全没了,能找回来吗
question_type: 刑事辩护 0.3614000678062439
*********************************************************
question desc:有人上高速,把车给刮的不像样子,如何是好
question_type: 交通事故 0.9999163150787354
*********************************************************
question desc:有个老头去世了,儿女们在争夺财产,闹得不亦乐乎
question_type: 婚姻家庭 0.9993444085121155
四、法务咨询FAQ自动问答
基于已有的QA对进行问答搜索,可以支持自动问答等业务场景。
1、模型设计
很自然的,我们可以选用Elasticsearch进行搜索。
'''创建ES索引,确定分词类型'''
def create_mapping(self):
node_mappings = {
"mappings": {
self.doc_type: { # type
"properties": {
"question": { # field: 问题
"type": "text", # lxw NOTE: cannot be string
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"index": "true" # The index option controls whether field values are indexed.
},
"answers": { # field: 问题
"type": "text", # lxw NOTE: cannot be string
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"index": "true" # The index option controls whether field values are indexed.
},
}
}
}
}
if not self.es.indices.exists(index=self._index):
self.es.indices.create(index=self._index, body=node_mappings)
print("Create {} mapping successfully.".format(self._index))
else:
print("index({}) already exists.".format(self._index))
2、模型效果
运行 python crime_qa.py
question:朋友欠钱不还咋办
answers: ['欠款金额是多少 ', '多少钱呢', '律师费诉讼费都非常少都很合理,一定要起诉。', '大概金额多少?', '需要看标的额和案情复杂程度,建议细致面谈']
*******************************************************
question:昨天把人家车刮了,要赔多少
answers: ['您好,建议协商处理,如果对方告了你们,就只能积极应诉了。', '您好,建议尽量协商处理,协商不成可起诉']
*******************************************************
question:最近丈夫经常家暴,我受不了了
answers: ['报警要求追究刑事责任。', '您好,建议起诉离婚并请求补偿。', '你好!可以起诉离婚,并主张精神损害赔偿。']
*******************************************************
question:毕业生拿了户口就跑路可以吗
answers: 您好,对于此类问题,您可以咨询公安部门
*******************************************************
question:孩子离家出走,怎么找回来
answers: ['孩子父母没有结婚,孩子母亲把孩子带走了?这样的话可以起诉要求抚养权的。毕竟母亲也是孩子的合法监护人,报警警察一般不受理。']
*******************************************************
question:村霸把我田地给占了,我要怎么起诉
answers: ['可以向上级主管部门投诉解决', '您好,您可以及时向土地管理部门投诉的!', '对方侵权,可以向法院起诉。', '你好,对方侵权,可以向法院起诉。', '你好,可起诉处理,一、当事人起诉,首先应提交起诉书,并按对方当事人人数提交相应份数的副本。当事人是公民的,应写明双方当事人的姓名、性别、年龄、籍贯、住址;当事人是单位的,应写明单位名称、地址、法定代表人或负责人姓名。起诉书正文应写明请求事项和起诉事实、理由,尾部须署名或盖公章。二、根据"谁主张谁举证"原则,原告向法院起诉应提交下列材料:1、原告主体资格的材料。如居民身份证、户口本、护照、港澳同胞回乡证、结婚证等证据的原件和复印件;企业单位作为原告的应提交营业执照、商业登记证明等材料的复印件。2、证明原告诉讼主张的证据。如合同、协议、债权文书(借条、欠条等)、收发货凭证、往来信函等。', '您好,起诉维权。', '您好,可以起诉解决。']
*******************************************************
question:售卖危违禁物品,有什么风险
answers: ['没什么']
*******************************************************
question:找不到女朋友啊.。
answers: 您好,对于此类问题,您可以咨询公安部门
*******************************************************
question:我要离婚
answers: ['现在就可向法院起诉离婚。', '不需要分开两年起诉离婚。感情完全破裂就可以提起诉讼离婚。', '你可以直接起诉离婚', '直接起诉']
*******************************************************
question:醉驾,要坐牢吗
answers: ['要负刑事责任很可能坐牢', '由警方处理.,']
*******************************************************
question:你好,我向大学提出退学申请,大学拒绝,理由是家长不同意。我该怎么办?
answers: ['自己可决定的 ']
*******************************************************
question:请问在上班途中,出车祸我的责任偏大属于工伤吗?
answers: ['属于工伤']
*******************************************************
question:结婚时女方拿了彩礼就逃了能要回来吗
answers: ['可以要求退还彩礼。,']
*******************************************************
question:房产证上是不是一定要写夫妻双方姓名
answers: ['可以不填,即使一个人的名字,婚后买房是共同财产。', '不是必须的', '可以写一方名字,对方公证,证明该房产系你一人财产', '你好,不是必须']
*******************************************************
question:儿女不履行赡养义务是不是要判刑
answers: ['什么情况了?']
*******************************************************
question:和未成年人发生关系,需要坐牢吗
answers: ['女孩子在发生关系的时候是否满14周岁,如果是且自愿就不是犯罪', '你好,如果是双方愿意的情况下是不犯法的。', '发生性关系时已满十四岁并且是自愿的依法律规定不构成强奸罪,不构成犯罪的。', '若是自愿,那就没什么可说了。', '双方愿意不犯法', '你好 如果是自愿的 不犯法 ', '自愿的就没事']
*******************************************************
question:撞死人逃跑要怎么处理
answers: ['等待警察处理。,']
总结
1、本项目实现的是以罪刑为核心的法务应用落地的一个demo尝试。
2、本项目采用机器学习,深度学习的方法完成了罪名预测,客服问句类型预测多分类任务,取得了较好的性能,模型可以直接使用。
3、本项目构建起了一个20万问答集,856个罪名的知识库,分别存放在data/kg_crime.json和data/qa_corpus.json文件中。
4、法务问答,可以是智能客服在法律资讯网站中的一个应用场景落地. 本项目采用的是ES+语义相似度加权打分策略实现的问答技术路线, 权值计算与阈值设定可以用户指定。
5、对于罪名知识图谱中的知识可以进一步进行结构化处理,这是后期可以完善的地方。
6、如何将罪名,咨询,智能研判结合在一起,形成通路,其实可以进一步提升知识图谱在法务领域的应用。
二、领域短语挖掘中的质量评估、常用算法解读与开源实现
对于一些未登录词或者领域词的识别时,会出现切分过细或者切分不合法的问题。
为了解决以上两个问题,短语提取逐步成为了当前NLP的一个重要任务,常见于文本分词、特征挖掘、领域实体发现、概念挖掘等场景当中。
解决这种情况,引申出来了多种方式:
当我们对一个文本进行分词,或者分字,并将所有长度不超过n的子串都当作潜在的词,然后组成ngram后,会得到很多候选的短语集合。
而为了得到真正有实际意义的短语,通常需要设计评判规则,并使用相应的统计手段加以实现。通过整理调研相关资料,一个高质量的短语应该满足高频率、一致性、信息量以及完整性等几个特性。
不过,上述方法遇到一个很大的问题,即需要统计的上下文语料,在语料缺失的情况下,就需要使用一些固定的构词规则【基于词法的或基于句法的】进行无监督抽取,或者使用有监督标注和训练的方法进行抽取。
本文主要围绕NLP中的短语抽取问题,展开论述,介绍基于高频性与TFIDF判定、一致性与PMI点间互信息判定、完整性及左右信息熵判定三种统计短语抽取方法,基于词性与构词模板规则生成的方法以及基于有监督识别的三种方法,供大家一起参考。
一、高频性与TFIDF的统计判定
1)思想
高频率认为,一个n-gram出现的频率越高,那么它是高质量的文章的可能性就越高,频率很低的组合成词的可能性很小。
2)原理
在实现上,可以使用TF算法计算候选短语出现的频次加以过滤,也可以在此基础上使用TF-IDF、TextRank算法或者词性过滤规则,过滤文中出现的频率高但是重要的词,如代词,副词,介词,助词等。
3)实现
def build_wordsdict(self, text):
word_dict = {}
candi_words = []
candi_dict = {}
for word in pseg.cut(text):
if word.flag[0] in ['n', 'v', 'a'] and len(word.word) > 1:
candi_words.append(word.word)
if word.word not in word_dict:
word_dict[word.word] = 1
else:
word_dict[word.word] += 1
count_total = sum(word_dict.values())
for word, word_count in word_dict.items():
if word in candi_words:
candi_dict[word] = word_count/count_total
else:
continue
return candi_dict
def extract_keywords(self, text, num_keywords):
keywords_dict = {}
candi_dict = self.build_wordsdict(text)
for word, word_tf in candi_dict.items():
word_idf = self.idf_dict.get(word, self.common_idf)
word_tfidf = word_idf * word_tf
keywords_dict[word] = word_tfidf
keywords_dict = sorted(keywords_dict.items(), key=lambda asd:asd[1], reverse=True)
return keywords_dict[:num_keywords]
开源实现:https://github.com/liuhuanyong/KeyInfoExtraction
二、一致性与PMI点间互信息的统计判定
1)思想
一致性,用于评估候选短语n-gram中的单词的搭配是否合理,与此相对应的是凝固度,即一个字组合片段里面字与字之间的紧密程度,例如“琉璃”、“榴莲”这样的词的凝固度就非常高,电影院的凝固度和合理性要比“的电影”要高。
不过,该方法存在一定的缺点,如果只看一致性,即凝固程度的话,会倾向于找出“巧克”、“俄罗”、“颜六色”、“柴可夫”等实际上是“半个词”的片段。
2)原理
在具体实现上,可以使用PMI点间互信息值来衡量,一个ngran短语的PMI点间互信息值越大成词的可能性越大。:
设定p(x)为文本片段x在整个语料中出现的概率,那么:
“电影院”的凝合程度就是p(电影院)与p(电)*p(影院)比值和p(电影院)与p(电影)*p(院)的比值中的较小值
“的电影”的凝合程度则是p(的电影)分别除以p(的)*p(电影)和p(的电)*p(影)所得的商的较小值。
其中,有个实现的细节,即针对一个ngram,需要对其进行切分组合,然后分别计算组合中的PMI值,然后排序,例如,针对 ngram ’abcd’:
首先,把字组合切分成不同的组合对,拆成(‘a’, ‘bcd’), (‘ab’, ‘cd’), (‘abc’, ‘d’)
然后,计算每个组合对的凝固度:*D(s1, s2)=P(s1s2)/(P(s1)P(s2))
最后,取这些组合对凝固度中最小的那个为整个字组合的凝固度,通常,我们会对概率取对数处理。
3)实现
def compute_mi(p1, p2, p12):
return math.log2(p12) - math.log2(p1) - math.log2(p2)
开源实现:https://github.com/zhanzecheng/Chinese_segment_augment
三、完整性及左右信息熵的统计判定
1)思想
高质量的短语需要是一个完整的语义单元,如“巧克力“与“巧克”相比,完整性要更高。一般来说,一个短语如果完整,那么其能够被独立运用的概率就越高,其独立使用时出现的前后上下文就越丰富。
与此相对应的概念叫做自由度,即一个字组合片段能独立自由运用的程度。 比如“巧克力”里面的“巧克”的凝固度就很高,和“巧克力”一样高,但是它自由运用的程度几乎为零,所以“巧克”不能单独成词。
2)原理
在具体实现上,我们可以使用左右信息熵来进行实现,左右邻熵,描绘的是一个短语左右搭配的丰富度,一个好的短语左右搭配应该是非常丰富的,分别计算它的左邻居信息熵和右邻居信息熵,取其中较小的为该组合的自由度,自由度越大成词的可能性越大。
例如,援引文献5的论述,对于“吃葡萄不吐葡萄皮不吃葡萄倒吐葡萄皮”,“葡萄”一词出现了四次,其中左邻字分别为{吃, 吐, 吃, 吐} ,右邻字分别为 {不, 皮, 倒, 皮} 。
H(x) = E[I(xi)] = E[log(2,1/P(xi))] = -∑P(xi)log(2,P(xi)) (i=1,2,..n)
其中,x表示随机变量,与之相对应的是所有可能输出的集合,定义为符号集,随机变量的输出用x表示,P(x)表示输出概率函数。变量的不确定性越大,熵也就越大,把它搞清楚所需要的信息量也就越大。
根据上述公式计算,
“葡萄”一词的左邻字的信息熵为:
–(1/2)·log(1/2)–(1/2)·log(1/2)≈0.693,
“葡萄”一词的右邻字的信息熵为:
–(1/2)·log(1/2)–(1/4)·log(1/4)–(1/4)·log(1/4)≈1.04
通过计算,可以发现“葡萄”一词的右邻字更加丰富一些。
3)实现
def compute_entropy(neighbours):
if neighbours:
right_sum = sum(neighbours)
#TODO 计算改词的右领字熵,可以怎么优化呢?
right_prob = map(lambda x:x/right_sum, neighbours)
right_entropy = sum(map(lambda x:-(x)*math.log(x), right_prob))
return right_entropy
else:
return 0
与一致性类似,如果只看完整性即自由程度的话,则会把 “吃了一顿”、“看了一遍”、“睡了一晚”、“去了一趟”中的“了一”提取出来,因为它的左右邻字都太丰富了。
因此,在最终实现的时候,通常都会综合考虑上面三个因素,然后分别设定阈值或者做得分的加和,得到一个整体的值,再进行阈值过滤,最终输出。
开源实现:https://github.com/zhanzecheng/Chinese_segment_augment
四、词性与构词模板的规则判定
上面列举的三种方法,都需要大量的文本进行统计,而且语料库越大,效果越好,但对于一些query或者短文本情况下,则并不奏效,因此,通常可以采用短语构词模板进行判定,将满足这种词性组合模式的短语过滤出来。
1)思想
词性模板规则判定的方法,其思想在于短语通常满足n+v,或者n+n,或a+n的模式,通过文本分词和词性标注,进行组合匹配,就可以输出。
2)原理与实现
通过jieba等开源工具进行分词和词性标注,可以得到一些有实际意义的词,但这些词分的粒度太细,可以进一步组合,例如,将连续的名词组合成新的NP短语。
IP = "(([NERMQ]*P*[ABDP]*)*([ABDV]{1,})*([NERMQ]*)*([VDAB]$)?([NERMQ]*)*([VDAB]$)?)*"
IP = "([NER]*([PMBQADP]*[NER]*)*([VPDA]{1,}[NEBRVMQDA]*)*)"
MQ = '[DP]*M{1,}[Q]*([VN]$)?'
VNP = 'V*N{1,}'
NP = '[NER]{1,}'
REN = 'R{2,}'
VP = 'P?(V|A$|D$){1,}'
PP = 'P?[NERMQ]{1,}'
SPO_n = "n{1,}"
SPO_v = "v{1,}"
def extract_ngram(pos_seq, self.NP):
ss = self.transfer_tags(pos_seq)
def gen():
for s in range(len(ss)):
for n in range(self.minlen, 1 + min(self.maxlen, len(ss) - s)):
e = s + n
substr = ss[s:e]
if re.match(regex + "$", substr):
yield (s, e)
return list(gen())
也可以使用standfordparser/corenlp进行浅层句子成分分析,得到相应结果。
from stanfordcorenlp import StanfordCoreNLP
nlp_ch = StanfordCoreNLP(r'stanford-corenlp-full-2018-10-05', lang='zh')
print (nlp_ch.parse('浙江大学有七个校区。'))
结果:
(ROOT
(IP
(NP (NR 浙江) (NN 大学))
(VP (VE 有)
(NP
(QP (CD 七)
(CLP (M 个)))
(NP (NN 校区))))
(PU 。)))
通过提取NP标签,可以直接提取出“浙江大学”、“七个校区”两个NP短语。
开源实现:https://github.com/liuhuanyong/EventTriplesExtraction
五、基于有监督标注分类评分的短语判定
在基于有监督的短语挖掘工作上,韩家炜老师团队逐步产出了系列具有代表性的工作,包括TopMine,SegPhrase、AutoPhrase,很具有启发性.
1、TopMine:频率模式挖掘+统计分析
TopMine,发表于《Scalable Topical Phrase Mining from Text Corpora》一文。
1)主要思想
该工作主要是对语料库文本的Topic进行挖掘,不同于以往采用Uni-gram的方法,而是将Topic 挖掘分成了两个步骤:通过Phrase Mining对文本进行分割;随后进行基于Phrase约束的Topic模型。
2)原理
首先,先进行Phrase挖掘,用到phrase本身的统计量以及phrase上下文信息。在统计量熵,直接使用频次作为过滤条件,生成所有的phrase候选,在上下文信息上,构造了一个类似PMI的指标,用来衡量合并之后的得分。
3)开源实现
https://github.com/anirudyd/topmine
2、SegPhrase:弱监督、高质量的 Phrase Mining
SegPhrase,发表于《Mining Quality Phrases from Massive Text Corpora》一文
1)思想
TopMine方法通常会产生低质量的主题短语,或者在中等大小的数据集上也会出现可伸缩性差的问题。SegPhrase是一种新的短语挖掘框架,将文档分为单词短语和多词短语,以及一个新的主题模型,该模型基于诱导文档划分,从而产生高质量的短语集合。
2)原理
根据用户需求生成常用短语候选,然后根据有关一致性和信息要求的特征来估计短语质量,并通过短语分段估计校正的频率,并将基于整流频率的基于细分的特征添加到短语质量分类器的特征集中,最后过滤低整流频率的短语,以满足后处理步骤的完整性要求。
3)开源实现
https://github.com/shangjingbo1226/SegPhrase
知识图谱AI大本营
知识图谱AI大本营 是一个追踪、解读、讨论和报道知识图谱、深度学习、机器学习等AI前沿成果的学术平台,致力于让人工智能领域的国内外优秀科研工作者们得到交流学习的机会。