概率软逻辑(PSL,Probabilistic soft logic)通用(可处理中文)版本
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了概率软逻辑(PSL,Probabilistic soft logic)通用(可处理中文)版本相关的知识,希望对你有一定的参考价值。
一、简介
概率软逻辑(PSL,Probabilistic soft logic)是用于开发概率模型的机器学习框架,由加州大学圣克鲁兹分校和马里兰大学联合开发。目前其复杂的环境构建方式和Groovy语言表达给像作者一样的初学者带来了不小的困难,而且诸多的依赖项使原本已经构建好的模型小错误频繁。
经过努力,作者将其构建成单个jar包,并且加入编码机制使其可以支持各种语言的数据。主要贡献有三:
1.将PSL原本复杂的依赖打包为单个jar包,加入依赖即可开始使用。
2. 将不够熟悉的Groovy语言模型构建方式全部转化为java支持,只需一个.java文件便可进行模型构建。
3.加入编码机制,使PSL可以处理除英文以外的语言。
链接:https://pan.baidu.com/s/1PybpNoPpvk4jmSMw7Rm_7A 密码:g1cx
链接文件夹里有三个文件:
PSL_swust1.0.jar 修改过的PSL模型
SimpleAcquaintances.zip PSL官方例子的改编版本(不包含权重学习和函数)
Entity_resolution.zip PSL官方例子的改编版本(包含权重学习和函数)
二、举例说明
以SimpleAcquaintances内SimpleAcquaintances.java为例进行阐述。
1.配置项
/*
* ======【配置项】======
*/
Tool tool = new Tool();
DataStore datastore;
HashMap<String, Partition> partitions = new HashMap<String, Partition>();
String path = tool.getPath(new SimpleAcquaintances().getClass())
+ "/../data/";// SimpleAcquaintances改为当前类名
String[] paths = tool.getFiles(path);
PSLMODEL psl = new PSLMODEL(paths, "H2");// 在安装了postgresql数据库时可H2改为postgresql
datastore = psl.getDatastore();
psl.transcoding = false;//是否给数据编码(此值只决定数据是否编码,谓词默认都要编码)
使用时SimpleAcquaintances需要改为当前类名,为了获取当前项目文件夹的数据文件夹data。另外当安装配置了postgreSQL时可将H2改为postgresql来使用postgreSQL数据库(H2为模型自带数据库,运行于内存)。transcoding 项设置为true时候会给数据编码(此时可设置谓词为UniqueIntID属性,提升模型计算效率),可以处理各种语言的数据,但是编码后无法合理使用PSL自带相似度计算函数(因为编码后数据不是原来的字符串了,相似度函数平时很少用到,自定义函数可以正常使用)。
2.定义分区
// 权重学习分区
// partitions.put("learn_obs", datastore.getPartition("learn_obs"));
// partitions.put("learn_target",
// datastore.getPartition("learn_target"));
// partitions.put("learn_truth", datastore.getPartition("learn_truth"));
// 实验分区
datastore = psl.getDatastore();
partitions.put("obs", datastore.getPartition("obs"));
partitions.put("target", datastore.getPartition("target"));
partitions.put("truth", datastore.getPartition("truth"));
psl.setPartitions(partitions);
当需要权重学习时(有训练数据时),需要定义权重学习分区。obs代表已知数据分区,target代表要推理的目标数据储存分区(当要使用LazyInference推理时可以不往里面加载数据),truth为真实数据分区。
3.谓词(函数)定义
HashMap<String, ConstantType[]> p = new HashMap<String, ConstantType[]>();
HashMap<String, ExternalFunction> f = new HashMap<String, ExternalFunction>();
// 添加谓词
p.put("Lived", new ConstantType[] { ConstantType.UniqueStringID,ConstantType.UniqueStringID });
p.put("Likes", new ConstantType[] { ConstantType.UniqueStringID,ConstantType.UniqueStringID });
p.put("Knows", new ConstantType[] { ConstantType.UniqueStringID,ConstantType.UniqueStringID });
// 添加函数
// f.put("SameInitials", new SameInitials());
// f.put("SameNumTokens", new SameNumTokens());
psl.definePredicates(p, f);// 谓词、函数输入模型
谓词定义只需替换即可,可随意增加,常用属性有UniqueStringID、UniqueIntID、String等。函数可以定义PSL自带相似度函数(transcoding 为false时)。
4.规则定义
String[] rules = {
"20.0: ( LIVED(P1, L) & (P1 != P2) & LIVED(P2, L) ) >> KNOWS(P1, P2) ^2",
"5.0: ( (L1 != L2) & (P1 != P2) & LIVED(P2, L2) & LIVED(P1, L1) ) >> ~( KNOWS(P1, P2) ) ^2",
"10.0: ( LIKES(P2, L) & (P1 != P2) & LIKES(P1, L) ) >> KNOWS(P1, P2) ^2",
"5.0: ( KNOWS(P1, P2) & KNOWS(P2, P3) & (P1 != P3) ) >> KNOWS(P1, P3) ^2",
"1.0 * KNOWS(P1, P2) + -1.0 * KNOWS(P2, P1) = 0.0 .",
"5.0: ~( KNOWS(P1, P2) ) ^2"
};
psl.defineRules(rules);// 规则输入模型
权重: 规则体 >> 规则头 ,^2代表平方优化,按照两个例子里的规则格式增加规则即可。
5.导入数据
/*
* ======【导入数据】======
* 其中"1-2"表示对数据的一二列进行转码
* 只有在transcoding = true时作用,表示只对1,2两列进行转码
*/
psl.loadData("Lived", path + "Lived_obs.txt", "obs", "1-2");
psl.loadDataTruth("Likes", path + "likes_obs.txt", "obs", "1-2");
psl.loadData("Knows", path + "knows_obs.txt", "obs", "1-2");
psl.loadData("Knows", path + "knows_targets.txt", "target","1-2");
psl.loadDataTruth("Knows", path + "knows_truth.txt", "truth","1-2");
// ArrayList<String[]> likepe = tool.fileToArrayList(path + "likes_obs.txt", "1-2-3");
// psl.insertDataTruth("Likes", likepe, "obs");
// psl.insertData("Likes", likepe, "obs");
提供了loadData,loadDataTruth,insertData,insertDataTruth四种方法载入数据,loadData("谓词",谓词对应文件路径, "导入分区", "1-2"),loadData,loadDataTruth区别在于loadDataTruth最后一列为概率值;insertData,insertDataTruth需要将文件转化为List数据,适用于一个数据文件存储了多个谓词的数据, "1-2-3"代表要取出1、2、3作为谓词的数据,insertDataTruth取出的每个数据 "1-2-...-n"的第n项是概率值。其中"1-2"表示对数据的一二列进行转码, 只有在transcoding = true时作用,表示只对数据文件里的1,2两列进行转码,多列增加即可,以“-”分开。
6.权重学习
// psl.learnWeights("learn_target", "Lived-Likes", "learn_obs", "learn_truth","MaxLikelihoodMPE");
("训练数据目标分区", "封闭谓词(即:作为已知数据,推理过程不会再新产生的原子)", "训练数据已知数据分区", "真实数据分区","权重学习方法")
有训练数据时候可进行权重学习优化规则权重。实现了五种权重优化方法:
"LazyMaxLikelihoodMPE",
"MaxLikelihoodMPE",
"MaxPiecewisePseudoLikelihood",
"MaxPseudoLikelihood",
"SimplexSampler"
替换即可使用。
7.打印输出模型
psl.printModel();
可查看已经定义的模型。
8.运行推理
// psl.runLazyInference("已知数据分区", "目标分区(存放结果)");
// psl.runLazyInference("obs", "target");
// psl.runInference(""已知数据分区"","封闭谓词1-封闭谓词2" , "目标分区(包含定义的目标原子)");
psl.runInference("obs","Lived-Likes" , "target");
两种推理方式LazympeInference,mpeInference。
9.数据输出
psl.writeOutput("target", "Knows", path
+ "/result/knows_inffer.txt");
("目标分区", "要输出的数据对应谓词1-要输出的数据对应谓词2", 输出路径)。
10.评估实验结果
psl.evalResults("target", "truth", "Knows", path
+ "/result/evalResults.txt");
("目标分区", "真实数据分区", "目标谓词1-目标谓词2", 评估结果输出路径)。值得一提的是,"目标谓词1-目标谓词2"需要包含所有真实数据分区里所包含数据对应的谓词。
11.关闭模型
psl.closeModel();
推理完成,请关闭模型。
以上是关于概率软逻辑(PSL,Probabilistic soft logic)通用(可处理中文)版本的主要内容,如果未能解决你的问题,请参考以下文章
概率软逻辑(PSL,Probabilistic soft logic)示例演练和模块解释
概率软逻辑(PSL,Probabilistic soft logic)在Groovy语言中的规则规范
概率潜在语义分析(Probabilistic Latent Semantic Analysis,PLSA)
概率图模型(PGM,Probabilistic Graphical Model)