Лемматизация Java

Я ищу реализацию лемматизации для английского языка в Java. Я уже нашел несколько, но мне нужно что-то, что не требует много памяти для запуска (1 ГБ сверху). Благодарю. Мне не нужен стеммер.

5 ответов

Java-библиотека Stanford CoreNLP содержит лемматизатор, который требует немного ресурсов, но я запустил его на своем ноутбуке с <512 МБ ОЗУ.

Чтобы использовать это:

  1. Загрузите файлы jar;
  2. Создайте новый проект в своем редакторе по вашему выбору / создайте скрипт ant, который включает все файлы jar, содержащиеся в архиве, который вы только что загрузили;
  3. Создайте новую Java, как показано ниже (на основе фрагмента с сайта Стэнфорда);
import java.util.Properties;

public class StanfordLemmatizer {

    protected StanfordCoreNLP pipeline;

    public StanfordLemmatizer() {
        // Create StanfordCoreNLP object properties, with POS tagging
        // (required for lemmatization), and lemmatization
        Properties props;
        props = new Properties();
        props.put("annotators", "tokenize, ssplit, pos, lemma");

        // StanfordCoreNLP loads a lot of models, so you probably
        // only want to do this once per execution
        this.pipeline = new StanfordCoreNLP(props);
    }

    public List<String> lemmatize(String documentText)
    {
        List<String> lemmas = new LinkedList<String>();

        // create an empty Annotation just with the given text
        Annotation document = new Annotation(documentText);

        // run all Annotators on this text
        this.pipeline.annotate(document);

        // Iterate over all of the sentences found
        List<CoreMap> sentences = document.get(SentencesAnnotation.class);
        for(CoreMap sentence: sentences) {
            // Iterate over all tokens in a sentence
            for (CoreLabel token: sentence.get(TokensAnnotation.class)) {
                // Retrieve and add the lemma for each word into the list of lemmas
                lemmas.add(token.get(LemmaAnnotation.class));
            }
        }

        return lemmas;
    }
}

Ответ Криса о Лемматизаторе Стэндфорда великолепен! Абсолютно красивый. Он даже включил указатель на файлы jar, поэтому мне не пришлось искать его в Google.

Но в одной из его строк кода была синтаксическая ошибка (он каким-то образом переключил завершающие закрывающие скобки и точку с запятой в строке, начинающейся с "lemmas.add...), и забыл включить импорт.

Что касается ошибки NoSuchMethodError, она обычно вызывается тем, что этот метод не делается общедоступным статическим, но если вы посмотрите на сам код (по адресу http://grepcode.com/file/repo1.maven.org/maven2/com.guokr/stan-cn-nlp/0.0.2/edu/stanford/nlp/util/Generics.java?av=h) это не проблема. Я подозреваю, что проблема где-то в пути сборки (я использую Eclipse Kepler, поэтому не было проблем с настройкой 33-х jar-файлов, которые я использую в своем проекте).

Ниже приведено небольшое исправление кода Криса, а также пример (мои извинения перед Evanescence за то, что они зарезали их идеальную лирику):

import java.util.LinkedList;
import java.util.List;
import java.util.Properties;

import edu.stanford.nlp.ling.CoreAnnotations.LemmaAnnotation;
import edu.stanford.nlp.ling.CoreAnnotations.SentencesAnnotation;
import edu.stanford.nlp.ling.CoreAnnotations.TokensAnnotation;
import edu.stanford.nlp.ling.CoreLabel;
import edu.stanford.nlp.pipeline.Annotation;
import edu.stanford.nlp.pipeline.StanfordCoreNLP;
import edu.stanford.nlp.util.CoreMap;

public class StanfordLemmatizer {

    protected StanfordCoreNLP pipeline;

    public StanfordLemmatizer() {
        // Create StanfordCoreNLP object properties, with POS tagging
        // (required for lemmatization), and lemmatization
        Properties props;
        props = new Properties();
        props.put("annotators", "tokenize, ssplit, pos, lemma");

        /*
         * This is a pipeline that takes in a string and returns various analyzed linguistic forms. 
         * The String is tokenized via a tokenizer (such as PTBTokenizerAnnotator), 
         * and then other sequence model style annotation can be used to add things like lemmas, 
         * POS tags, and named entities. These are returned as a list of CoreLabels. 
         * Other analysis components build and store parse trees, dependency graphs, etc. 
         * 
         * This class is designed to apply multiple Annotators to an Annotation. 
         * The idea is that you first build up the pipeline by adding Annotators, 
         * and then you take the objects you wish to annotate and pass them in and 
         * get in return a fully annotated object.
         * 
         *  StanfordCoreNLP loads a lot of models, so you probably
         *  only want to do this once per execution
         */
        this.pipeline = new StanfordCoreNLP(props);
    }

    public List<String> lemmatize(String documentText)
    {
        List<String> lemmas = new LinkedList<String>();
        // Create an empty Annotation just with the given text
        Annotation document = new Annotation(documentText);
        // run all Annotators on this text
        this.pipeline.annotate(document);
        // Iterate over all of the sentences found
        List<CoreMap> sentences = document.get(SentencesAnnotation.class);
        for(CoreMap sentence: sentences) {
            // Iterate over all tokens in a sentence
            for (CoreLabel token: sentence.get(TokensAnnotation.class)) {
                // Retrieve and add the lemma for each word into the
                // list of lemmas
                lemmas.add(token.get(LemmaAnnotation.class));
            }
        }
        return lemmas;
    }


    public static void main(String[] args) {
        System.out.println("Starting Stanford Lemmatizer");
        String text = "How could you be seeing into my eyes like open doors? \n"+
                "You led me down into my core where I've became so numb \n"+
                "Without a soul my spirit's sleeping somewhere cold \n"+
                "Until you find it there and led it back home \n"+
                "You woke me up inside \n"+
                "Called my name and saved me from the dark \n"+
                "You have bidden my blood and it ran \n"+
                "Before I would become undone \n"+
                "You saved me from the nothing I've almost become \n"+
                "You were bringing me to life \n"+
                "Now that I knew what I'm without \n"+
                "You can've just left me \n"+
                "You breathed into me and made me real \n"+
                "Frozen inside without your touch \n"+
                "Without your love, darling \n"+
                "Only you are the life among the dead \n"+
                "I've been living a lie, there's nothing inside \n"+
                "You were bringing me to life.";
        StanfordLemmatizer slem = new StanfordLemmatizer();
        System.out.println(slem.lemmatize(text));
    }

}

Вот мои результаты (я был очень впечатлен; он поймал "как" (иногда) и сделал почти все остальное отлично):

Начиная Стэнфордский лемматизатор

Добавление аннотатора токена

Добавление аннотатора сплит

Добавление аннотатора поз

Чтение модели POS-тегера из edu / stanford / nlp / models / pos-tagger /english-left3words /english-left3words-distsim.tagger... сделано [1,7 сек].

Добавление аннотатора леммы

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

Вы можете попробовать бесплатный API Lemmatizer здесь: http://twinword.com/lemmatizer.php

Прокрутите вниз, чтобы найти конечную точку лемматизатора.

Это позволит вам получить "собаки" для "собаки", "способности" для "способности".

Если вы передадите параметр POST или GET, называемый "text", со строкой, такой как "walked заводы":

// These code snippets use an open-source library. http://unirest.io/java
HttpResponse<JsonNode> response = Unirest.post("[ENDPOINT URL]")
.header("X-Mashape-Key", "[API KEY]")
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Accept", "application/json")
.field("text", "walked plants")
.asJson();

Вы получите ответ, подобный этому:

{
  "lemma": {
    "plant": 1,
    "walk": 1
  },
  "result_code": "200",
  "result_msg": "Success"
}

Существует JNI для hunspell, который является средством проверки, используемым в открытом офисе и FireFox. http://hunspell.sourceforge.net/

Проверьте Lucene Snowball.

Другие вопросы по тегам