JumanppをGolangから扱いやすくするラッパライブラリを書いた話
JumanppをGolangから扱いやすくするラッパライブラリを書いた話
なぎスケ!を永遠と見続けてエピソード #44まで見ました。 ぷっすまを彷彿とさせるAmazon Prime Videoのオリジナル番組です。 江頭2:50があまり出てこず寂しいですが、面白い番組です。
なぎスケ見ながらですが、サクッと書いていきます。
何をするのか
Twitter等のくだけた話し言葉を解析するのにはmecabよりもJumanppが優れていると聞いています。 JumanppはPythonやRubyバインディングは有るが、Golangで呼び出すものは無さそう?なので とりあえず自分が使うように書きました。 ビルドしたJumanppをexec.Command()で呼び出し、呼び出した結果を構造体に詰め込み返しているだけです。
より良い書き方が有ると思うのでコメントやPull Requestでご指摘頂けると励みになります。
あと知らなかったのですが、Githubにコードを上げるだけでgo get ****できるんようになるんですね。
使い方
ここにも書きました。
Install
go get github.com/kenpos/JumanppGo
呼び出し方
一例ですがこのように呼び出せるようになっています。
package main
import (
"fmt"
jumanppGo "github.com/kenpos/JumanppGo"
)
func main() {
dics := jumanppGo.JumanDic("魅力的な街に住んでいます")
fmt.Println(dics)
for _, v := range dics {
fmt.Printf("見出し:%s \n読み:%s \n原型:%s \n品詞:%s \n分類:%s \n活用1:%s \n活用2:%s \n意味:%s \nrepname:%s \n", v.Midasi, v.Yomi, v.Genkei, v.Hinsi, v.Bunrui, v.Katuyou1, v.Katuyou2, v.Imis, v.Repname)
}
}
中身の解説
外部から読み出す構造体の場合、名前の頭文字一文字目を大文字にする必要があります。 忘れていたのでハマりました。
ちなみに要素名はPythonバインディングと合わせる形で定義します。
type StandardDic struct {
Midasi string
Yomi string
Genkei string
Hinsi string
Bunrui string
Katuyou1 string
Katuyou2 string
Imis string
Repname string
}
JumanppをGolangから読み出し部分
jumandic.jppmdlは、公式のReleseからダウンロードできるjumanpp-2.0.0-rc3.tar.xz等の中に含まれているものを利用します。 jumanpp.exeはWindowsの場合自前でビルドする必要があります。
jumandic.jppmdlは動かしたいgo言語と同じフォルダに置いておけばとりあえず動くと思います。
func Jumanpp(str string) string {
cmdstr := "echo " + str + "|jumanpp.exe --model=jumandic.jppmdl --force-single-path"
stdout, err := exec.Command("sh", "-c", cmdstr).Output()
if err != nil {
fmt.Println(err)
}
return string(stdout)
}
Jumanppはパイプで文字列を受け取るのですが、Golangのexec.Commandはパイプをそのまま渡すとダメらしいので、 sh -cで読み出します。 そのため、このパッケージをWindowsで動かすには、WSLでの動作が前提となります。 Cygwinなどが入っていてsh使えればもしかしたら動くかもしれないですが…確かめていないです。
全文
go getで取得するので参考です。
package jumanppGo
import (
"fmt"
"os/exec"
"strings"
)
type StandardDic struct {
Midasi string
Yomi string
Genkei string
Hinsi string
Bunrui string
Katuyou1 string
Katuyou2 string
Imis string
Repname string
}
func set(n []string) StandardDic {
var s StandardDic
s.Midasi = n[0]
s.Yomi = n[1]
s.Genkei = n[2]
s.Hinsi = n[3]
s.Bunrui = n[4]
s.Katuyou1 = n[5]
s.Katuyou2 = n[6]
s.Imis = n[7]
s.Repname = n[8]
return s
}
func stuffingStandardDic(str string) []StandardDic {
var dic []StandardDic
spstr := strings.Split(str, "\n")
for _, s := range spstr {
tmp := strings.Split(s, " ")
if len(tmp) <= 1 {
break
}
dic = append(dic, set(tmp))
}
return dic
}
func jumanpp(str string) string {
cmdstr := "echo " + str + "|jumanpp.exe --model=jumandic.jppmdl --force-single-path"
stdout, err := exec.Command("sh", "-c", cmdstr).Output()
if err != nil {
fmt.Println(err)
}
return string(stdout)
}
func JumanDic(str string) []StandardDic {
stdout := jumanpp(str)
return stuffingStandardDic(string(stdout))
}
まとめ
とりあえず動くものをと思い書きました。 Go用のパッケージ公開の方法も分かったのでもう少し調べて記事にするネタ帳にストックしておきます。