2016년 8월 31일 수요일

スクリプト言語のバインディング (Mecab 스크립트언어 바인딩에 대해)

(직접 번역했습니다. 번역이 원문의 의도에서 크게 벗어나지 않을것이라 생각하지만, 혹여 틀린 부분 발견하면 알려주세요. )

スクリプト言語のバインディング

스크립트언어 바인딩

概要

요약

各種スクリプト言語 (perl, ruby, python, Java) から, MeCab が提供する形態素解析の機能を利用可能です. 各バインディングは SWIG というプログラ ムを用いて, 自動生成されています. SWIG がサポートする他の言語も 生成可能だと思われますが, 現在は, 作者の管理できる範囲内ということで, 上記の4つの言語のみを提供しております.
각종 스크립트 언어 (perl, ruby​​, python, Java)에서 MeCab가 제공하는 형태소 분석 기능을 사용할 수 있습니다. 각 바인딩은 SWIG라는 프로그램을 이용하여 자동으로 생성되어 있습니다. SWIG가 지원하는 다른 언어도 생성 가능하다고 생각됩니다만, 현재는 저자의 관리 범위 내의 것으로, 위의 네가지 언어만을 제공하고 있습니다.


インストール

Install

各言語バイディングのインストール方法は, perl/README, ruby/README, python/README, java/README を御覧下さい.
각 언어의 설치 방법은 perl/README, ruby/README, python/README, java/README 를 참조해 주세요.


とりあえず解析する

우선 분석하기

MeCab::Tagger というクラスのインスタンスを生成し, parse (もしくは parseToString) というメソッドを呼ぶことで, 解析結果が文字列として取得できます. MeCab::Tagger のコンストラクタの引数は, 基本的に mecab の実行形式に与え るパラメータと同一で, それらを文字列として与えます.
MeCab::Tagger라는 클래스의 인스턴스를 생성하고 parse (또는 parseToString)라는 메소드를 부르는 것으로, 해석 결과는 문자열로서 얻어질 수 있습니다. MeCab::Tagger의 Constructor 인수는, 기본적으로 mecab의 실행 형식에 미치는 파라미터와 동일하며, 그들을 문자열로서 제공합니다.

perl


1
2
3
use MeCab;
$m = new MeCab::Tagger ("-Ochasen");
print $m->parse ("今日もしないとね");


ruby


1
2
3
require 'MeCab'
m = MeCab::Tagger.new ("-Ochasen")
print m.parse ("今日もしないとね")


python


1
2
3
4
import sys
import MeCab
m = MeCab.Tagger ("-Ochasen")
print m.parse ("今日もしないとね")


Java


1
2
3
4
5
6
import org.chasen.mecab.Tagger;
import org.chasen.mecab.Node
 public static void main(String[] argv) {
 Tagger tagger = new Tagger ("-Ochasen");
 System.out.println (tagger.parse ("太郎は二郎にこの本を渡した.")); 
}



各形態素の詳細情報を取得する

각 형태소의 상세정보 얻기

MeCab::Tagger クラスの, parseToNode という メソッドを呼ぶことで, 「文頭」という特別な形態素が MeCab::Node クラスのインスタンスとして 取得できます.
MeCab::Tagger 클래스의 parseToNode라는 메소드를 부르는 것으로, 「문두」라고하는 특별한 형태소가 MeCab::Node 클래스의 인스턴스로 가져올 수 있습니다.

MeCab::Node は, 双方向リストとして表現されており, next, prev というメン バ変数があります. それぞれ, 次の形態素, 前の形態素を MeCab::Node クラスのインスタンスとして 返します. 全形態素には, next を順次呼ぶことでアクセスできます.
MeCab::Node는 양방향 List로 표현되고 있으며, next, prev라는 구성원 변수가 있습니다. 각각 다음 형태소, 이전 형태소를 MeCab::Node 클래스의 인스턴스로서 돌려줍니다. 전체 형태소는 next를 순차적으로 부르는 것으로 접근할 수 있습니다.

MeCab::Node は C 言語のインタフェイスで提供している mecab_node_t をラッ プしたクラスです. mecab_node_t が持つほぼすべてのメンバ変数にアクセスす ることができます. ただし, surface のみ, 単語そのものが返るように変更して います.
MeCab::Node는 C언어 인터페이스에서 제공하는 mecab_node_t를 랩핑한 클래스입니다. mecab_node_t가 가지는 거의 모든 멤버 변수에 액세스 할 수 있습니다. 하지만, surface만은 단어 자체가 반환시키도록 변경되어 있습니다.

以下に perl の例を示します. この例では, 各形態素を順次にアクセスし,形態素の表層文字列, 品詞, その形態素までのコストを表示します.
다음은 perl의 예를 보여줍니다. 이 예에서는 각 형태소를 순차적으로 방문하여 형태소의 표층 문자열, 품사, 형태소까지의 Cost를 표시합니다.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
use MeCab;
my $m = new MeCab::Tagger ("");

for (my $n = $m->parseToNode ("今日もしないとね"); $n ; $n = $n->{next}) {
   printf ("%s\t%s\t%d\n",
            $n->{surface},          # 表層
     $n->{feature},          # 現在の品詞
     $n->{cost}              # その形態素までのコスト
     );
}



エラー処理

에러처리

もし, コンストラクタや, 解析途中でエラーが起きた場合は, RuntimeError 例外が発生します. 例外のハンドリングの方法は, 各言語のリファレンスマニュアルを ごらんください. 以下は,python の例です
만약 Constructor의 해석 도중에 에러가 발생한 경우는, RuntimeError 예외가 발생합니다. 예외 처리 방법은 각 언어 레퍼런스를 참조하세요. 아래는 python의 예입니다.



1
2
3
4
5
try:
    m = MeCab.Tagger ("-d .")
    print m.parse ("今日もしないとね")
except RuntimeError, e:
    print "RuntimeError:", e;



注意事項

주의사항

文頭,文末形態素

문두(글머리), 문미(글마침) 형태소

parseToNode の返り値は, 「文頭」という特別な形態素を示す MeCab::Node インタンスです. さらに, 「文末」という特別な形態素も存在いたしますので, 注意してください. もし, これらを無視したい場合は, 以下のように next でそれぞれを読み飛ばしてください.
parseToNode의 반환 값은 "문두"라고 하는 특별한 형태소를 나타냅니다. MeCab::Node 인스턴스 입니다. 또한, "문미"라는 특별한 형태소도 존재하므로주의하세요. 만약 이를 무시하려면, 다음과 같이 next 각각을 읽어 날려주세요.


1
2
3
4
5
6
7
my $n = $m->parseToNode ("今日もしないとね"); 
$n = $n->{next}; # 「文頭」を無視

while ($n->{next}) { # next を調べる
  printf ("%s\n", $n->{surface});
  $n = $n->{next}; # 次に移動
}



MeCab::Node の振舞い

Mecab::Node의 동작

MeCab::Node の実体(メモリ上にある形態素情報)は, MeCab::Tagger インスタンスが管理しています. MeCab::Node は, Node の実体を指している参照にすぎせん. そのために, parseToNode が 呼ばれる度に, 実体そのものが, 上書きされていきます. 以下のような例はソースの意図する通りには動きません.
MeCab::Node의 실체 (메모리에 있는 형태소 정보)는 MeCab::Tagger 인스턴스가 관리하고 있습니다. MeCab::Node는 Node의 실체를 가리키는 참조용에 지나
지 않습니다. 이를 위해, parseToNode가 불릴 때마다 실체 그 자체가 Over Writing 됩니다. 다음과 같은 예는 의도대로는 움직이지 않습니다.


1
2
3
4
5
6
7
8
m = MeCab.Tagger ("")
n1 = m.parseToNode ("今日もしないとね") 
n2 = m.parseToNode ("さくさくさくら")

# n1 の内容は無効になっている
while (n1.hasNode () != 0):
   print n1.getSurface ()
   n1 = n1.next ()



上記の例では, n1 の指す中身が, 「さくさくさくら」を解析した時点で 上書きされており, 使用できなくなっています.
위의 예에서는 n1 가리키는 내용(今日もしないとね)이 "さくさくさくら'를 분석 한 시점에서 Over write 되어져 사용할 수 없게 됩니다.

複数の Node を同時にアクセスしたい場合は, 複数の MeCab::Tagger インスタンスを生成してください.
여러 Node를 동시에 액세스하려면 여러 MeCab::Tagger 인스턴스를 생성해 주세요.



全メソッド

전체 메소드

以下に, SWIG用のインタフェースファイル の一部を示します. バイディングの実装言語の都合上, C++ のシンタックスで 表記されていますが, 適宜読みかえてください. また, 各メソッドの動作も添え ていますので参考にしてください.
아래의 예는 SWIG용 인터페이스 파일의 일부를 보여줍니다. 바인딩 언어 사정상, C ++ 구문으로 표기되어 있습니다만, 상황에 따라 적당히 변경하세요. 또한 각 메소드의 동작도 함께 제공되니 참고하십시오.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
namespace MeCab {

  class Tagger {

     // str を解析して文字列として結果を得ます. len は str の長さ(省略可能)
     string parse(string str, int len);
  
     // parse と同じ
     string parseToString(string str, int len);
  
     // str を解析して MeCab::Node 型の形態素を返します. 
     // この形態素は文頭を示すもので, next を順に辿ることで全形態素にアクセスできます
     Node parseToNode(string str, int len);
  
     // parse の Nbest 版です. N に nbest の個数を指定します.
     // この機能を使う場合は, 起動時オプションとして -l 1 を指定する必要があります
     string parseNBest(int N, string str, int len);
  
     // 解析結果を, 確からしいものから順番に取得する場合にこの関数で初期化を行います.
     bool  parseNBestInit(string str, int len);
  
     // parseNbestInit() の後, この関数を順次呼ぶことで, 確からしい解析結果を, 順番に取得できます.
     string next();
  
     // next() と同じですが, MeCab::Node を返します.
     Node  nextNode();
  };
  
  #define MECAB_NOR_NODE  0
  #define MECAB_UNK_NODE  1
  #define MECAB_BOS_NODE  2
  #define MECAB_EOS_NODE  3
  
  struct Node {

    struct Node  prev;  // 一つ前の形態素へのポインタ
    struct Node  next;  // 一つ先の形態素へのポインタ
    
    struct Node  enext; // 同じ位置で終わる形態素へのポインタ
    struct Node  bnext; // 同じ開始位置で始まる形態素へのポインタ
  
    string surface;             // 形態素の文字列情報 
           
    string feature;             // CSV で表記された素性情報
    unsigned int   length;      // 形態素の長さ
    unsigned int   rlength;     // 形態素の長さ(先頭のスペースを含む)
    unsigned int   id;          // 形態素に付与される ユニークID
    unsigned short rcAttr;      // 右文脈 id 
    unsigned short lcAttr;      // 左文脈 id
    unsigned short posid;       // 形態素 ID (未使用)
    unsigned char  char_type;   // 文字種情報
    unsigned char  stat;        // 形態素の種類: 以下のマクロの値
                                // #define MECAB_NOR_NODE  0
                                // #define MECAB_UNK_NODE  1
                                // #define MECAB_BOS_NODE  2
                                // #define MECAB_EOS_NODE  3
    unsigned char  isbest;      // ベスト解の場合 1, それ以外 0
  
    float          alpha;       // forward backward の foward log 確率
    float          beta;        // forward backward の backward log 確率 
    float          prob;        // 周辺確率
                                // alpha, beta, prob は -l 2 オプションを指定した時に定義されます
  
    short          wcost;       // 単語生起コスト
    long           cost;        // 累積コスト
  };
}


サンプルプログラム

Sample program

perl/test.pl, ruby/test.rb, python/test.py, java/test.java にそれぞれの言語のサンプルがありますので, 参考にしてください.
perl / test.pl, ruby​​ / test.rb, python / test.py, java / test.java에 각 언어의 예제가 있으므로 참고하세요.





댓글 없음:

댓글 쓰기