Javaでの英語の lemmatization 実装を探しています。すでにいくつかは見つかりましたが、実行するのに多くのメモリを必要としないものが必要です(1 GB上)。ありがとう。ステマーは必要ありません。
Stanford CoreNLP Javaライブラリには、リソースを少し消費するlemmatizerが含まれていますが、ラップトップで512MB未満のRAMで実行しました。
それを使用するには:
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;
}
}
Standford Lemmatizerに関するChrisの回答は素晴らしいです。圧倒的に美しい。彼はjarファイルへのポインターも含めたので、グーグルする必要はありませんでした。
しかし、彼のコード行の1つに構文エラーがあり(彼は "lemmas.add ..."で始まる行の最後の閉じ括弧とセミコロンを何らかの方法で切り替えました)、彼はインポートを含めるのを忘れていました。
NoSuchMethodErrorエラーに関する限り、それは通常、そのメソッドがpublic staticになっていないことが原因ですが、コード自体を見ると( 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ファイルを構成しても問題ありませんでした)。
以下は、Chrisのコードのマイナーな修正と例(完全な歌詞を屠殺した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));
}
}
ここに私の結果があります(私は非常に感銘を受けました:「の」を「ある」として(時々)キャッチし、他のほとんどすべてを完全に行いました):
Stanford Lemmatizerの起動
アノテーターのトークナイズを追加する
アノテータースプリットの追加
アノテーターポジションの追加
Edu/stanford/nlp/models/pos-tagger/english-left3words/english-left3words-distsim.taggerからのPOSタガーモデルの読み取り...完了[1.7秒]。
アノテーターレンマの追加
[どのように、できる、あなた、ある、見る、中に、私、目、好き、開く、ドア、?、あなた、リード、私、ダウン、中に、私の、コア、どこに、私、持っている、になる、そう、麻痺、せずに、魂、私の、精神、の、睡眠、どこか、寒い、まで、あなた、見つけて、それ、そこに、そして、リード、それ、戻る、家、あなた、目覚め、私、上、中、呼び出し、私の名前、そして保存、私は、から、暗い、あなた、持っている、入札、私、血、そして、それは、実行する前に、私は、になる、元に戻す、あなた、保存、私、から、何もない、私、持っている、ほとんど、になる、あなた、ある、持ってくる、私、する、人生、今、それ、私、知っている、何、私、ある、なし、あなた、できる、持っている、ただ、去る、私、あなた、呼吸する、私、そして、作る、私、本当の、凍った、内側、なし、あなた、触る、なし、あなた、愛、、、最愛の人、あなただけ、人生、の中で、死んだ、私は、ある、ある、生きている、ある、ある、ある、ある、ある、何もない、内側、あなた、ある、ある、私、ある、ある、人生、]
ここで無料のLemmatizer APIを試すことができます: http://twinword.com/lemmatizer.php
下にスクロールして、Lemmatizerエンドポイントを見つけます。
これにより、「犬」から「犬」、「能力」から「能力」を取得できます。
POSTまたは「ウォークされた植物」のような文字列を含む「テキスト」と呼ばれるGETパラメータを渡す場合:
// 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"
}