「一句」を判定するライブラリikku-goをリリースしました

作ったもの

ikku-go というライブラリを作ったので公開しました。 github.com

ロゴ画像(?)はStable Diffusionで生成しました。

575を検知したい

このライブラリは何気ない会話から575が生まれているという気づきを与えてくれます。

もともとはr7kamuraさんの ikku を使っていたのですが、最近はgoを使うことが多かったため、go版も欲しくなったのが実装理由です。 実装の大部分を参考にさせていただきました。 GitHub - r7kamura/ikku: Discover haiku from text.

使い方

非常に簡単で、引数にとった文字列から5-7-5の形になっている部分を抽出します。

オプションで別途ルールを渡すことで、短歌のような5-7-5-7-7の型式にも対応可能です。 https://pkg.go.dev/github.com/kurochan/ikku-go#ReviewerOptionRule

import (
    "fmt"

    "github.com/ikawaha/kagome-dict/ipa"
    ikku "github.com/kurochan/ikku-go"
)

func main() {
    r, err := ikku.NewReviewer(ipa.Dict())
    if err != nil {
        panic(err)
    }
    song := r.Find("ああ古池や蛙飛び込む水の音。。")
    fmt.Println(song.String())
    // Output: 古池や蛙飛び込む水の音
}

形態素解析用の辞書の読み込みが重いせいか、残念ながらGo Playground上ではタイムアウトしてしまい動作せず。 https://go.dev/play/p/7BBNLRWaOml

実装

Goで実装された日本語形態素解析ライブラリ ikawaha/kagome を利用しています。

GitHub - ikawaha/kagome: Self-contained Japanese Morphological Analyzer written in pure Go

そのため別途mecabのネイティブライブラリを必要としないため利用が非常に楽です。cgoも不要です。

サンプルでは辞書にMeCab IPADICを利用していますが、他の辞書も利用可能となっています。

個人的にはコレクション操作系は https://github.com/samber/lo の書き心地が良いと思っていてよく使っているのですが、ここは好みが分かれるところかもしれません。

これ

func (s *Song) String() string {
    strs := lo.FlatMap(s.Phrases, func(ns []Node, _ int) []string {
        return lo.Map(ns, func(n Node, _ int) string { return n.String() })
    })
    return strings.Join(strs, "")
}

ikku-go/song.go at 026ed526fbeb0b2e2c76ec5df7a6cedf4923fe91 · kurochan/ikku-go · GitHub

samber/lo を使わないと

func (s *Song) String() string {
    var str string
    for _, ph := range s.Phrases {
        for _, n := range ph {
            str += n.String()
        }
    }
    return str
}

こうなります。(わかりにくいと言われそうな気がする)

こういう部分は1行で書けた方がスッキリしてていいんじゃないでしょうか。

case lo.Contains([]string{"助詞", "助動詞"}, n._type()):

ikku-go/node.go at 026ed526fbeb0b2e2c76ec5df7a6cedf4923fe91 · kurochan/ikku-go · GitHub

肝心の575判定ロジックの部分はこちらです。

ikku-go/scanner.go at 026ed526fbeb0b2e2c76ec5df7a6cedf4923fe91 · kurochan/ikku-go · GitHub

ほぼr7kamuraさんの判定ロジックを流用させて頂きました🙏

テスト

ひととおりのテストを書いたあとにfuzzingも入れてみました。

残念ながら?想定外のケースのバグは見つからず。。他のプロジェクトで意図しないバグが発見できたことがあったので、混み入ったロジックを実装した時はfuzzingも入れておきたいですね。

https://github.com/kurochan/ikku-go/blob/026ed526fbeb0b2e2c76ec5df7a6cedf4923fe91/reviewer_test.go#L236-L256

まとめ

  • go版の「一句」判定ライブラリを作りました
  • みんな気軽に575判定してみてね!