Как загрузить и использовать CRF, обученный с помощью Mallet?

Я обучил CRF, используя GenericAcrfTui, он записывает ACRF в файл. Я не совсем уверен, как загрузить и использовать обученную CRF, но

import cc.mallet.grmm.learning.ACRF;
import cc.mallet.util.FileUtils;
ACRF c = (ACRF) FileUtils.readObject(Paths.get("acrf.ser.gz").toFile());

кажется, работает. Однако маркировка кажется неправильной и, похоже, зависит от меток, которые я передаю в качестве входных данных. Как пометить загруженным ACRF?

Вот как я делаю свою маркировку:

GenericAcrfData2TokenSequence instanceMaker = new GenericAcrfData2TokenSequence();
instanceMaker.setDataAlphabet(c.getInputAlphabet());
instanceMaker.setIncludeTokenText(true);
instanceMaker.setFeaturesIncludeToken(true);
instanceMaker.setLabelsAtEnd(false);
Pipe pipe = new SerialPipes(new Pipe[] {
        instanceMaker,
        new TokenSequence2FeatureVectorSequence(c.getInputAlphabet(),
                true, false),
});
InstanceList testing = new InstanceList(pipe);
Iterator<Instance> testSource = new LineGroupIterator(
    // initialize the labels to O
        new StringReader("O O ---- what W=the@1 W=hell@2\n"
                    + "O O ---- the W=what@-1 W=hell@1\n"
                    + "O O ---- hell W=what@-2 W=the@-1"),
        Pattern.compile("^\\s*$"), true);
testing.addThruPipe(testSource);
System.out.println(c.getBestLabels(testing.get(0)));

Я понял это, посмотрев на GenericAcrfTui. Некоторые вещи, которые я пробовал:

  • Когда я попытался дать разные начальные метки (кроме «O»), результирующая маркировка изменилась, но это не помогает, потому что я не могу угадать, какие метки давать изначально, иначе мне не понадобился бы тегировщик.
  • Я пытался вообще не давать никаких начальных меток, но это только вызывало исключения, кажется, Маллет действительно хочет эти метки.

Я заметил, что есть также SimpleTagger, который можно использовать для обучения CRF, но я думаю, что у меня все еще будет та же проблема, используя его для маркировки нового ввода.

Любая помощь с маркировкой с использованием CRF из SimpleTagger или GenericAcrfTui поможет.

Кстати, я обычно использую CRF++, но для этой задачи я хочу построить свой собственный график, потому что я использую функции разбора зависимостей.


person Justin Harris    schedule 20.03.2014    source источник


Ответы (1)


Я понял!

Проблема заключалась в том, что канал не знал целевой алфавит. Решение состоит в том, чтобы использовать CRF Pipe, например:

Pipe pipe = crf.getInputPipe();

вместо того, чтобы делать это безумие, чтобы сделать свой собственный Pipe.

Теперь, если кто-нибудь знает более приятный способ сделать новый Instance с помощью запроса, это тоже было бы хорошо, я просто скопировал то, что делает тренер.

person Justin Harris    schedule 21.03.2014