「松原ガレッジ」のブログ

大阪府松原市にあるウェブ開発・HP制作をするところ。管理人が思ったことや困ったこと、課題についてまとめていきます。

Rubyの言語判定ライブラリは cld3-ruby を使うといいかも

здравствуйте

「何語やねん!」
そう思ったあなた、正解です
(ズドラーストヴィチェと読むそうです)

今日はロシア語の挨拶からお送りしております。
言語判定が必要そうな機会ができたので、色々調べてみました。

外部ネットワークを経由せずに高い精度で言語判定するなら cld3-ruby がよさげです。
Mastodon の中でも利用されているみたいですね

インストールする際には

C++ compiler
Protocol buffers

が必要になるので、

debian系だと(rubyのdockerイメージで確認)

libprotobuf-dev
protobuf-compiler

RedHat系だと(AmazonLinux2で確認)

protobuf-devel
protobuf-compiler

をインストールしてから gem をインストールしてみてください!

あとはreadmeの通り

require 'cld3'

cld3 = CLD3::NNetLanguageIdentifier.new(0, 1000)

cld3.find_language("こんにちは") # => #<struct Struct::Result language=:ja, probability=1.0, reliable?=true, proportion=1.0, byte_ranges=[]>

cld3.find_language("This is a pen.") # => #<struct Struct::Result language=:en, probability=0.9999408721923828, reliable?=true, proportion=1.0, byte_ranges=[]>

cld3.find_language("здравствуйте") # => #<struct Struct::Result language=:ru, probability=0.3140212297439575, reliable?=false, proportion=1.0, byte_ranges=[]>

最初のインスタンス生成する箇所で2つの数値を与えるんですけど、それぞれ
・最初の引数が(0の箇所)が与えられた文字列が、その引数のbyte数よりも小さい時nilを返す(最低限必要な閾値になるbyte数)
・2つめの引数(1000の箇所)が、最初にUTF8に変換可能なbyte列から最大のbyte数 です。

bype数基準なので日本語だと

text_utf8 = 'こんにちは'.encode(Encoding::UTF_8)
text_utf8.bytesize #=> 15

になるので、元のテキスト量にもよりますが気持ち多めの方が精度がいいかもしれません。
(この辺り最適な量がわかる人は教えて下さい!)

内部で利用されているコードChrome とかでも使われているとのこと、ありがとう Google さん
ありがとう gem の製作者さん

これで外部ネットワークを経由せずに言語判定ができますね