【プログラミング&テキスト解析】Go言語でN-gramを返す関数を書いてみた
N-gramを返す関数はPythonなどではすぐに書くこともできるのですが,(というかそういうパッケージも有るでしょうし)自分で色々実装して試してみよう,ということで書いてみた例を紹介します.
ちなみに,Go言語とは,Googleが開発したプログラミング言語で,クロスコンパイルがすごく簡単にできるがゆえにいいなーと思っていた言語でした.つまり,MacでつくったツールをWindowsで実行するようにするのがすごく簡単ということです.
クロスコンパイル参考:Goはクロスコンパイルが簡単 - unknownplace.org
では,N-gramを作成する関数を作ったので,ご参考までに.といっても凄く簡単な書き方ができるので,Pythonとくらべて特別な工夫はほとんど必要ありません.
今回は日本語の解析を目的としているので文字列ベースのN-gramを返す関数です.例えば,"徒然なるままに"のBi-gram(n=2)の場合には,["徒然", "然な", "なる", "るま", "まま", "まに"]という配列を返すのがゴールです.
まずは,Pythonのコードから
#文字からN-gramを作成して返す def ngram(target_string,n): if len(target_string)<n: error_message = "Error: Input string's length is less than n value ({} < {})" print(error_message.format(len(target_string),n)) return False ngrams = filter(lambda b:b!="", [target_string[k:k+n] for k in range(len(target_string)-n+1)]) return list(ngrams)
Pythonで気軽に書けばこのくらいです.基本的な処理は,一行で完結するのでかなりシンプルに記述することが出来ます.
Go言語で書いてみるとこんな感じになります.
package main import ( "fmt" "strings" "errors" ) //実行する func main(){ target_string := "徒然なるままに" bigrams, err := ngram(target_string,2) if err!=nil{ fmt.Println(err) } fmt.Println("Bigrams: ",bigrams) } // N-gramをstringの配列型で返す func ngram(target_text string, n int) ([]string, error) { sep_text := strings.Split(target_text,"") var ngrams []string if len(sep_text) < n{ err := errors.New("Error: Input string's length is less than n value") return nil, err } for i:=0; i<(len(sep_text)-n+1); i++{ ngrams = append(ngrams,strings.Join(sep_text[i:i+n],"")) } return ngrams, nil }
多分,appendのところでメモリを少なく使う処理ができるのと,配列を宣言する際にsliceにするとメモリを節約して実行できるのではないかと思います.Go言語は高速で実行できるので,テキスト解析にはかなり向いている言語かと思います.クロスコンパイルも便利となれば,今後ユーザーも伸びていく言語の一つではないでしょうか.
次はjsonファイルをパースしてスコアリングするところまでやってみたいと思います.
追記,Go言語のコードでエラー処理で動かない点がいくつかあったので訂正しました.2015-01-13-01:47