使用Java中的Mallet在LDA中折叠(估计新文档的主题)
我正在通过Java使用Mallet,但我不知道如何根据我培训过的现有主题模型评估新文档 我生成模型的初始代码与中的代码非常相似,之后我只是将模型保存为Java对象。在后面的过程中,我从文件中重新加载该Java对象,通过使用Java中的Mallet在LDA中折叠(估计新文档的主题),java,mallet,topic-modeling,Java,Mallet,Topic Modeling,我正在通过Java使用Mallet,但我不知道如何根据我培训过的现有主题模型评估新文档 我生成模型的初始代码与中的代码非常相似,之后我只是将模型保存为Java对象。在后面的过程中,我从文件中重新加载该Java对象,通过.addInstances()添加新实例,然后仅根据原始培训集中的主题评估这些新实例 提供了一些高级建议,但我不知道如何将它们应用到Mallet框架中 非常感谢您的帮助。我发现答案隐藏在: 推理实际上也列在问题中提供的列表中(最后几行) 对于任何对保存/加载经过训练的模型并使用它推
.addInstances()
添加新实例,然后仅根据原始培训集中的主题评估这些新实例
提供了一些高级建议,但我不知道如何将它们应用到Mallet框架中
非常感谢您的帮助。我发现答案隐藏在:
推理实际上也列在问题中提供的列表中(最后几行) 对于任何对保存/加载经过训练的模型并使用它推断新文档的模型分布的整个代码感兴趣的人,这里有一些代码片段: 在
model.estimate()
完成后,您就拥有了经过实际训练的模型,因此可以使用标准的JavaObjectOutputStream
对其进行序列化(因为ParallelTopicModel
实现了Serializable
):
但是请注意,当您进行推断时,您还需要通过相同的管道传递新句子(如实例
),以便对其进行预处理(tokenzie等),因此,您还需要保存管道列表(因为我们使用串行管道
,您可以创建实例,然后对其进行序列化):
为了加载模型/管道并使用它们进行推断,我们需要反序列化:
private static void InferByModel(String sentence) {
// define model and pipeline
ParallelTopicModel model = null;
SerialPipes pipes = null;
// load the model
try {
FileInputStream outFile = new FileInputStream("model.ser");
ObjectInputStream oos = new ObjectInputStream(outFile);
model = (ParallelTopicModel) oos.readObject();
} catch (IOException ex) {
System.out.println("Could not read model from file: " + ex);
} catch (ClassNotFoundException ex) {
System.out.println("Could not load the model: " + ex);
}
// load the pipeline
try {
FileInputStream outFile = new FileInputStream("pipes.ser");
ObjectInputStream oos = new ObjectInputStream(outFile);
pipes = (SerialPipes) oos.readObject();
} catch (IOException ex) {
System.out.println("Could not read pipes from file: " + ex);
} catch (ClassNotFoundException ex) {
System.out.println("Could not load the pipes: " + ex);
}
// if both are properly loaded
if (model != null && pipes != null){
// Create a new instance named "test instance" with empty target
// and source fields note we are using the pipes list here
InstanceList testing = new InstanceList(pipes);
testing.addThruPipe(
new Instance(sentence, null, "test instance", null));
// here we get an inferencer from our loaded model and use it
TopicInferencer inferencer = model.getInferencer();
double[] testProbabilities = inferencer
.getSampledDistribution(testing.get(0), 10, 1, 5);
System.out.println("0\t" + testProbabilities[0]);
}
}
由于某些原因,我对加载的模型的推断与原始模型的推断不完全相同,但这是另一个问题的问题(如果有人知道,我很乐意听到)为了在连续推断后获得相同的结果,您只需添加推断器。setRandomSeed(1)。但是,如果我对已经在模型中使用过的文本文档使用推理器,则无法获得相同的主题分布。感谢提供有用的代码片段。但就性能而言,最好是在训练模型时直接生成一个推理器,而不是先加载整个模型,然后从中获取推理器。@Phauly-有时候你想训练一个模型,然后再使用它。在这种情况下,如果有必要训练模型,然后保存它以便在必要时用于推理(如果我理解您的评论),那么这就是方法。此外,如果您想在训练后保存模型,并在测试前加载它(使它们分开),您可以看看这个答案
try {
FileOutputStream outFile = new FileOutputStream("model.ser");
ObjectOutputStream oos = new ObjectOutputStream(outFile);
oos.writeObject(model);
oos.close();
} catch (FileNotFoundException ex) {
// handle this error
} catch (IOException ex) {
// handle this error
}
// initialize the pipelist (using in model training)
SerialPipes pipes = new SerialPipes(pipeList);
try {
FileOutputStream outFile = new FileOutputStream("pipes.ser");
ObjectOutputStream oos = new ObjectOutputStream(outFile);
oos.writeObject(pipes);
oos.close();
} catch (FileNotFoundException ex) {
// handle error
} catch (IOException ex) {
// handle error
}
private static void InferByModel(String sentence) {
// define model and pipeline
ParallelTopicModel model = null;
SerialPipes pipes = null;
// load the model
try {
FileInputStream outFile = new FileInputStream("model.ser");
ObjectInputStream oos = new ObjectInputStream(outFile);
model = (ParallelTopicModel) oos.readObject();
} catch (IOException ex) {
System.out.println("Could not read model from file: " + ex);
} catch (ClassNotFoundException ex) {
System.out.println("Could not load the model: " + ex);
}
// load the pipeline
try {
FileInputStream outFile = new FileInputStream("pipes.ser");
ObjectInputStream oos = new ObjectInputStream(outFile);
pipes = (SerialPipes) oos.readObject();
} catch (IOException ex) {
System.out.println("Could not read pipes from file: " + ex);
} catch (ClassNotFoundException ex) {
System.out.println("Could not load the pipes: " + ex);
}
// if both are properly loaded
if (model != null && pipes != null){
// Create a new instance named "test instance" with empty target
// and source fields note we are using the pipes list here
InstanceList testing = new InstanceList(pipes);
testing.addThruPipe(
new Instance(sentence, null, "test instance", null));
// here we get an inferencer from our loaded model and use it
TopicInferencer inferencer = model.getInferencer();
double[] testProbabilities = inferencer
.getSampledDistribution(testing.get(0), 10, 1, 5);
System.out.println("0\t" + testProbabilities[0]);
}
}