ウェブ雑記

tushuhei が奮闘する日記

Budou - 機械学習を用いた日本語改行問題へのソリューション

こんにちは! 日本語のウェブサイトを作っていると、日本語特有の問題にぶちあたることがありますよね。 その中でも今回着目したいのは、日本語改行問題。最近、この問題を解決するためのライブラリを公開したので、紹介します。

f:id:tushuhei:20160911102630j:plain github.com

そもそも日本語改行問題とは何か

ウェブブラウザで日本語で書かれたウェブサイトを見ていると、ときどき文章が変なところで改行されているのを目にすることがありますよね。 たとえば、こんなかんじ。 f:id:tushuhei:20160908193635p:plain 「ソリューション」が「ソリューショ」と「ン」に分かれてしまっています。読みにくいですね。

英語では単語がスペースによって区切られますが、日本語や中国語などのアジア圏の言語では単語がスペースで区切られないことが多いです。 そのため、英語では単語の途中で改行されることは通常ありませんが、日本語では単語の途中で改行されることがよくあります。 本文ならともかく、見出しやキャッチコピーでこれが起きると、結構気になりますよね!長いカタカナの外来語が入ると、更に目立ちます。 そこで、僕はこの「日本語の単語が途中で改行されてしまう現象」のことを日本語改行問題と呼びたいと思います。

もちろん、対応策が無いわけではありません。

今までの解決法 1: <br> タグを使う

単語が途中で改行されてしまうのなら、その前に改行を入れてしまえ!というアプローチですね。 悪くはないアプローチですが、レスポンシブデザインでウェブサイトを作っている場合には、望ましくないところで改行が入ってしまう可能性があります。

今までの解決法 2: white-space: nowrap を使う

これもよく使われるアプローチだと思います。white-space: nowrap で指定したタグには改行が施されないので、これで改行してほしくない単語を囲むという方法です。しかし、このアプローチだと画面幅によっては単語が画面からはみ出してしまう可能性があります。

今までの解決法 3: display: inline-block を使う

これが有望なアプローチだと思います。display: inline-block で指定されたタグは出来る限り改行しないように振る舞うので、単語の途中で改行が発生することを防ぐことができます。しかも、画面幅が極端に狭い場合には画面からはみ出さずに改行してくれます。SPAN タグに display: inline-block を指定して使うことが多いようです。

というわけで、display: inline-block を使えば解決です。これからもたくさん SPAN タグ入れていこうな!めでたしめでたし。

本当に解決なのか?

とはいえこの作業は大変面倒くさいです。一文一文見て、文節を考えなければなりません。小さいサイトなら良いですが、膨大な数のページを抱えたサイトでは非現実的でしょう。さらに、なんといっても日本語が読めなくてはいけません。もともと英語で作られたサイトを日本語に翻訳して使っているケースもあるわけで、実はエンジニアもデザイナーも日本語は読めないという状況は決して珍しくありません。

そこで Budou ですよ

Budou は、自動的に文章を良い感じの文節で区切ってくれるライブラリです。

たとえば、最初に出てきた例に Budou を使うと、こんなふうになります。 f:id:tushuhei:20160908194051p:plain 切れてない!

やっていることはとてもシンプルで、Cloud Natural Language API を使ってわかち書き*1を行い、予め与えられたルールに従って文節の生成を行っています。

さっそく使い方を見てみましょう!

インストール

pip install budou でインストールできます。もしシステムの Python で使えるようにしたいのなら適宜 sudo をつけて下さい。

Cloud Natural Language API の credential を用意する。

Budou を使うには、Cloud Natural Language API の設定が必要です。まずは、Google Cloud Consoleでプロジェクトを作成します。 ナビゲーションバーのプルダウンをクリックすると「プロジェクトを作成」という項目が現れるので、それをクリックします。 f:id:tushuhei:20160906223007p:plain 次に、タブメニューから「API Manager」を選択してサイドバーから「ライブラリ」を選択し、Cloud Natural Language API を検索します。 Cloud Natural Language API を選択すると、「有効にする」と書かれたリンクがあるはずなので、クリックして API を有効にします。 f:id:tushuhei:20160906222956p:plain サイドバーから「認証情報」を選択して、認証情報の作成に移ります。 「認証情報を作成」と書かれたボタンをクリックして、サービスアカウントキーを生成します。 キーのタイプは JSON と P12 が選べますが、ここでは JSON を選択して下さい。 f:id:tushuhei:20160906222934p:plain 最後に、タブメニューから「お支払い」を選択して、有効な支払情報とプロジェクトを紐付ければ、API の設定は完了です。

※注意

API を有効にしても、最後の「お支払い」のステップを完了しないと Cloud Natural Language API が使えないため Budou を使うことはできません。 ただ、Cloud Natural Language API には無料枠も用意されていますので、短い文章なら月 5,000 回くらいまで無料で使うことができるはずです。料金体系について詳しくは下記のリンクを参照して下さい。

Pricing  |  Google Cloud Natural Language API Documentation  |  Google Cloud Platform

Budou を使ってみる

API の設定が完了したら、python を起動して Budou を使ってみましょう。

import budou
parser = budou.authenticate('/path/to/json')
output = parser.parse(u'今日も元気です', 'wordwrap')
print output['html_code']  # => "<span class="wordwrap">今日も</span><span class="wordwrap">元気です</span>"
print output['chunks'][0]  # => "Chunk(word='今日も', pos='NOUN', label='NN', forward=True)"
print output['chunks'][1]  # => "Chunk(word='元気です', pos='NOUN', label='ROOT', forward=False)]"

Budou を使うには、authenticateメソッドでダウンロードした JSON 形式の認証情報を指定してください。 生成されたパーサの parse メソッドに処理を行いたい文字列を渡すことで、文節が SPAN で囲まれた HTML コードと、文節のリストが返されます。 これは optional ですが、SPAN タグのクラス名も指定することができます。 単独の Python スクリプトしてはもちろん、テンプレートエンジンのカスタムフィルターに応用することもできます。

くれぐれも指定したクラス名の要素には display: inline-block を設定することをお忘れなく!

Budou を使えば、デバイスの幅にかかわらず日本語改行問題を解決することができます。 f:id:tushuhei:20160911110320g:plain

ぜひ使ってみてください

簡単なスクリプトですが、日々のウェブサイト開発を少しでも楽にできれば幸いです。

日本語改行問題を撲滅しましょう!

GitHub の issue や pull request もお待ちしております*2。

github.com

*1:「すもももももももものうち→すもも も もも も もも の うち」のように、単語を語にわけることです。わかち書き - Wikipedia

*2:ちなみに、Budou はぶどうの一粒一粒を潰してはいけない大切な文節に見立てて、命名しました。