機械語と数学とことば

更新が進みません.

【プログラミング&テキスト解析】Go言語でN-gramを返す関数を書いてみた

N-gramを返す関数はPythonなどではすぐに書くこともできるのですが,(というかそういうパッケージも有るでしょうし)自分で色々実装して試してみよう,ということで書いてみた例を紹介します.

ちなみに,Go言語とは,Googleが開発したプログラミング言語で,クロスコンパイルがすごく簡単にできるがゆえにいいなーと思っていた言語でした.つまり,MacでつくったツールをWindowsで実行するようにするのがすごく簡単ということです.

golang.jp - プログラミング言語Goの情報サイト

ロスコンパイル参考: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