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에 각 언어의 예제가 있으므로 참고하세요.





MeCabをPython3から使う(続報)


MeCabをPython3から使う(続報)
(DEC 20TH, 2015 1:03 AM)
Mecab를 Python3에서 사용 (이어지는 소식/게시물)
(2015-12-20 01:03) - //글쓴이가 야행성임을 알 수 있다.

Python3からMeCabを扱おうとして挫折していたのですが (MeCabをPython3から使う(中間報告))、 改めて調査して、上手くいかなかった原因が分かったのでご報告します。
이전 글에서 Python3에서 Mecab을 다뤄보려고 하다가 좌절했었지만, (관련게시글: Mecab을 Python3에서 사용 (중간 보고)), 하다보니 문제의 원인을 찾아냈기에 알려드립니다. //의역


おさらい

당시상황

Python3で以下のようにMeCabを使おうとすると
Python3에서 아래처럼 Mecab를 사용하려 하면,


1
2
3
4
5
6
7
import MeCab
tagger = MeCab.Tagger('')
text = u'MeCabで遊んでみよう!'
node = tagger.parseToNode(text)
while node:
    print(node.surface + '\t' + node.feature)
    node = node.next




surfaceが全く読み取れないという現象に遭遇していました。
surface를 전혀 읽지 못하는 현상이 발생하고 있었습니다.


1
2
3
4
5
6
7
8
9
BOS/EOS,*,*,*,*,*,*,*,*
名詞,一般,*,*,*,*,*
助詞,格助詞,一般,*,*,*,で,デ,デ
動詞,自立,*,*,五段・バ行,連用タ接続,遊ぶ,アソン,アソン
助詞,接続助詞,*,*,*,*,で,デ,デ
Traceback (most recent call last):
  File "m.py", line 10, in <module>
  print( node.surface + '\t' + node.feature )
  UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa3 in position 1: invalid start byte



解決策

해결책


詳しい原因なんてどうでもいいからMeCabを使いたい人向けに、最初に解決方法を書いておきます。 以下のように本当に解析したい対象を解析する前に、一度parseをしておけばOKです。
자세한 원인은 아무래도 상관 없으니까, Mecab을 사용하고 싶은 사람을 위한 첫 번째 해결 방법을 기록해 둡니다. 아래과 같이 정말 분석하고 싶은 대상을 분석하기 전에 한 번 parse을 해두면 OK입니다. //즉, tagger.parse('') 이 부분을 공(空)으로 한줄 넣어주면 된다는 의미.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import MeCab
tagger = MeCab.Tagger('')

tagger.parse('') # これ重要!!!!

text = u'MeCabで遊んでみよう!'
node = tagger.parseToNode(text)
while node:
    print(node.surface + '\t' + node.feature)
    node = node.next



解析結果を全く使わずに捨てていて無駄のように思えますが、この一行が重要です! これを入れると以下のように正常に解析ができます。
분석결과를 전혀 사용치 않고 버리는 낭비처럼 생각되지만, 이 한줄이 중요합니다! 이것을 넣으면 아래과 같이 올바르게 해석 할 수 있습니다.


1
2
3
4
5
6
7
8
9
    BOS/EOS,*,*,*,*,*,*,*,*
MeCab   名詞,一般,*,*,*,*,*
      助詞,格助詞,一般,*,*,*,で,デ,デ
遊ん    動詞,自立,*,*,五段・バ行,連用タ接続,遊ぶ,アソン,アソン
      助詞,接続助詞,*,*,*,*,で,デ,デ
みよ    動詞,非自立,*,*,一段,未然ウ接続,みる,ミヨ,ミヨ
      助動詞,*,*,*,不変化型,基本形,う,ウ,ウ
!       名詞,サ変接続,*,*,*,*,*
    BOS/EOS,*,*,*,*,*,*,*,*



解析を行うメソッドであればparseToNodeでも構いません。
분석을 실행하는 메소드라면, parseToNode라도 상관 없습니다.



原因

원인


結果が壊れる直接的な原因はMeCabをPythonから使う注意点とかで紹介したように、 解析対象の文字列がPythonの管理下から外れGCされてしまったからです。 高速化のために余計なメモリーアロケーションを避けており、メモリ管理は利用者の責任というわけです。
결과가 잘못 나오는 직접적 원인은 "관련게시글: Mecab를 Python에서 사용 주의점 등"에서 소개 한 바와 같이, 분석 대상 문자열이 Python의 관리에서 벗어나 GC되어 버렸기 때문입니다. 고속화를 위해 불필요한 Memory allocation을 피하고 있으며 (이러한) 메모리 관리는 이용자의 책임이라는 것입니다.

なんとかならないものかと、よくソースコードを追ってみるとMECAB_ALLOCATE_SENTENCEというフラグをONにすれば メモリ管理をMeCabに任せることができるということがわかりました。 これはTaggerを作るときの引数から指定でき、-Cもしくは--allocate-sentenceというオプションがこのフラグに対応します。 これを有効にすれば解決だ!と思ったのですが、実は各種言語バインディングからMeCabを利用する場合はデフォルトで有効になっています
어떻게 든 방법이 없을까 면밀히 소스코드를 쫓아 보니 MECAB_ALLOCATE_SENTENCE 플래그를 ON으로하면 메모리 관리를 MeCab에 맡길 수 있다는 것을 알 수 있었습니다. 이것은 Tagger를 만들 때 인수에서 지정할 수 있으며 -C 또는 --allocate-sentence라는 옵션이 플래그를 지원합니다. 이걸 활성화하면 해결이다! 라고 생각했는데, 실은 각종 언어 바인딩에서 MeCab를 이용하는 경우는 기본적으로 활성화되어 있습니다.

何故だ・・・とさらにコードを追ってみるとparseToNodeの実装が以下のようになっていることがわかりました。
왜지? 그러면서 더 코드를 쫓아 보면, parseToNode의 구현은 다음과 같이 되어있는 것을 알 수 있었습니다.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const Node *TaggerImpl::parseToNode(const char *str, size_t len) {
  Lattice *lattice = mutable_lattice();
  lattice->set_sentence(str, len); // このなかでMECAB_ALLOCATE_SENTENCEフラグが立ってるか確認している
  initRequestType();               // このなかでMECAB_ALLOCATE_SENTENCEフラグを立ててる
  if (!parse(lattice)) {
    set_what(lattice->what());
    return 0;
  }
  return lattice->bos_node();
}



MECAB_ALLOCATE_SENTENCEフラグを立てる前に、立っているかを確認しています。

MECAB_ALLOCATE_SENTENCE 플래그 앞에 (정의되어) 있는지 확인해보았습니다.

解析対象の文字列を渡す前にinitRequestType()を呼んでMECAB_ALLOCATE_SENTENCEフラグを立てれば良いのですが、 残念ながらinitRequestType()もmutable_lattice()もprivateなメソッドなのでPythonから直接呼ぶことはできません。 そこでparse()を使ってinitRequestType()を間接的に呼び出せば問題解決というわけです。
분석 대상의 문자열을 전달받기 전에 initRequestType()를 불러 MECAB_ALLOCATE_SENTENCE 플래그를 (정의해) 주면 되겠다 싶지만, 불행히도 initRequestType()도 mutable_lattice()도 private 메서드이기에 Python에서 직접 부를 수 없습니다. 그래서 parse()를 사용하여 initRequestType()를 간접적으로 호출하면 문제 해결이라는 것입니다. //글쓴이의 잔머리에 탄복한다.ㅋ




別解

다른 해결안


mutable_lattice()は触れなくても、自分で作ったlatticeなら自由にいじれるので、 以下のようにlatticeをPython側で作るのも手ですね。
mutable_lattice()를 굳이 건드리지 않는대도, 스스로 만든 lattice이라면 자유롭게 유지됩니다. 아래과 같이 lattice을 Python측에서 만드는 방법도 있습니다만 손이 많이가네요.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
lattice = MeCab.Lattice()
import MeCab
tagger = MeCab.Tagger('')
lattice = MeCab.Lattice()
text = u'MeCabで遊んでみよう!'
lattice.set_sentence(text)
tagger.parse(lattice)
node = lattice.bos_node()
while node:
    print(node.surface+"\t"+node.feature)
    node = node.next



いずれの方法でもnodeからlatticeやtaggerへの参照がない(実際はあるけどPythonはそのことを知らない)ので、 解析結果を読んでいる最中にlatticeやtaggerがGCで回収されないよう注意しましょう。
어떤 방법으로도 node에서 lattice과 tagger에 대한 참조가 없기 때문에 (사실 있지만 Python은 모르는), 분석 결과를 읽는 동안 lattice과 tagger가 GC에서 회수되지 않도록 주의하여야 합니다.



追記(2015-12-20)

덧붙임1


MeCab自体の問題っぽいので、MeCabにpullreq送って直してもらおうとソースいじってたけど、すでにpatchあったpatchを取り込んだブランチを用意したので、 GCされて困っている方はgit cloneしてお試し下さい。
Mecab의 문제 같아보여서, Mecab에 pullreq를 보내 알리려 소스를 확인하고 했지만, 이 문제는 이미 patch되어 있었습니다. patch를 끌어들은 브런치를 준비했기 때문에 GC로 낭패를 보시고 계신 분은 git clone에서 직접 가져다가 써보세요.


追記その2(2016-02-08)

덧붙임2


なんとか取り込んでもらおうとPull Requestにしてマージしてもらいました。 まだリリースはされていませんが、2016-02-08現在のmasterブランチをビルドすれば、ガーベージコレクションの問題はなくなるはずです。 Twitterで作者に聞いてくれた人がいたみたいで、僕のpulllreq以外もたくさんマージされたようです。 よかったよかった。リリースを心待ちにしています。 (が、Python3対応のpullreqはマージされていない・・・一応試してみてから+1しておこうかな)

어떻게든 넣어보려고 Pull Request하고 병합해 봤습니다. 아직 출시되지 않지만 2016-02-08 현재의 master 브랜치를 빌드하면 가비지 컬렉션의 문제는 없게 될 것입니다. Twitter에서 저작자에게 물어봐주었다는 사람이 있다는 듯 해서, 내 pulllreq 이외도 많이 병합 된 것 같습니다. (요갓따ㅋ 요갓따ㅋ). 릴리즈를 손꼽 아 기다리고 있습니다. (하지만, Python3 지원 pullreq는 병합되지 않은;; 일단 시도했다는데에 +1 해둘까나?)






2016년 8월 9일 화요일

python-rake를 이용한 RVM TEST

python-rake를 이용해 LDA(Latent Dirichlet allocation)를 구현해보려 시도했다.
(at python 3.5)

(참고사이트)
https://www.airpair.com/nlp/keyword-extraction-tutorial

먼저 튜토리얼을 다운로드하고,
 $ git clone https://github.com/zelandiya/RAKE-tutorial 

python-rake 인스톨도 했다.
 $ pip3 install python-rake 

다음과 같은 소스를 실행했다. (쵸~단순;;)

import rake
import operator
rake_object = rake.Rake("SmartStoplist.txt", 3, 3, 1)
text = "RIO DE JANEIRO — Japan returned to the top of the men’s gymnastics world, beating Russia and China in the team event at the Olympics. The event was a renewal of the longtime gymnastics rivalry between Japan and China. China won the last two gold medals, in 2008 and 2012. But Japan has Kohei Uchimura, the world’s best gymnast — and perhaps the best ever — anchoring their team. In the final rotation, Japan took on Russia head-to-head in the floor exercise, holding a slim 0.208 lead. Japan went first. After an outstanding score from Kenzo Shirai and a good one from Ryohei Kato, Uchimura locked down the win with a 15.6. Combined, it was the best team floor exercise score of the night. It was the end of a dominant night for Uchimura, who started strong with a 15.100 on the pommel horse, below. Russia could not match those scores and had to settle for second. China won the bronze. Russia had been the early leader after strong horse and rings performances, including a 15.7 by Denis Abliazin on rings. Japan rallied on the vault and parallel bars and took the lead on the high bar. Abliazin, below, and the Russians came up short on the floor routine later in the night, allowing Japan to seal the victory. Russia met with some jeers from the crowd, as it has at other events in the aftermath of reports of state-sponsored doping. China was making early mistakes. You Hao stumbled on his rings landing. More stumbles followed on the vault, normally a chance to pick up high scores. A big parallel bars, including a stellar one by You, thrust China back into medal contention. The Americans got off to a slow start on their first apparatus, floor exercise, when two of their three gymnasts, Alexander Naddour, below, and Sam Mikulak, tumbled out of bounds. Next up was the horse, where Danell Leyva slipped on the dismount, leading to another low score and seriously denting United States medal hopes. Better performances followed, but Leyva fell on the high bar, and the team could finish no better than fifth."
keywords = rake_object.run(text)
print ("keywords: ", keywords)


아, rake_object = rake.Rake("SmartStoplist.txt", 3, 3, 1) 에서 

SmartStoplist.txt 에는 각종 영어단어가 A~Z까지 순차적으로 기록되어 있었다.
(한글도 같은 방법으로 넣으면 될 듯? 항상 뭐든 영어기준으로 개발되는게 참 안타깝다;)

3, 3, 1 은 다음과 같은 의미를 지닌다.
  1. 각 단어는 최소 3문자
  2. 각 구절은 최대 3단어
  3. 각 키워드는 텍스트에 최소 1회 노출

결과는 나름 훌륭했다.
무엇보다 빠른 분석속도가 놀라웠다.


(기사주소)
http://www.nytimes.com/2016/08/09/sports/olympics/gymnastics-japan-team-results.html?hp&action=click&pgtype=Homepage&clickSource=story-heading&module=photo-spot-region&region=top-news&WT.nav=top-news

(결과내용)
making early mistakes: 85%
Danell Leyva slipped: 85%
longtime gymnastics rivalry: 85%
big parallel bars: 80%
thrust China back: 76%
(그외)..

(물론 테스트는 더 많은 기사로서 테스트를 했다. 테스트하다 엄청 졸았다;;;;)

목적과는 부합하지 않아 당장 써먹지는 못하겠지만, 언젠가 문장 분석에 요긴할 듯 하다.




2016년 8월 4일 목요일

성주 주민의 마음을 울린 표창원의 연설 - 한겨레

성주 주민의 마음을 울린 표창원의 연설 (한겨레)


입력 16.08.04. 13:26 (수정 16.08.04. 14:06)
[한겨레]3일 더민주 의원들과 함께 촛불집회 참석해
‘프랜시스 스테이트호 좌초 사건’사드 배치와 비유해 이야기
페이스북에 성주 군민 응원글도 남겨…주민들 “가슴뭉클하다”



지난 3일 더불어민주당 동료 의원들과 함께 사드(THAAD·고고도미사일방어) 체계가 배치되는 경북 성주를 찾은 표창원(50) 의원이 ‘감동적인 연설’로 주민들에게 큰 호응을 받았다.

표 의원은 이날 저녁 7시30분부터 성주군청 앞마당에서 열린 촛불집회에 참석했다. 그는 마이크를 잡고 1835년 ‘프랜시스 스테이트호 좌초 사건’을 사드 배치와 비유하며 사드 배치에 맞서 싸우고 있는 주민들을 응원했다(아래 전문 참조).

서울로 올라가는 길에는 페이스북에 이런 글을 남겼다. “성주 군민 여러분 힘 내세요. 저희도 최선 다하겠습니다. 미처 못 드린 말씀, 사드 문제 해결되면 다시 새누리 텃밭으로 돌아가셔도 괜찮습니다. 다만 늘 어딘가엔 지금의 성주 같은 억울한 소수 피해자들이 있다는 것만 기억해주세요. 고맙습니다. ”

성주 주민들이 모인 카카오톡 그룹 채팅방에는“표창원님 글이 가슴뭉클하게 하네요 감사합니다. 힘이 됩니다”, “오늘 표창원님 애쓰시는 모습 너무나 감사합니다”, “표창원님 페이스북이에요 감동 ㅜㅜ” 등과 같은 글이 올라왔다.

성주/글·영상 김일우 기자 cooly@hani.co.kr



<표창원 의원, 촛불집회에서 한 프랜시스 스테이트호 좌초 사건 이야기>


표창원: 표창원입니다. 짧은 이야기 하나 해드릴게요. 혹시 여러분 프랜시스 스테이트라는 배 이름 아십니까?

주민들: 아니오.…

표창원: 모르시죠. 1835년 11월 캐나다 앞바다에서 좌초한 배 이름입니다. 이 배의 이름이 중요한 이유는요, 이 배가 좌초해서 18명의 선원이 살아남습니다. 그리고 음식도 없이 13일을 버텨요. 굶어 죽을 지경이죠. 구조선은 오지 않습니다. 그때 선장이 이야기합니다. “우리 이대로 죽을 순 없어. 우리가 살 수 있는 방법이 있다”. “그게 뭡니까?”. 선원들이 묻죠. 그때 선장이 이야기합니다. “우리 중에 누군가 한 명만 희생하면 그 사람의 고기를 먹고 17명이 살아남을 수 있어”. 여러분 선장의 말에 동의하시겠습니까?

주민들: 아니오.

표창원: 다들 동의하지 않았습니다. 그런데 그때 갑판장이 앞으로 나섭니다. “가만히 생각해보니 선장 말이 맞는 것 같아. 우리가 이대로 다 죽을 수는 없잖아. 대를 위해 소는 희생을 해야지. 한 명만, 우리 모두 공평한 기회만 주어진다면 나라도 희생하겠어”. 옆에 있던 기관장이 나섭니다. “내 생각도 그래”. 또 옆에 있던 요리장이 나섭니다. “내 생각도 그래”. 선원들이 웅성거립니다. 선장이 다시 이야기하죠. “나도 이 이야기 하기 싫었어. 너무 괴로워. 하지만 어쩔수 없잖아. 우리 다 죽을까? 모두가 기회만 공평하다면 우리 모두 동참하는 게 맞겠지”. 고개를 끄덕입니다. 결국 선장이 준비한 제비뽑기가 이뤄집니다. 18개의 막대기 그중에 하나만 아래에 빗금이 처져 있습니다. 그것을 뽑으면 그 사람이 희생하는 것입니다. 누가 그 막대기를 뽑았을까요?

주민들: 선장.

표창원: 제안한 선장 아닙니다. 동의한 기관장, 갑판장 아닙니다. 그 배에서 가장 나이가 어린 15살의 수습선원이 그 막대기를 뽑았습니다. 그리고는 순간 충격을 받은 얼굴이었다가 곧 미소를 짓습니다. “잘됐습니다. 가장 어리고 약하고 경험 없는 제가 여러 선배 선원님들을 위해 희생할 수 있는 기회를 주셔서 감사합니다. 어차피 저는 죽을 사람이었는데요. 가장 약하고….” 결국 17명이 그 소년의 피와 살을 먹고 버팁니다. 3일 후 지나가던 다른 어선이 이들을 구조해줍니다. 그리고 재판이 열리죠. 이들의 행위는 과연 살인행위일까요, 정당방위일까요? 하지만 그 당시 법정은 유죄, 무죄를 반복하다가 결국 최종심에서 정당방위 무죄를 판결합니다. 여기서 끝이 아닙니다. 판결이 이뤄진 다음에 그중에 한 명이 술에 취해 이야기하고 말죠. “사실 그 제비뽑기는 공정한 게 아니었다고”. 저는 이 이야기에서 사드와 성주를 떠올립니다. 성주가 15살 선원 같은 느낌이 듭니다.

주민들: (박수) 맞어.

표창원: 첫째 과연 당시 프랜시스 스테이트 호에서 꼭 한 명이 희생했어야 했을까요?

주민들: 아니오.

표창원: 3일만 더 버텼으면 다 살아나는 것 아니었습니까? 그쵸?

주민들: 예.

표창원: 대한민국에 사드가 반드시 필요합니까?

주민들: 아니오.

표창원: 필요합니까?

주민들: 아니오.

표창원: 저도 아니라고 생각합니다. 그런데 누군가는 필요하다고 이야기하고 있습니다. 그리고 성주가 그 지역이 되어야만 합니까?

주민들: 아니오.

표창원: 그 절차가 공정했습니까?

주민들: 아니오.

표창원: 한 말씀만 더 드리겠습니다. 하지만 성주와 사드는 이번이 처음이 아닙니다. 이미 강정에서, 밀양에서, 세월호에서, 여러분은 사드가 들어오기 전에 과연 그분들 편에 서주셨습니까?

주민들: 아니오.

표창원: 지금 다른 국민들이 여러분 편에서 계십니까?

주민들: 아니오.

표창원: 대한민국이 슬픈 프랜시스 스테이트 호 같다는 생각이 드는 건 저 뿐입니까?

주민들: 아니오.

표창원: 그래서 여러분들이 존경스럽습니다. 성주가 아니면 된다가 아니라, 대한민국에 사드는 아니다. 공부하시고 따져보시고 사드가 우리 안보에 도움이 되지 않는다, 북핵을 막지 못한다, 우리나라에 오히려 전쟁의 위협을 고조시킨다, 중국과 러시아가 북한편에 서게 만든다, 북한이 핵을 개발할 명분을 준다, 대한민국은 경제와 외교의 위기에 내몰린다, 제 말이 맞습니까?

주민들: 예

표창원: 최선을 다해 노력하겠습니다. 고맙습니다.


출처: 다음뉴스



2016년 8월 2일 화요일

VPN Gate: 사이트 우회 방법

출처: http://www.vpngate.net/en/download.aspx

사이트를 우회하는 방법은 많이 있다. 보통 정부의 방화벽을 우회 할 때 많이 쓰는 방법이지만, 많은 VPN 우회, 로컬 프록시 우회 프로그램과는 다르게 VPN Gate은 조금 독특하다. VPN Gate는 단순 인터넷만 우회하는 프로그램과는 다르게 인터넷망 자체를 우회시키는 기능을 가지고 있다. 그렇기에 VPN Gate를 실행 후 PC를 이용한다면 인터넷 속도 뿐만 아니라 게임, 다운로드 또한 우회한 상태로 PC에서 실행된다.

이러한 우회의 장점은 사이트가 아닌 게임, P2P, 토렌트 등 막아놓은 학교나 공공도서관의 방화벽을 회선 전체 우회를 통해 사용이 가능해지며 국내에서 막힌 게임 해외 서버도 연결이 가능하며 결제 또한 해외 통화 결제가 가능하게 된다. 또한 VPN Gate는 모바일에서도 사용이 가능한 어플을 제공하여 이 방법을 통해 일본 구글 스토어에 접속하는 방법 등으로도 사용이 가능하다.



1단계: VPN Gate 사이트 접속하기

VPN GATE는 일본 츠쿠바 대학의 대학원 학술 실험 프로젝트의 일환으로 제공하는 온라인 서비스를 제공하여 공식 사이트에서 다운로드가 가능하다.

VPN GATE 공식 배포 링크 바로가기



2단계: VPN Gate 다운로드 및 압축 해제하기

Download SoftEther VPN Client + VPN Gate Client Plugin을 다운로드하고 압축을 해제한다.





3단계 : VPNGate 설치하기

압축 해제 후 파일 중 vpngate-client—-.exe 파일을 실행하여 설치한다. 설치 중간에 광고 등 타 프로그램 설치 권유는 포함되어 있지 않아 다음(N) 버튼만 누르면 쉽게 설치가 가능하다. 혹은 중간에 윈도우 보안 동의에 체크해야 할 수도 있다. 설치가 완료되면 윈도우 바탕화면 – SoftEther VPN Client Manager 바로가기를 실행한다.




4단계: 공개 VPN 서버 목록 보기

VPN Gate를 실행 후 VPN Gate Public VPN Relay Server를 클릭하면 연결이 가능한 VPN 서버 목록이 나온다.



5단계: VPN 서버 연결하기

우회할 국가(REGION)를 보고 선택하여 접속하면 해당 접속 국가로 우회를 시도하게 된다. 서버마다 속도는 제각각이며 연결이 실패한다면 다른 서버로 연결을 시도하자.





6단계: VPN 프로토콜 선택하기

Use TCP Protocol 체크한다. TCP를 사용해서 접속이 안되면, 방화벽을 통과하기 쉬운 UDP로 접속하라는 선택 표시이다.







7단계: VPN 연결 확인하기

VPN Gate 화면에 Connected가 뜨면 되면 VPN 우회가 완료된다.



TIP: 접속되지 않는 서버는 Connected Error이 뜨며 다른 서버를 통해 재시도를 해보자. 간혹 환영 메세지가 뜨는 서버도 있으니 OK를 누르자.



8단계: VPN Gate 우회 종료하기

우회의 사용이 끝났으면 우회를 종료시켜야 본래의 IP주소, 본래의 인터넷 속도로 PC를 사용이 가능해진다. VPN 이후 생긴 VPN Gate Connection에서 오른쪽 마우스 클릭 – Disconnect 클릭하면 우회 해제가 완료된다.