概率软逻辑(PSL,Probabilistic soft logic)示例演练和模块解释

  这里将引导您完成Simple Acquaintances示例的Groovy版本。

一、建立示例项目

  首先,确保您的系统满足先决条件。然后克隆psl-examples存储库:

git clone https://github.com/linqs/psl-examples.git

二、运行

  进入简单groovy示例的根目录:

cd psl-examples/simple-acquaintances/groovy

  在根目录下运行(这里特别容易失败):

mvn compile
mvn eclipse:eclipse     //把项目编译成eclipse版本

  通过eclipse里的maven导入项目后,无报错即可运行,结果如下:

0    [main] INFO  org.linqs.psl.examples.simpleacquaintances.Run  - Defining model rules
139  [main] INFO  org.linqs.psl.examples.simpleacquaintances.Run  - Loading data into database
171  [main] INFO  org.linqs.psl.examples.simpleacquaintances.Run  - Starting inference
389  [main] INFO  org.linqs.psl.application.inference.LazyMPEInference  - Beginning inference round 1.
488  [main] INFO  org.linqs.psl.reasoner.admm.ADMMReasoner  - Optimization completed in 411 iterations. Primal res.: 0.028260373, Dual res.: 9.052008E-4
488  [main] INFO  org.linqs.psl.application.inference.LazyMPEInference  - Inference round 1 complete.
566  [main] INFO  org.linqs.psl.application.inference.LazyMPEInference  - Beginning inference round 2.
566  [main] INFO  org.linqs.psl.reasoner.admm.ADMMReasoner  - Optimization completed in 1 iterations. Primal res.: NaN, Dual res.: NaN
566  [main] INFO  org.linqs.psl.application.inference.LazyMPEInference  - Inference round 2 complete.
584  [main] INFO  org.linqs.psl.examples.simpleacquaintances.Run  - Inference complete
631  [main] INFO  org.linqs.psl.examples.simpleacquaintances.Run  - Accuracy: 0.400000, F1: 0.280000, Positive Class Precision: 0.466667, Positive Class Recall: 0.200000, Negative Class Precision: 0.377778, Negative Class Recall: 0.680000

  要查看示例的输出,请检查groovy下的inferred-predicates/KNOWS.txt文件:

inferred-predicates/KNOWS.txt

  应该看到一些输出,如:

'Arti' 'Ben'  0.48425865173339844
'Arti' 'Steve'       0.5642937421798706
< ... 48 rows omitted for brevity ...>
'Jay'  'Dhanya'      0.4534565508365631
'Alex' 'Dhanya'      0.48786869645118713

  输出的确切顺序可能会改变,为简洁起见,省略了一些行。
  现在我们已经运行了示例,让我们看看示例中唯一的源文件:

src/main/java/org/linqs/psl/examples/simpleacquaintances/Run.groovy。

三、Groovy源码文件解析

1. 配置(Configuration)

  在构造函数中,您可以看到创建的ConfigBundle:

config = ConfigManager.getManager().getBundle("simpleacquaintances");

  请注意,传入的字符串getBundle()是此配置集的前缀。这意味着特定于此程序的所有配置键都应该以前缀simpleacquaintances为前缀。

2. 谓词定义(Defining Predicates)

  该definePredicates()方法为我们的示例定义了三个谓词:

model.add predicate: "Lived", types: [ConstantType.UniqueStringID, ConstantType.UniqueStringID]; 
model.add predicate: "Likes", types: [ConstantType.UniqueStringID, ConstantType.UniqueStringID]; 
model.add predicate: "Knows", types: [ConstantType.UniqueStringID, ConstantType.UniqueStringID];

  这里的每个谓词都有两个唯一的属性为字符串标识符的作为参数,请注意,对于唯一标识符(Unique),ConstantType.UniqueStringID和ConstantType.UniqueIntID都是可用的。值得一提的是,拥有整数标识符通常需要在用户方面进行更多预处理,但能获得更好的性能。

谓词释义:
  • Lived 表示一个人住在特定的位置。例如:Lived(Sammy,SantaCruz)表示Sammy住在Santa Cruz。
  • Likes 表示一个人喜欢某事的程度。例如:Likes(Sammy,Hiking)会表明Sammy喜欢徒步旅行的程度。
  • Knows 表明一个人认识其他人。例如:Knows(Sammy,Jay)会表示Sammy和Jay相互认识。

3. 规则定义(Defining Rules)

  该defineRules()方法为该示例定义了六个规则。有些页面涵盖了PSL 规则规范和Groovy中的规则规范。我们将讨论以下两条规则:

model.add( rule: "20: Lived(P1, L) & Lived(P2, L) & (P1 != P2) -> Knows(P1, P2) ^2" ); 
model.add( rule: "5: !Knows(P1, P2) ^2" );

  第一条规则可以理解为 “ 如果P1和P2是不同的两个人,并且两者都住在同一个地方L,那么他们彼此认识 ” 。此规则需要注意的一些要点是:

  • 变量L在两个Lived原子中重复使用,因此必须引用相同的位置L。
  • (P1 != P2)指的是P1和P2是不同的人(不同的独特ID)。

  第二条规则是作为先验的特殊规则。请注意这条规则与其他所有规则的含义并不相同。相反,此规则可以理解为“默认情况下,人们彼此不了解”。因此,该项目将首先相信没有人相互了解,并且这个先验的观念将被其他定义的规则作为证据来克服。

4. 加载数据(Loading Data)

  该loadData()方法将数据从data目录中的文件加载到PSL正在使用的虚拟数据存储库中。为了便于理解,我们来查看两个文件:

Inserter inserter = dataStore.getInserter(Lived, obsPartition); 
inserter.loadDelimitedData(Paths.get(DATA_PATH, "lived_obs.txt").toString()); 
inserter = dataStore.getInserter(Likes, obsPartition); 
inserter.loadDelimitedDataTruth(Paths.get(DATA_PATH, "likes_obs.txt").toString());

  两个部分都使用一个加载数据Inserter。两个调用之间的主要区别在于第二个调用正在加载真值,而第一个调用默认真值是1。
  如果我们查看文件内容,我们会看到以下行:


../data/lives_obs.txt

Jay    Maryland
Jay    California

../data/likes_obs.txt

Jay    Machine Learning  1
Jay    Skeeball 0.8

  在lives_obs.txt,没有必要使用真值,因为生活在某个地方是一个离散的行为。你要么住在那里,要么没有。然而,喜欢某些东西为连续的软真值会更符合常理。如:Jay有 100%的可能会喜欢机器学习,但他只有80%的可能喜欢Skeeball。

5. 分区(Partitions)

  在PSL中,使用分区来组织数据。分区只不过是数据的容器,但我们使用它们将特定的数据块保存在一起或分开。例如,如果我们正在运行结果评估模块,我们必须确保在训练中不使用我们的测试分区。
  PSL用户通常在至少三个不同的分区中组织他们的数据(在本例中您可以看到所有这些分区):
  •obsPartition 在这个例子中称为观察分区:在这个分区中我们放置了实际的观察数据。在这个例子中,我们把关于谁住在哪里,谁喜欢什么,谁知道谁在观察分区中的所有观察。
  •targetsPartition 在本例中称为目标分区:在这个分区中,我们放置了我们想要推断的值的原子。例如,如果我们想要推断Jay和Sammy相互认识的概率,那么我们会将原子Knows(Jay, Sammy)放入目标分区。
  •truthPartition 在这个例子中称为事实分区:在这个分区中,我们放置了实际值的数据,但不包括在我们的已知观察数据,目的用于评估模型推理效果。例如,如果我们知道Jay和Sammy确实相互了解,我们会将Knows(Jay, Sammy)事实分区放入真值1。

6. 运行推理(Running Inference)

  该runInference()方法处理我们加载的所有数据的运行推理。
  在我们进行推理之前,我们必须建立一个用于推理的数据库:

Database inferDB = dataStore.getDatabase(targetsPartition, [Lived, Likes] as Set, obsPartition);

  getDatabase()方法对于DataStore是获得一个数据库的正确方法。此方法至少需要两个参数:

  •允许此数据库写入的分区targetsPartition。在推理中,我们将原子的推断真值写入目标分区,因此我们需要将其打开以进行写入。
  •要在写入分区中关闭的一组分区obsPartition。即使我们将值写入写分区,我们可能只有一些谓词,我们实际上想要推断它们的值。此参数允许您关闭那些没有更改的谓词(封闭谓词)。最后,getDatabase()获取要包含在此数据库中的任意数量的只读分区。在我们的示例中,我们希望在进行推理时包含我们的观察结果。

  接下来我们准备推理部分:

InferenceApplication inference = new MPEInference(model, inferDB);
inference.inference();
inference.close();
inferDB.close();

  对于MPEInference构造函数,我们提供我们的模型和数据库来推断。要查看结果,我们需要查看目标分区。

7. 输出(Output)

  该方法writeOutput()处理打印(输出)出推断的结果。此方法有两个关键行:

Database resultsDB = ds.getDatabase(targetsPartition);
...
for (GroundAtom atom : resultsDB.getAllGrondAtoms(Knows)) {

  第一行得到一个新的数据库,我们可以从中获取原子。请注意,我们把targetsPartition作为写分区传入,但实际上我们只是从它读取已经推理得到的结果数据。
  第二行使用Queries来迭代此数据库中的所有为 Knows 的原子。

8. 评估(Evaluation)

  最后,用evalResults()方法评判我们的模型的效果。本DiscreteEvaluator类提供基本的工具来比较两个分区。在这个例子中,我们将目标分区与真值分区进行比较。

private void evalResults(Partition targetsPartition, Partition truthPartition) {
        Database resultsDB = dataStore.getDatabase(targetsPartition);
        Database truthDB = dataStore.getDatabase(truthPartition, [Knows] as Set);

        Evaluator eval = new DiscreteEvaluator();
        eval.compute(resultsDB, truthDB, Knows);
        log.info(eval.getAllStats());

        resultsDB.close();
        truthDB.close();
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • 一、什么是PSL 概率软逻辑(PSL)是由马里兰大学和加利福尼亚大学圣克鲁斯分校的统计关系学习组LINQS开发的机...
    十一年前梦一场_5486阅读 3,925评论 1 2
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,590评论 18 139
  • 分析函数,也称为窗口函数,通常被认为仅对数据仓库SQL有用。使用分析函数的查询,基于对数据行的分组来计算总量值。与...
    猫猫_tomluo阅读 3,305评论 3 18
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,894评论 2 89
  • 在《海上钢琴师》之童年基因(上)中,我们解读了1900一生无法走下大船迈向新大陆的必然。有的朋友觉得不解渴,要阐述...
    孟享阅读 319评论 0 1