前回の続きです。

前回は機械学習のための日本語学習コンテンツを IBM developerWorks からの情報を元に生成しました。 今回はこのコンテンツを使って機械学習を行い、その上で実際にいくつか問い合わせをして期待しているような分類ができるかどうかを確認してみます。

なお、今回のコンテンツで使う dwj.csv 以外のファイルの一覧は、このエントリの最後にダウンロードリンクを用意しています。必要に応じて利用してください。


おさらいとして、今回行おうとしている作業は、以下の3段階です:
(1) 学習させるデータを収集する
(2) 収集データを学習させる
(3) 実際に利用する

前回の作業によって (1) の学習データを収集し、以下の様な2列フォーマットの CSV ファイル(dwj.csv)が機械学習用コンテンツとして手元にある、という段階になっているものとします:
React Native ゲームを作成し、・・・・・,opensource
iOS 開発用プラットフォームと・・・・・,opensource
Vagrant と PuPHPet のおかげで、・・・・,opensource
Bluemix 上にホストされる、Go ・・・・・,opensource
  :
  :
(学習コンテンツ),(分類カテゴリ)
  :
  :

このコンテンツが手元にない場合は前回の内容を参照して、用意しておいてください:
http://dotnsf.blog.jp/archives/1041438999.html


では、引き続き作業の (2) を行います。この dwj.csv ファイルの内容を Watson に学習させてみます。IBM Bluemix にログインし、Watson カテゴリの NLC(Natural Language Classifier) サービスをランタイムに追加するなどしてインスタンス化します:
2015100101


インスタンス化した後に資格情報を確認して、環境変数内の username と password の値を確認します(後で使うのでメモするか、保存しておきます):
2015100102


学習させる前に、この NLC サービスの API をリファレンスで確認しておきましょう:
http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/apis/#!/natural-language-classifier

2015100103

NLC には(2015/Oct/01 時点で)6つの API が用意されていることがわかります。それぞれの API の用途を簡単に紹介しておきます:
2015100104

HTTPメソッドAPI パス説明
POST/v1/classifiersコンテンツをポストして学習させる
GET/v1/classifiers現在の学習クラス一覧を確認する
POST/v1/classifiers/{classifier_id}/classify特定の学習クラスを指定して、テキストを分類する※
GET/v1/classifiers/{classifier_id}/classify
DELETE/v1/classifiers/{classifier_id}特定の学習クラスを削除する
GET/v1/classifiers/{classifier_id}特定の学習クラスの状態を確認する

※ POST と GET の違いはテキストの指定方法の違い


表の上から2番目の API は現在の学習クラス一覧を調べて確認するものです。まだ何も作っていない状態であれば一覧は空のはずです。作業前後での比較の意味で一度この API を実行してみましょう。ブラウザを開いて、以下の URL にアクセスします。なお URL 内の (username) 部分と (password) 部分は上記の NLC サービス環境変数内でメモしたものに書き換えてください:
https://(username):(password)@gateway.watsonplatform.net/natural-language-classifier/api/v1/classifiers

以下の様な画面になるはずです。 API の実行結果が JSON で返されますが、"classifiers" という変数の値は空の配列になっています。たしかにまだ学習は行われていない状態であることが確認できました。なお、このウィンドウは後でも使うので、このまま開いておいてください:
2015100104


作業 (2) の学習を行うのは、表の1番上にある /v1/classifiers への POST メソッドになります。上記リファレンスページの一番上にある /v1/classifiers への POST メソッドをクリックすると以下の様な説明が表示されます:
2015100101


これを見ると、このメソッドで2つのファイルをフォームデータとして送ることで学習指示を行うことができる、ということがわかります。2つのファイルのうちの1つは前回用意した学習コンテンツ(dwj.csv)で、これを training_data というパラメータで指定することが分かります。そしてもう1つは training_metadata というパラメータでメタデータ情報を指定する必要があることがわかります。この training_metadata で指定するファイルは以下の内容の JSON テキストファイル(training_metadata.json)を用意します(注 "dwj" 部分は名前なので任意):
{"language":"ja","name":"dwj"}

ではこの2つのファイルを使って Watson に学習させるための処理を指定する HTML ファイル(nlc_training.html)を1つローカルに用意します。上記のように /v1/classifiers に2つのファイルを POST することで学習させることができるので、それを実際に行うためのフォームを含む HTML にしています。なおテキスト内の (username) 部分と (password) 部分は上記の NLC サービス環境変数内でメモしたものに書き換えてください:
<html>
<body>
<form action="https://(username):(password)@gateway.watsonplatform.net/natural-language-classifier/api/v1/classifiers" method="post" enctype="multipart/form-data">
<table border="1">
<tr><th>Meta Data</th><td><input type="file" name="training_metadata"/></td></tr>
<tr><th>Data</th><td><input type="file" name="training_data"/></td></tr>
</table>
<input type="submit" value="submit">
</form>
</body>
</html>

この HTML ファイルをブラウザで開きます。Ctrl+O から HTML を指定するか、エクスプローラーなどからダブルクリックしたり、ドラッグ&ドロップすることでもブラウザで開くことができます:
2015100102


2つの参照ボタンをクリックして、Meta Data には training_metadata.json ファイルを、Data には dwj.csv をそれぞれ指定します。正しく指定できたことを確認して submit ボタンをクリックすると、指定した dwj.csv を元にした機械学習が開始します:
2015100103


submit ボタンをクリックした後の画面(の例)がこちら、この時点で機械学習が始まっていて、その id(classifier_id) が "FAA074-nlc-602" であることが分かります:
2015100101


この時点で上記の /v1/classifier API (学習クラス一覧)を再度実行してみます(まだウィンドウを閉じていなければ F5 でリロードします)。先程までは "classifiers" 変数の中身は空配列でしたが、今は学習中のクラスが存在しているため、結果がこのようになります:
2015100102


ここで表の一番下にある /v1/classifier/{classfier_id} への GET を実行して、この学習クラスの状態を確認してみましょう。新たにブラウザを開き、classfier_id の値を最後に指定して、以下の URL へアクセスします:
https://(username):(password)@gateway.watsonplatform.net/natural-language-classifier/api/v1/classifiers/FAA074-nlc-602

するとこのような結果が表示されます。"status" の値が "Training" になっていて、この学習クラスは現時点で学習中である、ということがわかります。学習が終わるまでしばらく(今回の例であれば30分程度)待ちましょう:
2015100103


しばらくしてから同じ URL にアクセスして、この図のように "status" の値が "Training" から "Available" に変わることを確認してください。ここまでの状態になった段階で、3段階の作業の (2) までが完了したことを意味します:
2015100104



用意した日本語コンテンツによる機械学習が完了したことが確認できたので、最後に (3) の、学習させた内容を使って実際にテキスト分類ができるがどうかを確認してみましょう。

表で言うと3番目および4番目にある /v1/classifiers/{classifier_id}/classify API を使います({classifier_id} の部分に実際のクラスID(今回であれば FAA074-nlc-602)を指定する)。この API を POST で実行する時は本文で、GET で実行する時は text パラメータで、分類させたいテキストを指定して実行します。今回はブラウザでも確認できるよう後者の方法を使って確認してみます。

例えば、前回のエントリの導入部で試した「mongoDBっていいよね」というメッセージが、何に分類されるかを確認してみるには、ブラウザで以下の URL にアクセスします。メッセージを text パラメータで指定している点がポイントです:
https://(username):(password)@gateway.watsonplatform.net/natural-language-classifier/api/v1/classifiers/FAA074-nlc-602/classify?text=mongoDBっていいよね

するとこのような結果がブラウザ画面に表示されました:
2015100105


見やすいように JSON に適宜改行を加えた結果がこちらです(赤字はコメント):
{
 "classifier_id":"FAA074-nlc-602",
 "url":"https://gateway.watsonplatform.net/natural-language-classifier/api/v1/classifiers/FAA074-nlc-602",
 "text":"mongodBっていいよね", 与えたテキスト
 "top_class":"java",           最も可能性が高いと判断された分類結果(=java)
 "classes":[                   全結果とそれぞれの確信度
  {"class_name":"java","confidence":0.31087844561162503},       java = 31.1%
  {"class_name":"cloud","confidence":0.23414513131908235},      cloud = 23.4%
  {"class_name":"opensource","confidence":0.18726090536344517}, opensource = 18.7%
  {"class_name":"linux","confidence":0.14376505541140203},      linux = 14.4%
  {"class_name":"mobile","confidence":0.07936916665292562},     mobile = 8.0%
  {"class_name":"xml","confidence":0.044581295641519754}        xml = 4.5%
 ]
}

結論として、今回学習させたコンテンツをベースに「mongoDBっていいよね」というテキストを分類させると、これは "Java" に分類される可能性が最も高い(約31.1%)、と判断されました。続いて "Cloud"(約23.4%)、"OpenSource"(約18.7%)、"Linux"(約14.4%)、"Mobile"(約8.0%)、そして "XML"(約4.5%)という結果になりました。前回の話というか、当初の計画では、ここは "OpenSource" になって欲しかった所でした(苦笑)。

実際のところ、というか私個人的には「mongoDB といえばオープンソース、またはクラウドかな」という印象を持っているので、私の主観とは少し違う結果になりました。皆さんの考えとしてはいかがでしょう? 最も高い Java も 31.1% なので、その確信度としては必ずしも自信満々に回答しているわけではなさそうです。まあ、この結果を導きだすような学習コンテンツだった、ということになるんですかね。

いくつかのテキストを試して見た結果を載せておきます:
テキスト分類結果確信度(%)
mongoDBっていいよねJava31.1
Cloud23.4
OpenSource18.7
Linux23.4
Mobile8.0
XML4.5
Bluemixって知ってる?Cloud83.9
Java7.1
Mobile4.6
OpenSource3.4
Linux0.9
XML0.1
Ubuntuも勉強しなきゃLinux83.1
OpenSource5.2
Cloud5.0
XML2.4
Mobile2.1
Java2.0
人工知能は人間を超えるのか?Java34.7
Linux24.5
Cloud16.5
OpenSource16.2
Mobile7.1
XML1.0


どうでしょうね。なんとなくですが、確信度が高い(80%超え)結果は私個人の主観とも一致しているような分類ができていると思います。逆に1位でも確信度が低いと、必ずしも私の主観とは一致していないような気もしています。その意味では、そこそこな分類エンジンが出来たかな、という印象です。

以上、ここまでで作業工程の (3) も確認できました。 大作ブログエントリになってしまいましたが、現在 IBM Bluemix から提供されている日本語対応の言語分類エンジンの学習方法と利用方法、そしてオマケ的ですが、学習コンテンツの生成例まで併せて紹介しました。 繰り返しになりますが、学習コンテンツを作る際に、是非試される方の身近にあるもの(学校内/企業内のコンテンツなど)を使ってコンテンツを作った上でこのシステムを作っていただくと、その有用度についても身近でわかりやすく、もしかするとビジネス的にも有用な分類エンジンができるかもしれません。是非挑戦してみていただきたいです。


最後に、今回の2回ぶんのエントリで紹介したサンプルアプリケーション一式のソースコードを Github 上で公開しておきました。よろしければ clone なりダウンロードなりして参考にしてください:
https://github.com/dotnsf/nlc_sample