我正在尝试在项目中使用MALLET机器学习库来进行词义消歧。我的特征向量由目标令牌左右两侧的x标记的固定大小标记窗口组成。 MALLET训练实例的创建方式如下:
// Create training list
Pipe pipe = new TokenSequenceLowercase();
InstanceList instanceList = new InstanceList(pipe);
Instance trainingInstance = new Instance(data, senseID, instanceID, text);
instanceList.add(trainingInstance);
...
// Training
ClassifierTrainer classifierTrainer = new NaiveBayesTrainer();
Classifier classifier = classifierTrainer.train(trainingList);
其中
我原本期望InstanceList的dataAlphabet和targetAlphabet属性是在添加训练实例时动态构建的,但事实并非如此。因此,我的代码在NPE的上一行中失败,因为NB培训师的targetAlphabet属性为NULL。
查看MALLET代码(感谢开源),我可以看到非构造字母表的根本原因是我的数据和标签没有实现AlphabetCarrying接口。因此,在Instance类中返回NULL:
public Alphabet getDataAlphabet() {
if (data instanceof AlphabetCarrying)
return ((AlphabetCarrying)data).getAlphabet();
else
return null;
}
我觉得这很令人困惑,因为文档说数据和标签可以是任何对象类型。但是上面的这个错误似乎表明我需要构造一个实现AlphabetCarrying的特定数据/标签类。
我觉得我错过了关于这些字母的概念层面的重要内容。另外,我不清楚,如果数据字母表应该来自所有培训实例或只是一个。 有人可以解释这里的错误吗?
干杯,
马丁
答案 0 :(得分:4)
在这里回答我自己的问题:解决方案是添加一些管道,特别是TokenSequence2FeatureSequence管道来构建数据字母表,使用Target2Label来构建标签字母表。此外,需要使用instanceList.addThruPipe(trainingInstance)添加训练实例。
这是基于Mallet邮件列表的答案。