영어문장에서 단어를 찾아내는 솔루션이 필요하여 알아보니 아파치재단에 openNLP라는것이 있다는것을 알게 되었다. 혹시 참고 될 사람이 있을까 싶어서 openNLP사용법을 간단히 적어본다.
홈페이지 : https://opennlp.apache.org/
아파치 설명서 : https://opennlp.apache.org/documentation/1.7.0/manual/opennlp.html
참고한곳 (영어) : http://www.programcreek.com/2012/05/opennlp-tutorial/
관련 라이브러리는 Maven으로 설치하였다. 현재기준으로 1.7이 최신버전이다.
pom.xml에 아래와 같이 적어주면 된다.
<dependency>
<groupId>org.apache.opennlp</groupId>
<artifactId>opennlp-tools</artifactId>
<version>1.7.0</version>
</dependency>
openNLP는 영어뿐만 아니라 스페인어등 다른 언어도 지원하기 때문에 각 언어별로 단어를 추출하는 로직이 다르므로 각 언어별로 필요한 모델을 다운받아서 사용한다. 모델에는 문장 추출, token(단어, 구둣점등) 추출, 고유명사 추출, POS태깅등이 각각 따로 존재한다.)
openNLP 1.7은 model 1.5를 사용하면 된다.
다운받는 경로 : http://opennlp.sourceforge.net/models-1.5/
다운 받은 모델을 프로젝트의 리소스에 추가해준다.(아래는 필자의 경로입다.)
String strOri = "Hi. How're you? This is Mike.";
System.out.println("\nSentences : " + strOri);
try {
//Resource에 있는 Model 파일을 읽기 위한 설정
ClassLoader loader = Thread.currentThread().getContextClassLoader();
//문장으로 분리하기
InputStream is_sentence = loader.getResourceAsStream("en-sent.bin");
SentenceModel modelSentence = new SentenceModel(is_sentence);
SentenceDetectorME sdetector = new SentenceDetectorME(modelSentence);
String sentences[] = sdetector.sentDetect(strOri);
//POS(Part of Speech)를 찾아내기...
InputStream is_POS = loader.getResourceAsStream("en-pos-maxent.bin");
POSModel modelPOS = new POSModel(is_POS);
POSTaggerME tagger = new POSTaggerME(modelPOS);
//token(단어)으로 분리하기 (How're을 하나의 token로 본다.)
InputStream is_token = loader.getResourceAsStream("en-token.bin");
TokenizerModel modelToekn = new TokenizerModel(is_token);
TokenizerME tokenizer = new TokenizerME(modelToekn);
//고유명사들 찾기...
//사람 이름 찾아내기
InputStream is_NameOfPeople = loader.getResourceAsStream("en-ner-person.bin");
TokenNameFinderModel model_NameOfPeople = new TokenNameFinderModel(is_NameOfPeople);
NameFinderME peopleNameFinder = new NameFinderME(model_NameOfPeople);
//지명 이름 찾아내기
InputStream is_NameOfLocation = loader.getResourceAsStream("en-ner-location.bin");
TokenNameFinderModel model_NameOfLocation = new TokenNameFinderModel(is_NameOfLocation);
NameFinderME locationNameFinder = new NameFinderME(model_NameOfLocation);
//조직 이름 찾아내기
InputStream is_NameOfOrgan = loader.getResourceAsStream("en-ner-organization.bin");
TokenNameFinderModel model_NameOfOrgan= new TokenNameFinderModel(is_NameOfOrgan);
NameFinderME organNameFinder = new NameFinderME(model_NameOfOrgan);
//날짜 찾아내기
InputStream is_NameOfDate = loader.getResourceAsStream("en-ner-date.bin");
TokenNameFinderModel model_NameOfDate= new TokenNameFinderModel(is_NameOfDate);
NameFinderME dateNameFinder = new NameFinderME(model_NameOfDate);
//화폐 이름 찾아내기
InputStream is_NameOfMoney= loader.getResourceAsStream("en-ner-money.bin");
TokenNameFinderModel model_NameOfMoney= new TokenNameFinderModel(is_NameOfMoney);
NameFinderME moneyNameFinder = new NameFinderME(model_NameOfMoney);
//입력문장 전체를 문장으로 나눈다.
System.out.println("count of senctences : " + sentences.length);
for(String sentence : sentences){
System.out.println("sentence : " + sentence);
//각 문장에서 token단위(단어, 구둣점등)로 나눈다.
String[] tokens = tokenizer.tokenize(sentence);
//tokens으로 분리한 토큰들에 대한 POS를 가져온다.
String tag[] = tagger.tag(tokens);
System.out.println("\ncount of tokens : " + tokens.length);
for (int i = 0; i < tokens.length; i++) {
String strWord = tokens[i];
String pos = tag[i];
System.out.println(i + " : " + strWord);//+ " , POS[" + pos + "]");
}
//whitespaceTokens으로 분리한 토큰들에 대한 POS를 가져온다.
String whitespaceTokens[] = WhitespaceTokenizer.INSTANCE.tokenize(sentence);
String tagOfWhitespaceTokens[] = tagger.tag(whitespaceTokens);
System.out.println("\ncount of whitespaceTokens : " + whitespaceTokens.length);
for (int i = 0; i < whitespaceTokens.length; i++) {
String strWord = whitespaceTokens[i];
String pos = tagOfWhitespaceTokens[i];
System.out.println(i + " : " + strWord);//+ " , POS[" + pos + "]");
}
//simpleTokens으로 분리한 토큰들에 대한 POS를 가져온다.
String simpleTokens[] = SimpleTokenizer.INSTANCE.tokenize(sentence);
String tagOfSimpleTokens[] = tagger.tag(simpleTokens);
System.out.println("\ncount of simpleTokens : " + simpleTokens.length);
for (int i = 0; i < simpleTokens.length; i++) {
String strWord = simpleTokens[i];
String pos = tagOfSimpleTokens[i];
System.out.println(i + " : " + strWord);//+ " , POS[" + pos + "]");
}
Span peopleNameSpans[] = peopleNameFinder.find(simpleTokens);
for(Span name: peopleNameSpans) {
logger.info("people Name : " + name.toString());
}
Span locationNameSpans[] = locationNameFinder.find(simpleTokens);
for(Span name: locationNameSpans) {
logger.info("location Name : " + name.toString());
}
Span organNameSpans[] = organNameFinder.find(simpleTokens);
for(Span name: organNameSpans) {
logger.info("organ Name : " + name.toString());
}
Span dateNameSpans[] = dateNameFinder.find(simpleTokens);
for(Span name: dateNameSpans) {
logger.info("date Name : " + name.toString());
}
Span moneyNameSpans[] = moneyNameFinder.find(simpleTokens);
for(Span name: moneyNameSpans) {
logger.info("money Name : " + name.toString());
}
}
is_sentence.close();
is_token.close();
is_NameOfPeople.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
위를 실행하면 나오는 결과는 아래와 같다..
Sentences : Hi. How're you? This is Mike.
count of senctences : 2
sentence : Hi. How're you?
count of tokens : 5
0 : Hi
1 : .
2 : How're
3 : you
4 : ?
count of whitespaceTokens : 3
0 : Hi.
1 : How're
2 : you?
count of simpleTokens : 7
0 : Hi
1 : .
2 : How
3 : '
4 : re
5 : you
6 : ?
sentence : This is Mike.
count of tokens : 4
0 : This
1 : is
2 : Mike
3 : .
count of whitespaceTokens : 3
0 : This
1 : is
2 : Mike.
count of simpleTokens : 4
0 : This
1 : is
2 : Mike
3 : .