概率軟邏輯(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)通用(可處理中文)版本