JGibbLDA是Java版本的LDA(Latent Dirichlet Allocation)实现,下载地址http://jgibblda.sourceforge.net/
我这里下载的是JGibbLDA-v.1.0,下载完成解压时候的文件结构如下
其中models文件夹当中是两个已经成长的主题模型例子,lib文件夹当中是个jar包args4j-2.0.6.jar,是用于处理java命令行参数的一个jar包,导入项目时需将此包也导入构建路径,我用的是win 7,感觉用命令行别扭,就想着把它改造一下,用配置文件吧。
JGibbLDA的参数基本上有下面几个:
- #-est 此参数初次训练LDA模型;
- #-estc:此参数用于从已有的模型当中训练LDA模型;
- #-inf: 此参数用于对新的文档进行测试;
- #-model <string>: 已有的模型的名称;
- #-alpha<double>:α超参数,默认是50/K,K为主题数量;
- #-beta <double>: β超参数,默认为0.1;
- #-ntopics <int>: 主题数量,默认100;
- #-niters <int>: Gibbs抽样迭代次数,默认为2000;
- #-savestep <int>: 保持模型的迭代次数,即每迭代多少次将保持一次结果模型。默认为200;
- # -twords <int>: 每个主题最可能的单车数量。默认为0,如果设定大于0,比如20,JGibbLDA将会根据此参数在每次保持模型时为每个主题打印出最可能的20个词;
- #-dir <string>: 输入词集文件夹目录;此目录也是模型结果输出目录
- # -dfile <string>: 输入词集文件名称
输入词集格式一般如下
[M]
[document1]
[document2]
...
[documentM]
其中:M是文档个数[documenti]为文档词集,按空格分隔
输出数据
建立模型阶段,会输出5类以如下规则命名的文件类型:
model-XXXXX.others:
model-XXXXX.phi
model-XXXXX.theta
model-XXXXX.tassign
model-XXXXX.twords
XXXXX都以数字组成。最后一次迭代所保存的这些数字将会换成“final”。
其中:
.others为“信息文件”。文件保存的是跟该LDA模型有关的参数,比如alpha,beta,ntopiccs,ndocs,nwords,liter( the Gibbssampling iteration at which the model was saved)
.phi文件为“词项-类簇概率分布文件”,表现上是一个大矩阵M。其中,假设设类簇的数目topict为1000个,每一个类簇需要列出top 100个词项wordw,则M以100为行,1000为列。即M每一行是词项,每一列是类簇。M元素值则为条件概率p(wordw|topict)。
.theta文件为“记录-类簇概率分布文件”。表现上也是一个大矩阵M。每一行是训练数据的一条记录,每一列是一个类簇,元素值则为条件概率 p(topict|documentm)。
.tassign文件为“记录-词项-类簇分布文件”。文件每一行代表训练数据的一条记录,原记录由一组词项组成,现每一行为原来的记录词项指派了其最大可能的所属类簇。注意,不包含该记录所属类簇。
.twords文件为“词项-类簇推断文件”。这个文件作为模型参数结果推断出了每一个类簇下最优的topN个词项及其概率。请注意这里的类簇数和N都是事先指定的。
这5个文件包括副产品wordmap.txt在有些应用场景下有时并不是完全需要的,是否生成可视情况而定。如果利用类簇下topN词项来做基于距离的聚类,可能只需.twords即可。
推断新数据和关键代码
将产生如下文件,其组织和意义如前所述一致:
newdocs.dat.others
newdocs.dat.phi
newdocs.dat.tassign
newdocs.dat.theta
newdocs.dat.twords
修改运行模式为配置文件的修改代码如下
PropertyUtils.java读取配置文件src/option.properties
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package cn.edu.gdut.utils; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.util.Properties; 8 9 public class PropertyUtils { 10 11 private static Properties p = null; 12 13 private static Properties getProperties() { 14 if (p == null) { 15 synchronized (FileUtils.class) { 16 if (p == null) { 17 p = new Properties(); 18 try { 19 InputStream in = new FileInputStream(new File( 20 "src/option.properties")); 21 p.load(in); 22 in.close(); 23 } catch (IOException e) { 24 e.printStackTrace(); 25 return null; 26 } 27 } 28 } 29 } 30 return p; 31 } 32 33 public static boolean getEst() { 34 if (getProperties().get("est") == null 35 || "".equals(getProperties().get("est"))) { 36 return false; 37 } 38 return ("true").equals((String) getProperties().get("est")) ? true 39 : false; 40 } 41 42 public static boolean getEstc() { 43 if (getProperties().get("estc") == null 44 || "".equals(getProperties().get("estc"))) { 45 return false; 46 } 47 return ("true").equals((String) getProperties().get("estc")) ? true 48 : false; 49 } 50 51 public static boolean getInf() { 52 if (getProperties().get("inf") == null 53 || "".equals(getProperties().get("inf"))) { 54 return false; 55 } 56 return ("true").equals((String) getProperties().get("inf")) ? true 57 : false; 58 } 59 60 public static double getAlpha() { 61 if (getProperties().get("alpha") == null 62 || "".equals(getProperties().get("alpha"))) { 63 return 50.0 / getNtopics(); 64 } 65 return Double.parseDouble((String) getProperties().get("alpha")); 66 } 67 68 public static double getBeta() { 69 if (getProperties().get("beta") == null 70 || "".equals(getProperties().get("beta"))) { 71 return 0.1; 72 } 73 return Double.parseDouble((String) getProperties().get("beta")); 74 } 75 76 public static int getNiters() { 77 if (getProperties().get("niters") == null 78 || "".equals(getProperties().get("niters"))) { 79 return 2000; 80 } 81 return Integer.parseInt((String) getProperties().get("niters")); 82 } 83 84 public static int getNtopics() { 85 if (getProperties().get("ntopics") == null 86 || "".equals(getProperties().get("ntopics"))) { 87 return 100; 88 } 89 return Integer.parseInt((String) getProperties().get("ntopics")); 90 } 91 92 public static void setNtopics(int K) { 93 getProperties().setProperty("ntopics", String.valueOf(K)); 94 } 95 96 public static int getSavestep() { 97 if (getProperties().get("savestep") == null 98 || "".equals(getProperties().get("savestep"))) { 99 return 200; 100 } 101 return Integer.parseInt((String) getProperties().get("savestep")); 102 } 103 104 public static int getTwords() { 105 if (getProperties().get("savestep") == null 106 || "".equals(getProperties().get("savestep"))) { 107 return 200; 108 } 109 return Integer.parseInt((String) getProperties().get("twords")); 110 } 111 112 public static String getDir() { 113 if (getProperties().get("dir") == null 114 || "".equals(getProperties().get("dir"))) { 115 return "models\\casestudy-zh"; 116 } 117 return (String) getProperties().get("dir"); 118 } 119 120 public static String getOutDir() { 121 if (getProperties().get("outdir") == null 122 || "".equals(getProperties().get("outdir"))) { 123 return "LDAModels\\casestudy-zh"; 124 } 125 return (String) getProperties().get("outdir"); 126 } 127 128 public static String getDfile() { 129 if (getProperties().get("dfile") == null 130 || "".equals(getProperties().get("dfile"))) { 131 return "sdate.dat"; 132 } 133 return (String) getProperties().get("dfile"); 134 } 135 136 public static String getModel() { 137 if (getProperties().get("dfile") == null 138 || "".equals(getProperties().get("dfile"))) { 139 return ""; 140 } 141 return (String) getProperties().get("model"); 142 } 143 144 145 }
修改LDA代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package jgibblda; 2 3 import cn.edu.gdut.util.FileUtil; 4 5 public class LDA { 6 7 public static void main(String args[]) { 8 LDACmdOption option = new LDACmdOption(); 9 fillOption(option); 10 if (!option.est && !option.estc && !option.inf) { 11 System.out.println("请选择一种模式!"); 12 return; 13 } 14 15 if (option.est || option.estc) { 16 Estimator estimator = new Estimator(); 17 estimator.init(option); 18 estimator.estimate(); 19 } else if (option.inf) { 20 Inferencer inferencer = new Inferencer(); 21 inferencer.init(option); 22 23 Model newModel = inferencer.inference(); 24 25 for (int i = 0; i < newModel.phi.length; ++i) { 26 System.out 27 .println("-----------------------\ntopic" + i + " : "); 28 for (int j = 0; j < 10; ++j) { 29 System.out.println(inferencer.globalDict.id2word.get(j) 30 + "\t" + newModel.phi[i][j]); 31 } 32 } 33 } 34 } 35 36 private static void fillOption(LDACmdOption option) { 37 option.est = FileUtil.getEst(); 38 option.estc = FileUtil.getEstc(); 39 option.inf = FileUtil.getInf(); 40 option.alpha = FileUtil.getAlpha(); 41 option.beta = FileUtil.getBeta(); 42 option.dir = FileUtil.getDir(); 43 option.dfile = FileUtil.getDfile(); 44 option.modelName = FileUtil.getModel(); 45 option.niters = FileUtil.getNiters(); 46 option.K = FileUtil.getNtopics(); 47 option.savestep = FileUtil.getSavestep(); 48 option.twords = FileUtil.getTwords(); 49 } 50 51 }
这个时候,lib文件夹当中args4j-2.0.6.jar可以丢弃了。