OpenNLP: обучение пользовательской модели NER для нескольких объектов

Я пытаюсь обучить пользовательскую модель NER для нескольких объектов. Вот пример обучающих данных:

count all <START:item_type> operating tables <END> on the <START:location_id> third <END> <START:location_type> floor <END>
count all <START:item_type> items <END> on the <START:location_id> third <END> <START:location_type> floor <END>
how many <START:item_type> beds <END> are in <START:location_type> room <END> <START:location_id> 2 <END>

Метод NameFinderME.train(.) принимает строковый параметр type. Какая польза от этого параметра? И как я могу обучить модель для нескольких объектов (например, item_type, location_type, location_id в моем случае)

public static void main(String[] args) {
    String trainingDataFile = "/home/OpenNLPTest/lib/training_data.txt";
    String outputModelFile = "/tmp/model.bin";
    String sentence = "how many beds are in the hospital";

    train(trainingDataFile, outputModelFile, "location_type");
    predict(sentence, outputModelFile);
}

private static void train(String trainingDataFile, String outputModelFile, String tagToFind) {
    File inFile = new File(trainingDataFile);
    NameSampleDataStream nss = null;
    try {
        nss = new NameSampleDataStream(new PlainTextByLineStream(new java.io.FileReader(inFile)));
    } catch (Exception e) {}

    TokenNameFinderModel model = null;
    int iterations = 100;
    int cutoff = 5;
    try {
        // Does the 'type' parameter mean the entity type that I am trying to train the model for?
        // What if I need to train for multiple entities?
        model = NameFinderME.train("en", tagToFind, nss, (AdaptiveFeatureGenerator) null, Collections.<String,Object>emptyMap(), iterations, cutoff); 
    } catch(Exception e) {}

    try {
        File outFile = new File(outputModelFile);           
        FileOutputStream outFileStream = new FileOutputStream(outFile);
        model.serialize(outFileStream);
    }
    catch (Exception ex) {}
}

private static void predict(String sentence, String modelFile) throws Exception {
    FileInputStream modelInToken = new FileInputStream("/tmp/en-token.bin");
    TokenizerModel modelToken = new TokenizerModel(modelInToken);
    Tokenizer tokenizer = new TokenizerME(modelToken); 
    String tokens[] = tokenizer.tokenize(sentence);

    FileInputStream modelIn = new FileInputStream(modelFile);

    TokenNameFinderModel model = new TokenNameFinderModel(modelIn);
    NameFinderME nameFinder = new NameFinderME(model);
    Span nameSpans[] = nameFinder.find(tokens);

    double[] spanProbs = nameFinder.probs(nameSpans);

    for( int i = 0; i<nameSpans.length; i++) {
        System.out.println(nameSpans[i]);
    }

}


person Darth.Vader    schedule 13.07.2015    source источник


Ответы (1)


Аргумент type для NameFinderME.train используется как тип по умолчанию для обучающих данных, которые не включают параметр типа. Это актуально только в том случае, если у вас есть образец, который выглядит так:

<START> operating tables <END>

Вместо такого:

<START:item_type> operating tables <END>

В документации разработчика говорится, что для обучения нескольких типов сущностей

Учебный файл может содержать несколько типов. Если обучающий файл содержит несколько типов, созданная модель также сможет обнаружить эти несколько типов. На данный момент рекомендуется обучать только модели одного типа, так как поддержка нескольких типов все еще находится в экспериментальной стадии.

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

Сам путь кода стабилен, причина, по которой мы его туда поместили, заключается в том, что он не показал хорошей производительности на английских данных.

В любом случае, производительность может сильно зависеть от вашего набора данных и языка.

Если вы не получаете хорошей производительности с моделью, которая обрабатывает несколько типов, альтернативой может быть создание нескольких копий ваших обучающих данных, где каждая копия модифицируется, чтобы включать только один тип. Затем вы должны обучить отдельную модель на каждом наборе обучающих данных. На этом этапе у вас должна быть (например) модель item_type, модель location_type и модель location_id. Затем вы можете запустить свой ввод через каждую модель, чтобы обнаружить различные типы.

person John Wiseman    schedule 19.07.2015