NLCでトレーニング、テストする

Windows 環境において Watson API である NLC(Natural Language Classifier)を実行したときのメモを残します。(2017年2月)

スポンサーリンク

参考にしたページ:Getting started with the Natural Language Classifier service

トレーニングする

(1)トレーニング用csv作成
トレーニング用のcsv を作成します。<質問>,<分類ID>で構成された CSV ファイルを作成します。このテキストファイルは UTF-8 で保存します。
training-sample.csv
その後作成した csv をアップロードします。USERNAMEとPASSWORDはサービス作成時に取得します。
API コマンド
c:\>set USERNAME=********-****-****-****-************
c:\>set PASSWORD=************

c:\>curl -i -u "%USERNAME%":"%PASSWORD%" -F training_data=@c:\temp\training-sample.csv -F training_metadata="{\"language\":\"ja\",\"name\":\"TutorialClassifier\"}" "%APIURL%"
以下のような結果が表示されます。classifier_idは*で隠しています。
{
"classifier_id" : "**********-nlc-****",
"name" : "TutorialClassifier",
"language" : "ja",
"created" : "2017-02-01T00:00:00.000Z",
"url" : "https://gateway.watsonplatform.net/natural-language-classifier/api/v1/classifiers/**********-nlc-****",
"status" : "Training",
"status_description" : "The classifier instance is in its training phase, not yet ready to accept classify requests"
}
トレーニングが開始されます。以下のコマンドでトレーニングの状態を確認することが可能です。
c:\>set USERNAME=********-****-****-****-************
c:\>set PASSWORD=***********
c:\>set CLASSIFIER_ID=**********-nlc-****

c:\>curl -k -u "%USERNAME%":"%PASSWORD%" "%APIURL%/%CLASSIFIER_ID%"
以下のような応答が返されます。
{
"classifier_id" : "**********-nlc-****",
"name" : "TutorialClassifier",
"language" : "ja",
"created" : "2017-02-01T00:00:00.000Z",
"url" : "https://gateway.watsonplatform.net/natural-language-classifier/api/v1/classifiers/**********-nlc-****",
"status" : "Available",
"status_description" : "The classifier instance is now available and is ready to take classifier requests."
}
status" : "Available" と表示されれば、投入したトレーニング用の csv のトレーニングが完了しているようです。
以上に関して、人間(要するに私)がトレーニングデータの生成に所要した時間は20分程度です。同等のアルゴリズムをC言語やJavaで作成し、メンテナンスしていく時間と比較すると圧倒的に低コストであることが分かるでしょう。

スポンサーリンク

質問する

実際に質問し、どの質問に分類されるか確認してみます。
その前にコマンドプロンプトの表示をUTF-8 に変更します。
質問1:「パスワードが分かりません」
トレーニングの文書と同じ質問をしてみます。かなりの高度で「RESET_PASSWORD」と判定されるはずです。
Windows の場合、コマンドプロンプトでUTF-8を扱うのは困難であるため、質問のファイルはc:\temp\question.txt にUTF-8で保存してcurl で送信することにしました。text="文字列"のように送信されると、Shift-jisを % エンコードされ送信されるため、正しい結果が表示されません。
参考:curl で urlencode してquerystring(パラメータ)を送信する場合の注意事項
ここではc:\temp\question.txtには"パスワードが分かりません"とUTF-8で保存しています。(ダブルクォートは無し)
c:\>set USERNAME=********-****-****-****-************
c:\>set PASSWORD=***********
c:\>set CLASSIFIER_ID=**********-nlc-****


c:\>curl -k -G -u "%USERNAME%":"%PASSWORD%" "%APIURL%/%CLASSIFIER_ID%/classify" --data-urlencode text@c:\temp\question.txt
成功すると以下のような結果が表示されます。1.0で"RESET_PASSWORD"と表示されているため、正確に分類されていることが分かります。
{
"classifier_id" : "**********-nlc-****",
"url" : "https://gateway.watsonplatform.net/natural-language-classifier/api/v1/classifiers/**********-nlc-****",
"text" : "パスワードが分かりません",
"top_class" : "RESET_PASSWORD",
"classes" : [ {
"class_name" : "RESET_PASSWORD",
"confidence" : 1.0

}, {
"class_name" : "PERMISSION_ERROR",
"confidence" : 0.0
}, {
"class_name" : "HOWTO_EXIT",
"confidence" : 0.0
}, {
"class_name" : "WHERE_LOGIN_URL",
"confidence" : 0.0
}, {
"class_name" : "FORGET_USERID",
"confidence" : 0.0
} ]
}* Curl_http_done: called premature == 0
* Connection #0 to host gateway.watsonplatform.net left intact
ここで text が文字化けする場合はコマンドプロンプトの表示が UTF-8に変更されていない可能性があります。
質問2:「パスワードを忘れてしまいましたので教えてください」
今度はちょっと質問の形式を変えてみました。
{
"classifier_id" : "**********-nlc-****",
"url" : "https://gateway.watsonplatform.net/natural-language-classifier/api/v1/classifiers/**********-nlc-****",
"text" : "パスワードを忘れてしまいましたので教えてください",
"top_class" : "RESET_PASSWORD",
"classes" : [ {
"class_name" : "RESET_PASSWORD",
"confidence" : 0.9820378548284615

}, {
"class_name" : "WHERE_LOGIN_URL",
"confidence" : 0.0106215083851753
}, {
"class_name" : "FORGET_USERID",
"confidence" : 0.003736533619975934
}, {
"class_name" : "PERMISSION_ERROR",
"confidence" : 0.0018583092797659646
}, {
"class_name" : "HOWTO_EXIT",
"confidence" : 0.0017457938866214213
} ]
}* Curl_http_done: called premature == 0
* Connection #0 to host gateway.watsonplatform.net left intact
先ほどよりは落ちますが、約 0.98 でRESET_PASSWORDと正しく判定されています。よって実際のアプリでは RESET_PASSWORD に対応した FAQ文(パスワード初期化の申請手順)を案内すればよいでしょう。
質問3:「どこから入れば良いですか?」
今度はちょっと変化球を投げてみます。
"classes" : [ {
"class_name" : "WHERE_LOGIN_URL",
"confidence" : 0.5677246779274869

}, {
"class_name" : "HOWTO_EXIT",
"confidence" : 0.3953622101726974
}, {
"class_name" : "RESET_PASSWORD",
"confidence" : 0.014041556967503087
}, {
"class_name" : "PERMISSION_ERROR",
"confidence" : 0.01146632991355667
}, {
"class_name" : "FORGET_USERID",
"confidence" : 0.011405225018755977
} ]
}* Curl_http_done: called premature == 0
* Connection #0 to host gateway.watsonplatform.net left intact
WHERE_LOGIN_URL が約0.567とまあまあ正しく判断されたようです。
このように数種類のサンプルをトレーニングするだけで、ある程度の質問文の分類が出来るようになりました。これと音声認識、自然言語処理などと組み合わせればコールセンターの受付係の方のFAQサポートなどに活用できるでしょう。
次のステップは追加の学習による改善です。

スポンサーリンク

[自然言語分類(NLC,Natural Language Classifier)に戻る]