Help us understand the problem. What is going on with this article?

Elixirで弱々しいAI#3「MeCab辞書差し替え |> CaboChaモジュールの作成」

(この記事は Elixir (その2)とPhoenix Advent Calendar 2016 8日目の記事です)

前回は、PhoenixでWebアプリ化して、最後に出現した固有名詞をオウム返しする、多少は言われたことを掴む(文字通り「掴む」だけですが…)貧弱AIを作りましたが、「進撃の巨人」を知らないオールドタイプであることが判明しました :sweat_smile:

今回は、MeCabの辞書を差し替え、貧弱AIを現代っ子に進化させた後、文章の構成を解析するための「CaboCha」をElixirで使えるようにします

CaboChaのElixirモジュールは、世に無いようなので、今回作ってみます :rainbow:

なお、本コラム中の「Elixirの書き方」については、あまり細かく説明をしていないので、「ここの書き方が分からない」とか「この処理が何をしているのかよく分からない」等あれば、コメントいただければ、回答します :headphones:

新語辞書に差し替え

「mecab-ipadic-NEologd」という、MeCabの新語辞書をインストールすることで、現在っ子に進化します

Windowsを除いて、パッケージマネージャでインストール可能です :ok_hand:

  • Docker(trenpixster/elixir)やUbuntu・・・apt
  • CentOSなど・・・yum
  • Mac・・・Homebrew
  • Windows・・・手動で設定 ※UTF-8で行うため、以下2点の手順を変更する必要があります
    • 2の手順は、「 [Recompile SHIFT-JIS Dictionary]」では無く「 [Recompile UTF-8 Dictionary]」を実行
    • 4の手順の前に、mecab-dict-compile.cmdの「-t」の「shift-jis」を「UTF-8」に変更

早速、「神撃の巨人」をリトライしてみると...おー、通じるようになった :laughing:

1.png

CaboChaのインストール

CaboChaを下記の「ダウンロード」からインストールするか、yum等でインストールしてください

 CaboCha: https://taku910.github.io/cabocha/

なお、Windows版は、MeCab同様、「UTF-8」を選択してください

CaboChaモジュールの作成

インストールが終わったら、CaboChaを呼び出すモジュールを追加します

lib/cabocha.ex
defmodule Cabocha do
    def view( body ), do: tree( body )
    def tree( body ), do: if body == "" || body == nil, do: "", else: "echo #{body} | cabocha" |> execute
    def execute( command ) do
        command
        |> to_char_list
        |> :os.cmd
        |> to_string
    end
end

このモジュールを使って、CaboChaの解析結果をページに追加してみます

lib/web_mini_ai_web/templates/page/index.html.eex
<p>あなた「<%= @params[ "message" ] %></p>
<p>貧弱AI「<%= MiniAi.listen( @params[ "message" ] ) %></p>

<form method="GET" action="/">
<input type="text" name="message" size="60" value="">
<input type="submit" value="話しかける">
</form>

<hr>
<h3>CaboCha解析結果</h3>
<p><pre><%= Cabocha.view( @params[ "message" ] ) %></pre></p>

話しかけると、CaboChaでどのように解析されているかが分かります

2.png

CaboCha出力をXMLに切り替え

このツリー構造は、見た目は良いですが、このままだとプログラム上からは扱いにくいので、CaboChaのコマンドラインオプション「-f3」を使って、XML出力に切り替えます

lib/cabocha.ex
defmodule Cabocha do
    def view( body ), do: xml( body )
    def xml( body ),  do: if body == "" || body == nil, do: "", else: "echo #{body} | cabocha -f3" |> execute
 …

ブラウズをリロードすると、以下のようなXML表示に切り替わります

image.png

CaboCha XMLをパターンマッチしやすい形に変換

XMLのままだと、Elixirで処理しにくいので、「xml_parser」モジュールを使って変換します

mix.exsにxml_parserモジュールのエントリーを追加します

mix.exs
defmodule WebMiniAi.Mixfile do
  use Mix.Project
 …
  defp deps do
    [{:phoenix, "~> 1.2.1"},
     {:phoenix_pubsub, "~> 1.0"},
     {:phoenix_html, "~> 2.6"},
     {:phoenix_live_reload, "~> 1.0", only: :dev},
     {:gettext, "~> 0.11"},
     {:cowboy, "~> 1.0"},
     { :mecab, "~> 1.0" }, 
     { :xml_parser, "~> 0.1.0" }, 
    ]
  end
 …

iexを、Ctrl+Cを2回押して抜けた後、モジュールを取得します(要ネット接続)

iex>
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
       (v)ersion (k)ill (D)b-tables (d)istribution
# mix deps.get

xml_parser.parseを使って、XMLからパターンマッチしやすい形に変換します

lib/cabocha.ex
defmodule Cabocha do
    def parse( body \\ "10年後、ブラックホールの謎を応用した、重力のプログラミングが可能となる" ) do
        case body == "" || body == nil do
            true  -> ""
            false ->
                body
                |> xml
                |> XmlParser.parse
        end
    end
 …

そのままPhoenixで表示できないので、コンソールで確認します

5/8補足:inspect()使えばPhoenix上でも見れます

# iex -S mix phoenix.server
iex> Cabocha.parse
{:sentence, nil,
 [{:chunk,
   %{func: "3", head: "3", id: "0", link: "6", rel: "D", score: "-1.514907"},
   [{:tok, %{feature: "名詞,数,*,*,*,*,1,イチ,イチ", id: "0"}, "1"},
    {:tok, %{feature: "名詞,数,*,*,*,*,0,ゼロ,ゼロ", id: "1"}, "0"},
    {:tok,
     %{feature: "名詞,接尾,助数詞,*,*,*,年,ネン,ネン", id: "2"},
     "年"},
    {:tok, %{feature: "名詞,接尾,副詞可能,*,*,*,後,ゴ,ゴ", id: "3"},
     "後"},
    {:tok, %{feature: "記号,読点,*,*,*,*,、,、,、", id: "4"}, "、"}]},
  {:chunk,
   %{func: "6", head: "5", id: "1", link: "2", rel: "D", score: "1.513072"},
   [{:tok,
     %{feature: "名詞,固有名詞,一般,*,*,*,ブラックホール,ブラックホール,ブラックホール",
       id: "5"}, "ブラックホール"},
 …(略)…
    {:tok,
     %{feature: "動詞,自立,*,*,五段・ラ行,基本形,なる,ナル,ナル",
       id: "18"}, "なる"}]}]}

これで、文章の構成を解析できるようになったので、いよいよ次回は、AIらしく、文脈から意味を読み取る(といってもカンタンな解釈ですが)ようなロジックを作っていきます :rocket:

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした