Juliaで日本語テキストからワードクラウド

技術
この記事は約8分で読めます。

はじめに

 ここでは、Juliaでワードクラウドを作成します。
 前回までに、Juliaでの日本語形態素解析を紹介したので、日本語テキストを対象とします。
 実行環境は、SageMaker Studio Labです。

事前準備(フォントファイル):SageMaker Studio Labの事情

(※SageMaker Studio Lab以外の環境で実行する場合は、読み飛ばしてください)

 さて、いざ始めようとしたときに、ある事実が判明します。なんと、SageMaker Studio Labにはフォントがインストールされていません。Terminalを開いて「find / -name *.ttf -print」を実行すると、pythonのインストール先以外に「*.ttf」ファイルが存在しないことが確認できます。
 ワードクラウドでは、フォントを読み込んで配置するので、その元となるフォントファイルがなければどうしようもありません。
 実際に、Juliaのwordcloudパッケージを試してみると、フォントが見つからないため、文字は四角で表示されてしまいます。(その前に大量のエラーが出ます。)

 一方、Pythonでワードクラウドの動作を確認すると、問題なく文字が表示されます。
 調べてみると、pythonのwordcloudライブラリ内に「DroidSansMono.ttf」というフォントファイルを持っていて、デフォルトではこれを使っています。


 Juliaでワードクラウドするためには、フォントをインストールする必要があります。しかし、「sudo」も「apt-get」も使えず、標準のインストール方法は使えないので、手動でフォントをインストールします。
 また、日本語のワードクラウドを行うので、日本語フォントが含まれているものを使います。今回は、一般社団法人文字情報技術促進協議会より配布されている「IPAexフォント」の「IPAexゴシック」を使うことにします。
 次の手順でインストールします。Terminal内で次のlinuxコマンドを実行してください。

cd
mkdir .fonts
cd .fonts
wget https://moji.or.jp/wp-content/ipafont/IPAexfont/ipaexg00401.zip
unzip ipaexg00401.zip

 上記実行後に、runtimeを再起動します。すなわち、JupyterLabのタブを閉じ、SageMaker Studio Lab画面で「stop runtime」したのち、「start runtime」します。
 本来、Linux上では、フォントキャッシュを更新するために「fc-cache -fv」コマンドを実行するのですが、SageMaker Studio Labにはこのコマンドがないので、このようにしています。
 また、runtimeを再起動しなくても、juliaカーネルの再起動でも大丈夫そうです。juliaカーネルを使用しているipynbファイルを開いた画面で、マウス右クリックメニューから「Restart Kernel…」をクリックで、カーネル再起動ができます。

 以上で、フォルダ「/home/studio-lab-user/.fonts/ipaexg00401/」にフォント「ipaexg.ttf」がインストールされて、フォントとして認識される状態になりました。

 余談ですが、SageMaker Studio Lab上で、Pythonのワードクラウドで日本語を扱う場合にも、このフォントのインストールは意味があります。デフォルトの「DroidSansMono.ttf」には日本語フォントが含まれていないので、そのままでは日本語が表示されません。そこで、この日本語フォントを参照するように指定することで、日本語文字も正しく表示されます。

日本語テキスト

 今回、日本語テキストは、「青空文庫」の「アリスはふしぎの国で(ルイス・キャロル, 大久保ゆう訳)」を用いることにしました。これは、英語のサンプルが「ALICE IN WONDERLAND」だったので、それに合わせて同作の日本語版を使うことにしました。

 「青空文庫」のテキストファイル版を用いて、ルビ・注釈、および、訳者あとがきや、末尾の奥付部分を削除したテキストを作成しました。さらに、処理の都合上、句点「。」での改行を追加したり、行頭の空白は削除、行中の空白は改行に置換、といった加工を施しています。

使用するパッケージ

単語の出現数計算

 パッケージのサンプルプログラムと異なり、単語の出現数一覧をDict{Stding, Int}型でwordcloudに引き渡します。
 そのための計算を行う関数を定義します。
 日本語テキストを前提しているので、内部で形態素解析を行っています。有効な単語は名詞のみにしました。また、形態素解析の誤解析の場合に出現しやすい一文字のひらがなとカタカナ、および長音記号「ー」、波線記号「~」は出現数を計算しないようにしてあります。

using Dates
using Awabi
using WordCloud

# テキストに含まれる単語の出現数を求める
function countmorph(file::String)::Dict{String, Int}
    # 形態素解析の初期化(辞書の設定)
    tokenizer = Tokenizer("/home/studio-lab-user/mecab/etc/mecabrc")

    count = Dict{String, Int}()
    open(file) do f
        for line in eachline(f)
            # 一行を形態素解析
            tokens = tokenize(tokenizer, line)
            for token in tokens
                surface = token[1]
                hinsi = split(token[2], ",")
                # 一文字のひらがな・カタカナ・長音「ー」・波線「〜」を対象外にする
                if hinsi[1] == "名詞" && (length(surface) > 1 || ((surface < "ぁ" || surface > "ヶ") && !(surface in ["ー", "~"])))
                    count[surface] = get(count, surface, 0) + 1
                end
            end
        end
    end
    count
end

# 解析対象のテキスト
textfile = "text/alice_jp.txt"

# テキストを形態素解析し、単語の出現数一覧を求める
word_counts = countmorph(textfile)

 ここで得られた単語のなかには、極端に出現数が小さいもの(例えば、出現数1)や、どのテキストにも広く出現するであろう表記が含まれています。これらを除外します。

# 除外する表記の一覧
ngwords = ["こと", "もの"]
# 最小出現数:出現数が極端に小さい単語を除外するため
mincount = 10
# 出現数一覧から指定に基づいて除外
word_counts = Dict((k, v) for (k, v) in collect(word_counts) if v >= mincount && ! (k in ngwords))

 これで、妥当な出現数一覧が得られました。

ワードクラウドの作成

 wordcloudに出現数一覧を渡します。
 その際、他の引数はほとんど英語版でのサンプルと同じですが、fontsだけ変えてあります。fontsを”ipaexg”にしてあるのは、上でインストールしたフォントファイルの名前です。別のフォントを使用する場合は、その名前を指定するようにしてください。

# 表示する形状
maskfile = pkgdir(WordCloud)*"/res/alice_mask.png"

# ワードクラウドの作成
wc = wordcloud(
    word_counts, 
    mask = maskfile,
    maskcolor="#faeef8",
    outline = 4,
    linecolor = "purple",
    colors = :Set1_5,
    angles = (0, 90),
    fonts = "ipaexg", 
    density = 0.5) |> generate!

# 出力
outfile = "out/" * Dates.format(now(), "yyyymmddHHMMSS") * ".svg"
paint(wc, outfile)

 実行すると、次のような画像が出力されます。

 以上で、ワードクラウドを表示することができました。
 あとは、textfile(解析対象のテキスト)やmaskfile(表示する形状)などを変更して、結果を確認してください。

まとめ

 上記をまとめたipynbファイルを、下記に格納してあります。

参考記事

コメント

タイトルとURLをコピーしました