DeepDive教程-模型构建
教程列表
DeepDive的推理和学习过程都是基于因子图进行的,下面先介绍下什么是因子图,后面将如何构建模型
2.0 基础工作
本文的数据和工具都来自于http://www.openkg.cn/dataset/cn-deepdive,然后将其文档按照自己的理解写了出来,并且对其中的一些细节内容加入了写详细的描述
本文假设读者已经安装好deepdive了,如果没有安装,请参见上面链接中的教程文档,或者自行百度
本篇是DeepDive系列第二篇,第一篇点传送门
2.1 背景知识:因子图
- Variables:如果这种结点的值已知,它就可以当作一个证据变量(用来推断别的值);这个值也可以是未知的,这事就叫做查询变量,就是我们需要进行预测得到的值,比如图中的 X 1 , X 2 , X 3 X_1,X_2,X_3 X1,X2,X3;
- Factor:每个因子都可以连接到多个变量,并用因子函数定义它们之间的关系,比如图中的
f
1
,
f
2
,
f
3
,
f
4
f_1,f_2,f_3,f_4
f1,f2,f3,f4 ;每个因子(或者说因子函数)都有一个权重值,来表示这个因子影响力的大小。换个说法,这个权重值表示了某个因子的可信程度,正数越大则越正确,负数越小则越错误(错误表示某种不可能,比如一个人的亲儿子同时是他的亲兄弟,这就是一个错误,所以这个因子的权重就应该是一个很小的负值)。因子函数的权重可以通过训练学习得到,也可以手动赋值(通过脚本或者
app.ddlog
)。
通过前面的步骤,我们已经将需要用到的数据都准备好了,下面构建我们的模型。
2.1 模型构建
(1) 通过上一篇的介绍和学习,至少我们知道了,最终想要得到的是什么(请问你自己,是什么?)。是判断某两家公司之间是否存在交易,对吧。就像前面的数据一样,我们的推理数据同样需要存储他们的数据表,因为他是算出来的,所以这些是变量,故DeepDive给它取了个名字:Variable Relation(变量关系)。变量关系的定义方法,就是在普通关系的关系名后面加上一个问好:?
,就可以表示这个表是变量表。比如我们要求的是是否有交易,所以可以按照下面例子定义一个变量关系:
@extraction
has_transaction?(
p1_id text,
p2_id text
).
这里的变量关系结合到前面说的因子图,应该是那一部分呢?应该是变量这一部分,变量即可以包含已知的知识,也可是未知的要抽取的知识,所以这个变量关系其实就是定义了因子图中的一部分变量节点,下一小部分就是填入因子和已知知识的过程。当然一个DeepDive项目中可以有很多种变量节点,构建一个复杂的因子图来实现更准确的抽取。
(2). 上一篇文章(数据准备)已经对数据进行了简单的打标,也就是相当于机器学习任务中,我们有了已标记数据。把已经标记了的数据,输入到has_transaction
表中,也就是可以得到因子图中的已知的变量节点。可以按照下面的例子来操作,这个条件的意思很明显吧。
has_transaction(p1_id, p2_id) = if l > 0 then TRUE
else if l < 0 then FALSE
else NULL end :- transaction_label_resolved(p1_id, p2_id, l).
此时变量表中的部分变量label已知,成为了先验变量。
(3). 最后编译执行这个表,可以得到带有已知结果的变量节点:
deepdive compile && deepdive do has_transaction
2.2 因子图构建
(1). 指定特征
前面已经定义了因子图中的基本节点,下面应该定义其中的因子了,还有用来学习的特征。transaction_candidate
这个表中,我们存储了所有候选的公司的匹配对,transaction_feature
中存储了每个公司对之间的语言特征(详情见上一篇博文)。现在我们告诉因子图,如何训练权重,就是根据我们之前抽取到的特征来训练。比如下面:
将每一对has_transaction中的实体对和特征表连接起来,通过特征的连接,全局学习这些特征的权重。在app.ddlog中定义:
@weight(f)
has_transaction(p1_id, p2_id) :-
transaction_candidate(p1_id, _, p2_id, _),
transaction_feature(p1_id, p2_id, f).
(2) 定义一个简单的因子,指定变量间的依赖性,也是一个简单的推理规则:
在当前的工作中,甲公司和乙公司发生交易,那么必定乙公司和甲公司也发生了交易,交易是一个双向的关系,所以我们现在按照下面的例子来定义一个推理的因子,表示这种关系,其中weight
中的3.0
认为赋予这个规则的权重,不用学习。
@weight(3.0)
has_transaction(p1_id, p2_id) => has_transaction(p2_id, p1_id) :-
transaction_candidate(p1_id, _, p2_id, _).
变量表间的依赖性使得deepdive很好地支持了多关系下的抽取。
(3). 最后,编译,并生成最终的概率模型:
deepdive compile && deepdive do probabilities
查看我们预测的公司间交易关系概率:
deepdive sql "SELECT p1_id, p2_id, expectation FROM has_transaction_label_inference ORDER BY random() LIMIT 20"
p1_id | p2_id | expectation |
---|---|---|
1201778739_118_170_171 | 1201778739_118_54_60 | 0 |
1201778739_54_30_35 | 1201778739_54_8_11 | 0.035 |
1201759193_1_26_31 | 1201759193_1_43_48 | 0.07 |
1201766319_65_331_331 | 1201766319_65_159_163 | 0 |
1201761624_17_30_35 | 1201761624_17_9_14 | 0.188 |
1201743500_3_0_5 | 1201743500_3_8_14 | 0.347 |
1201789764_3_16_21 | 1201789764_3_75_76 | 0 |
1201778739_120_26_27 | 1201778739_120_29_30 | 0.003 |
1201752964_3_21_21 | 1201752964_3_5_10 | 0.133 |
1201775403_1_83_88 | 1201775403_1_3_6 | 0 |
1201778793_15_5_6 | 1201778793_15_17_18 | 0.984 |
1201773262_2_85_88 | 1201773262_2_99_99 | 0.043 |
1201734457_24_19_20 | 1201734457_24_28_29 | 0.081 |
1201752964_22_48_50 | 1201752964_22_9_10 | 0.013 |
1201759216_5_38_44 | 1201759216_5_55_56 | 0.305 |
1201755097_4_18_22 | 1201755097_4_52_57 | 1 |
1201750746_2_0_5 | 1201750746_2_20_26 | 0.034 |
1201759186_4_45_46 | 1201759186_4_41_43 | 0.005 |
1201734457_18_7_11 | 1201734457_18_13_18 | 0.964 |
1201759263_36_18_20 | 1201759263_36_33_36 | 0.002 |
上面数据借鉴于http://www.openkg.cn/dataset/cn-deepdive中的教程文档
阶段性结束
到这里,一个简单的DeepDive应用就完成了,后续的工作很简单,就是把DeepDive推理的概率按照一定规则从数据库中导出到一个知识数据库中(比如概率大于0.95)的公司交易关系,就构建完成了一个很简单的知识图谱。
当然DeepDive还有很多功能这里没有用到,我后面的文章会一一提到,如果你感兴趣也可以参见DeepDive的官方网站:http://deepdive.stanford.edu