Я пытаюсь использовать библиотеку машинного обучения MALLET в проекте для устранения неоднозначности слова. Мои векторы объектов состоят из окна токенов фиксированного размера х токенов слева и справа от целевого токена. Учебные примеры 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);
где
Я ожидал, что свойства dataAlphabet и targetAlphabet экземпляра InstanceList будут построены на лету, когда будут добавлены учебные экземпляры, но это не так. Следовательно, мой код не работает в последней строке выше с NPE, так как свойство targetAlphabet тренера NB равно NULL.
Глядя на код MALLET (благодаря открытому исходному коду), я вижу, что основной причиной неконструкций Alphabets является то, что мои данные и метки не реализуют интерфейс AlphabetCarrying. Поэтому NULL возвращается в классе Instance:
public Alphabet getDataAlphabet() {
if (data instanceof AlphabetCarrying)
return ((AlphabetCarrying)data).getAlphabet();
else
return null;
}
Я считаю это довольно запутанным, потому что в документации говорится, что данные и метки могут быть любого типа объекта. Но эта вышеприведенная ошибка указывает, напротив, что мне нужно построить конкретный класс данных/меток, который реализует AlphabetCarrying.
Я чувствую, что я упускаю что-то важное на концептуальном уровне в отношении этих алфавитов. Кроме того, я не понимаю, если алфавит данных должен быть получен из всех учебных экземпляров или только одного. Может кто-нибудь объяснить ошибку здесь?
Ура,
Мартин
Отвечая на мой собственный вопрос здесь: решение заключалось в том, чтобы добавить некоторые каналы, в частности, к протоколу TokenSequence2FeatureSequence для создания алфавита данных и Target2Label для создания алфавита метки. Кроме того, необходимо добавить экземпляры тренировки, используя instanceList.addThruPipe(trainingInstance).
Это основано на ответах на список рассылки Mallet.