Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

センシティブワード・ミュートワードの誤検出を減らすために、日本語の単語分割(分かち書き)を導入する #10741

Open
yuriha-chan opened this issue May 2, 2023 · 8 comments
Labels
[Feat] Mute/Block Mute or Block related issue. It does not cover server blocking or server muting. ✨Feature This adds/improves/enhances a feature

Comments

@yuriha-chan
Copy link
Contributor

単語分割(わかち書き)とは

これはセンシティブじゃないぞ!ゴールドマンコーポレーション
という文字列から
これ / / センシティブ / じゃ / ない / / / ゴールドマン / コーポレーション
を得る処理のこと。

何が問題なのか

例えば、「クソ」という単語でフィルターしようとすると、「ダークソウル」「ポークソーセージ」「フォークソング」等が誤検出される。

正規表現(#10688)や除外パターン(#10701)により抑制可能だが、

  • 誤検出のたびにパターンを考える手間が生じる
  • 誤検出が管理者に認知されパターンが登録されるまで、ユーザーに誤検出された結果を提示し続ける
  • 出現頻度の低い除外ワードが放置される
  • 複雑なパターンを意図したように動くための管理が面倒

という問題が生じる。

解決策

日本語の単語分割により、マッチの先頭および末尾を単語境界に限定する(オプションを提供する)ことで系統的に誤検出を減らせる。

コスト

CPU資源をそれなりに消費する。(一秒あたり5000文 ~ 50000文/s/CPU 程度) また、モデルや辞書のデータ容量が大きい(50MB~400MB)ので、クライアントサイドで動かすのは現実的ではない。

センシティブワード・ミュートワードの適用のみを目的とする場合は、単純な文字列マッチにひっかかった文のみを対象とすることで適用対象を絞り込むことが可能。

計算量は(ビームサーチにより)O(n)なのでRE-DoSのような極端な速度問題は生じないと考えられる。

単語分割器の候補

  • Juman++ v2 (https://github.com/ku-nlp/jumanpp)
    • 分割精度が高い。
    • デフォルトの辞書の単語数が大きく、多くの種類の単語に対応可能。
    • 速度はあまり速くない。(5000文/s 程度)
    • ユーザー辞書の適用に対応していない。(実装できなくはない)
    • 一文2000文字といった極端に長い文は処理できないので句点等であらかじめ分割が必要
    • C++
  • Mecab
    • カタカナ語の複合語・造語を長い未知語として認識しがちという問題がある。
    • ユーザー辞書を適用可能。
    • 速い。(50000文/s 程度)
    • C++
  • Kuromoji
    • Mecabと似たモデルを使っているため、同程度の精度と特性。(速度も同じくらいと思われる)
    • Elasticsearchでよく採用されている。
    • Java
    • Pure Javascript実装もあるらしい。性能は分からん。
  • KyTea
    • 用例登録による精度向上がしやすい。
    • モデルファイルが巨大(~GB)でロードにも時間がかかる
    • Mecabと同程度の速度
    • 分割を間違えた時、理解不能な間違いになりやすい

コマンドのパイプ入出力でラッパーを書くか、C++のラッパーライブラリを書いて利用する。前者の場合はプロセスを生かしっぱなしにして通信する方が速度的には有利。

未知語の扱い

ユーザーによる造語などは未知語として検出される。未知語は文字単位で分割する処理とすることでセンシティブワードやミュートワードを含む造語にマッチさせることができる。

@yuriha-chan yuriha-chan added the ✨Feature This adds/improves/enhances a feature label May 2, 2023
@syuilo
Copy link
Member

syuilo commented May 2, 2023

インスンスが日本語だとは限らないから面倒そう

@yuriha-chan
Copy link
Contributor Author

日本語のインスタンスにしか必要ない機能なので、ビルドか環境構築時にオプションが必要そうという面でたしかに面倒そうではある

@acid-chicken
Copy link
Member

どちらかというと開発におけるメンテナンスと負荷が大変

@acid-chicken
Copy link
Member

センシティブ機能で全てフィルタするのは無理なので曖昧なものはアンテナを活用して手動でやっていくのが望ましそう

@yuriha-chan
Copy link
Contributor Author

yuriha-chan commented May 2, 2023

手動でモデレートしていくのが望ましいというのはそれはそう

その上で想定外の巻き込みミュートを予防する需要がありそうだと思ったのだがどうだろうか…(もちろん単語分割を使ったところで巻き込みミュートがゼロになるわけではないがベターな策として)

コマンドラインインタフェースは安定している(というかmecabに関してはもう更新されていない)ので、導入するとしたらffmpegのように外部プログラムの扱いにすればメンテナンスも容易かと思う。mecabならubuntuのパッケージもあるのでテスト環境の構築もapt install mecab mecab-ipadic-utf8だけでできる

(個人的には自インスタンス立てるなら検索用の単語分割含め導入したいくらいの気持ちだがコミュニティ的には需要・関心あるのかなという気持ちでIssueを立てている)

@acid-chicken
Copy link
Member

acid-chicken commented May 2, 2023

4 年前に twista (fork) で MeCab による日本語検索機能を導入したのを発端に現在もめいすきーなど MaCab を依存に持つ fork はあるが、それらの運用において辞書更新による検索結果の不安定性などがかなり気になったので、うまいローテーション(実際先に挙げた fork でもローテーションしていたが結果として負荷がそこそこあった)などを含めて考えるとそんなにシンプルに行かないという感想

@yuriha-chan
Copy link
Contributor Author

yuriha-chan commented May 2, 2023

要するにインタフェースだけ用意して、単語分割器の性能やインタフェースへの適合云々はインスタンス運用者が自己責任で管理してねという形にしたい

また精度が悪く多くの未知語が生じたとしても、未知語は文字単位で分割するようにすれば単純な文字列マッチにフォールバックされることと同じなので問題にはならないと思われる(そもそも利用者が検索除けするなどすればどのみち検出できないので完璧な精度が求められているわけでもない)

まぁでもmecab-ipadicの精度は気になるレベルなのでJuman++がおすすめで、そうなると(少なくとも利用者は)ビルドの手間と(大きなインスタンスでは)運用時の計算負荷が必要という問題はある

ところでめいすきーで使われているneologdという辞書は

新語の固有名詞を大量に含んでいる関係上、更新が頻繁(だった)
neologdは固有名詞を積極的に見つけにいくのでトレンドワードの検出等には良いが、単語(形態素)の単位が長すぎてミュートワードの検出や検索のインデックスを張るのには向いていないのでそもそもこの機能には使わないのが妥当

@KisaragiEffective
Copy link
Collaborator

KisaragiEffective commented Jun 16, 2024

revisit: 現代だとIntl.Segmenterを使うのが良さそう:

image

@samunohito samunohito added the [Feat] Mute/Block Mute or Block related issue. It does not cover server blocking or server muting. label Nov 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feat] Mute/Block Mute or Block related issue. It does not cover server blocking or server muting. ✨Feature This adds/improves/enhances a feature
Projects
Development

No branches or pull requests

5 participants