まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:language

先日、IBM Bluemix から提供されている IBM Watson の翻訳 API である "Language Translator" サービスが待望の日本語対応を果たしました。現在、日本語翻訳機能としては英語→日本語、および日本語→英語のテキスト翻訳が可能になっています:
2016122808


この翻訳 API は文章の翻訳に加え、入力されたテキストが何語のテキストなのかを識別する機能も備えています。実際にどんな言語翻訳ができるのか、そのサンプル的なアプリケーションが以下で公開されているので、興味ある方は試してみてください:
https://language-translator-demo.mybluemix.net/

2016122809



さて、この IBM Watson 翻訳 API の特徴の1つが「カスタマイズ機能」です。デフォルトで提供される翻訳機能をベースに、自分なりのカスタマイズを加えることができるようになっています。これは日本語翻訳機能においても有効な機能です。

というわけで、早速カスタマイズを試してみましょう。ただし、このカスタマイズを使うには、Language Translator サービスは標準プランではなく、拡張プランを選択する必要があります。標準プランには無料枠が用意されていますが、拡張プランにはありません。サインアップから 30 日間の無料期間を過ぎていたり、既に有償プランに移行済みの場合は、サービスインスタンスを作成した段階でインスタンス料金が発生しますので、ご注意ください:
2016122801


では「拡張プラン」を選択していることを確認した上でインスタンスを「作成」します:
2016122802


こうして拡張プランの Language Translator サービスインスタンスを作りました。この後、実際に API を使うことになるので「サービス資格情報」の「資格情報の表示」からクレデンシャル情報を調べてメモしておいてください(繰り返しですが、拡張プランの資格情報です。流出すると勝手に使われて課金額がどんどん増えていくことになるので、取扱いに注意してください):
2016122803


次に実際にカスタマイズする内容を TMX(Transaction Memory eXchange) という翻訳メモリデータの標準フォーマットである XML ファイルで用意します。今回は以下の内容の osaka.tmx ファイルを手元で作って用意しました:
<tmx version="1.4">
  <header
    creationtool="MyTool" creationtoolversion="1.00"
    datatype="PlainText" segtype="sentence"
    adminlang="en-ja" srclang="en"
    o-tmf="MyTransMem"/>
  <body>
    <tu>
      <tuv xml:lang="en">
        <seg>Hello</seg>
      </tuv>
      <tuv xml:lang="ja">
        <seg>もうかりまっか</seg>
      </tuv>
    </tu>
    <tu>
      <tuv xml:lang="en">
        <seg>I am fine</seg>
      </tuv>
      <tuv xml:lang="ja">
        <seg>ぼちぼちでんな</seg>
      </tuv>
    </tu>
  </body>
</tmx>

(かなり偏見入ってますが・・)大阪弁のカスタマイズをするためのファイルです。英語の "Hello" を「もうかりまっか」に、"I am fine" を「ぼちぼちでんな」に変換する、という内容です。これを元々の英→日翻訳機能に上書きする形でカスタマイズする、という意味です。なお日→英の翻訳カスタマイズは今回の説明には含めませんが、同様にして(同様の TMX ファイルを別途用意する形で)カスタマイズすることは可能です。


これでカスタマイズの準備はできました。 が、カスタマイズの前に、カスタマイズ前の挙動を確認しておきます(後でカスタマイズ後の挙動と比較するためです)。ここからは curl コマンドを使って実際に API を使ってみるので、必要に応じてここなどから curl コマンドをインストールしておいてください。

まず最初に、Language Translator がデフォルトで用意しているモデル(日英とか、英日とか、英仏とか、・・)の一覧を取得してみます(username と password には上記の資格情報で取得したものを指定します。また黒字が入力コマンド、青字が出力結果です):
$ curl -u "username:password" "https://gateway.watsonplatform.net/language-translator/api/v2/models"

{
  "models":[
    {
      "model_id":"ar-en",
      "source":"ar",
      "target":"en",
      "base_model_id":"",
      "domain":"news",
      "customizable":true,
      "default_model":true,
      "owner":"",
      "status":"available",
      "name":"",
      "train_log":null
    },
      :
    {
      "model_id":"en-ja",
      "source":"en",
      "target":"ja",
      "base_model_id":"",
      "domain":"news",
      "customizable":true,
      "default_model":true,
      "owner":"",
      "status":"available",
      "name":"",
      "train_log":null
    },
      :
    {
      "model_id":"ja-en",
      "source":"ja",
      "target":"en",
      "base_model_id":"",
      "domain":"news",
      "customizable":true,
      "default_model":true,
      "owner":"",
      "status":"available",
      "name":"",
      "train_log":null
    },
      :
  ]
}

モデルの一覧が JSON 配列形式で出力されます。"model_id" の値が実際に翻訳する時やこの後のカスタマイズ時に翻訳の種類を指定する値になります。英日であれば "en-ja" 、日英であれば "ja-en" という値になります。

また各モデルの中に "customizable" という値があります。これは「このモデルをカスタマイズ可能か」を示した値であり、true になっているとカスタマイズ可能であることを示しており、このモデルに上書きする形でのカスタマイズが可能です(英日、日英ともに true です)。また "status" の値は現時点で利用可能な状態になっているかどうかを示しています(これも英日、日英ともに "available" となっているので使える状態になっています)。

ではカスタマイズ前の翻訳機能を試してみましょう。英語の "Hello" を日本語に翻訳してみます:
$ curl -u "username:password" "https://gateway.watsonplatform.net/language-translator/api/v2/translate?model_id=en-ja&text=Hello"

こんにちは

カスタマイズ前(model_id に既存の en-ja を指定)なので、期待通りの結果になりました。

ではここからはカスタマイズを加えてみましょう。上記で用意した osaka.tmx を指定して、以下のコマンドを実行します:
$ curl -u "username:password" -X POST -F base_model_id="en-ja" -F forced_glossary=@osaka.tmx "https://gateway.watsonplatform.net/language-translator/api/v2/models"

{
  "model_id":"be81b082-1292-47ac-badf-0beb83846f66",
  "source":"en",
  "target":"ja",
  "base_model_id":"en-ja",
  "domain":"news",
  "customizable":false,
  "default_model":false,
  "owner":"da0dc7f3-87c6-4d82-b965-79b463266291",
  "status":"dispatching",
  "name":null,
  "train_log":null
}

基本モデル(base_model_id)を英日(en-ja)にして、そこに osaka.tmx で指定した内容を上書きでカスタマイズする、という内容のコマンドです。実行結果には新しい model_id (be81b082-1292-47ac-badf-0beb83846f66)が付与されて返っています。また customizable 値は false になっているので、このモデルをベースに更にカスタマイズ、ということはできません。status は "dispatching" となっているので、この時点ではまだ内部処理中です。

少し待ってから再度ステータスを確認し、"available" となっていることを確認できたら翻訳も可能になります。
$ curl -u "username:password" "https://gateway.watsonplatform.net/language-translator/api/v2/models/be81b082-1292-47ac-badf-0beb83846f66"

{
  "model_id":"be81b082-1292-47ac-badf-0beb83846f66",
  "source":"en",
  "target":"ja",
  "base_model_id":"en-ja",
  "domain":"news",
  "customizable":false,
  "default_model":false,
  "owner":"da0dc7f3-87c6-4d82-b965-79b463266291",
  "status":"available",
  "name":null,
  "train_log":null
}

また、この段階でモデル一覧を再確認すると、カスタマイズしたこのモデルも一覧の先頭に含まれて表示されることがわかります:
$ curl -u "username:password" "https://gateway.watsonplatform.net/language-translator/api/v2/models"

{
  "models":[
    {
      "model_id":"be81b082-1292-47ac-badf-0beb83846f66",
      "source":"en",
      "target":"ja",
      "base_model_id":"en-ja",
      "domain":"news",
      "customizable":false,
      "default_model":false,
      "owner":"da0dc7f3-87c6-4d82-b965-79b463266291",
      "status":"available",
      "name":null,
      "train_log":null
    },
    {
      "model_id":"ar-en",
      "source":"ar",
      "target":"en",
      "base_model_id":"",
      "domain":"news",
      "customizable":true,
      "default_model":true,
      "owner":"",
      "status":"available",
      "name":"",
      "train_log":null
    },
      :
    {
      "model_id":"en-ja",
      "source":"en",
      "target":"ja",
      "base_model_id":"",
      "domain":"news",
      "customizable":true,
      "default_model":true,
      "owner":"",
      "status":"available",
      "name":"",
      "train_log":null
    },
      :
    {
      "model_id":"ja-en",
      "source":"ja",
      "target":"en",
      "base_model_id":"",
      "domain":"news",
      "customizable":true,
      "default_model":true,
      "owner":"",
      "status":"available",
      "name":"",
      "train_log":null
    },
      :
  ]
}

ではこのカスタマイズモデルを model_id に指定して、先程と同じ英語を翻訳してみます:
$ curl -u "username:password" "https://gateway.watsonplatform.net/language-translator/api/v2/translate?model_id=be81b082-1292-47ac-badf-0beb83846f66&text=Hello"

もうかりまっか

期待通りのカスタマイズが有効な変換結果になりました。なお "I am fine" でもカスタマイズした結果が翻訳されますが、それ以外の(カスタマイズしていない)テキストについてはベースとなっている英日翻訳が有効になって実行されます:
$ curl -u "username:password" "https://gateway.watsonplatform.net/language-translator/api/v2/translate?model_id=be81b082-1292-47ac-badf-0beb83846f66&text=I%20am%20fine"

ぼちぼちでんな

$ curl -u "username:password" "https://gateway.watsonplatform.net/language-translator/api/v2/translate?model_id=be81b082-1292-47ac-badf-0beb83846f66&text=Good%20evening"

こんばんは

カスタマイズモデルが不要になった場合は以下のコマンドで削除することができます:
$ curl -u "username:password" -X DELETE "https://gateway.watsonplatform.net/language-translator/api/v2/models/be81b082-1292-47ac-badf-0beb83846f66"

{"status":"OK"}

今回紹介したのはごくシンプルなカスタマイズでしたが、より多くの語彙を用意できれば方言や、或いは全く新しい言語の翻訳機能まで実現することができるかもしれません。そんなカスタマイズ機能が IBM Watson の Language Translator API には提供されている、という紹介でした。


なお、Language Translator API の詳しい関数リファレンスはこちらを参照ください:
https://www.ibm.com/watson/developercloud/language-translator/api/v2/

実際に挙動をためせる Watson API Explorer はこちら:
https://watson-api-explorer.mybluemix.net/apis/language-translator-v2#/


#TMX をもう少し楽に作れるツールとかないかな・・・


前回の続きです。

前回は機械学習のための日本語学習コンテンツを 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


久しぶりに壮大な規模とテーマのブログに挑戦します。

最初に「何がやりたいのか」を書いておきます。例えば、
 「mongoDBっていいよね」
という日本語テキストを与えた時に、
 「それはオープンソースソフトウェアの話ですね」
と、何の話題についてのテキストだったのかを分類して答えてくれるような仕組みを作ります:
2015093001


Bluemix や Watson について、ある程度ご存知の方であれば気付かれたかもしれませんが、これを IBM のコグニティブエンジンを使って実装します。なので、実際には、
 「mongoDBっていいよね」
という日本語テキストを与えた時に、
 「それはオープンソースソフトウェアの話ですね(40%)」
 「あ、ウェブ開発の可能性もあります(30%)」
 「もしかするとクラウドの話題ですか?
(20%) それとも Linux?(10%)」
といった、他の可能性についても数値の根拠を出した上で候補を羅列してくれるような、そんな仕組みを作ってみようと思います:
2015093002


この仕組の実現には IBM Bluemix から提供されている Watson サービスの NLC(Natural Language Classifier) API を使います:
2015093003


NLC はテキストで与えられた文章の内容に対して、事前に定義(学習)したいくつかの分類クラスの中からマッチするものを選んで返してくれる、という API です。特徴としては、この「事前に定義(学習)」を自分で行うことができることと、日本語にも対応しているということが挙げられます。

作業としては、以下の3段階に分けておこないます:
(1) 学習させるデータを収集する
(2) 収集データを学習させる
(3) 実際に利用する


今回のエントリでは (1) までを行います(というか、準備します)。


さて、今回の目的は、どんな質問にもうまく分類してこたえてくれる万能ロボットを作るつもりはなく、あくまで「IT 系の会話を、どんな IT カテゴリの会話だったのか」に分類してくれるロボットを作ろうと思います。そのためには以下の2つが必要です:
[A] 会話の回答となるようないくつかのカテゴリの選定と、
[B] 各カテゴリのことを機械学習させるためのコンテンツ

例えば [A] で「Linux のことを勉強させたい!」と選ぶのであれば、どんな内容だったら Linux に関連していると判断できるのか?を学ばせるためのコンテンツが必要になる、という意味です。「Java のことも勉強させたい」のであれば、加えて Java を学ぶためのコンテンツが必要になります。 このカテゴリをどう決めて、各学習コンテンツをどうやって入手するか、というのが課題となります。

実際のビジネスで、業務データがある程度保存されているのであればそこから取り出して、業務のことを機械学習させる、というのがいいと思っています。ただ今回は「IT 系の会話」という、ある意味で一般的な内容なので、この一般的な内容をどこから取り出すか、という問題に直面します。 特にこういうブログで一般的な内容として紹介する際の高いハードルになったりします。

今回は(勝手にw)IBM developerWorks に協力してもらうことにしました。オープンな技術情報やサンプルコードなどを紹介するポータルサイトです。


特にこのページを見ると、いくつかのテクノロジーカテゴリごとの技術記事の RSS が提供されていることが分かります:
2015093004

(各 RSS フィードのリンク先(この例は Java technology))
2015093005


この仕組みを(勝手にw)使わせていただきます。要は IBM developerWorks  から提供されるいくつかのカテゴリごとの RSS を元に、(Java とか Linux とかモバイルとかの)カテゴリ毎の記事内容を取り出して、機械学習用コンテンツを作ることにします。

詳しくは次回紹介予定ですが、今回作る学習コンテンツは以下のような2列の CSV フォーマットで作ります:
学習コンテンツテキスト,カテゴリ


1列目の学習コンテンツテキストには、2列目のカテゴリについて学習させるためのテキストを記載します(例えばカテゴリが Java だとしたら、Java について書かれたテキスト)。必然的にある程度長いテキストになることが多いのですが、今回使う NLC API の仕様上、1文字以上1024 文字以下である必要があります。そして1度に学習させることができるコンテンツは5以上10000未満(つまり CSV 5 行以上 10000 行未満)という制約もあります。また CSV というフォーマットの特性上、学習コンテンツに改行やカンマを含めることはできません。細かくはもう少しありますが、今回の作業で問題になるとしたらこの辺りかなと思ってます。

なお、NLC の仕様についてはこちらのドキュメントを参照ください:
http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/nl-classifier/


この機械学習用コンテンツを上記の IBM developerWorks RSS から作ってしまおう、というのが今回のエントリの目的です。具体的にはこんな感じの PHP を作りました。これを PHP ウェブサーバーに(Bluemix であれば IBM DevOps Services や cf コマンドラインツールを使って)プッシュします:
<?php
// RSS を取得する対象
$sites = array( "opensource", "java", "cloud", "linux", "xml", "mobile" );

// 強制ダウンロード指定
header( 'Content-Type: application/force-download;' );
header( 'Content-Disposition: attachment; filename="dwj.csv"' );

for( $i = 0; $i < count( $sites ); $i ++ ){
  // RSS の URL
  $url = "http://www.ibm.com/developerworks/jp/views/" . $sites[$i] . "/rss/libraryview.jsp";
  
  $rss = file_get_contents( $url );
  $xml = simplexml_load_string( $rss );
  $items = $xml->channel->item;
  for( $j = 0; $j < count( $items ); $j ++ ){
    $item = $items[$j];
    $description = $item->description;

    // カンマを大文字に&改行を無視
    $description = str_replace( ",", ",", $description );
    $description = str_replace( "\n", "", $description );
    $description = str_replace( "\r", "", $description );

    $len = mb_strlen( $description );
    if( $len > 0 ){
      // $description が 1024 文字を超えていたら強制的に切る
      if( $len > 1024 ){
        $description = mb_substr( $description, 0 , 1024 );
      }

      // CSV のレコードを作成
      $line = $description . "," . $sites[$i] . "\n";
      echo $line;
    }
  }
}
@ob_flush();
@flush();
exit();
?>

一応、内容を紹介しておくと、IBM developerWorks のオープンソース(opensource)、Java(java)、クラウド(cloud)、Linux(linux)、XML(xml)、そしてモバイル(mobile)の各カテゴリごとに RSS の description の内容を取り出します。そしてその中身が1文字以上1024文字以内であれば、カテゴリ名を併せて CSV の1行となって出力される、というものです(1024文字を越えた場合は対象にしていませんが、今回の RSS では超えることがないので問題ないと思っています。ただ1024文字を超える可能性のあるコンテンツを扱う可能性がある場合は、(例えば1024文字で切るなどして)対処した上で出力する、といった改良をする必要があります)。このスクリプトがブラウザから呼び出された時に強制的に(CSV の)ダウンロードになるよう、HTTP ヘッダも調整しています。


そして、同 PHP ファイルをブラウザから呼び出すと、dwj.csv という CSV ファイルが動的に作成され、ダウンロードが始まります:
2015093006


ダウンロードした dwj.csv が目的の機械学習コンテンツになっています:
2015093007


これで上記の (1) 部分が揃いました。オープンソース、Java、クラウド、Linux、XML、そしてモバイル。6つのカテゴリごとに約100件ずつの日本語コンテンツ概要を得ることができました。次回はこれを機械学習させて、その上で日本語で IT 関連のメッセージを問いかけた際に、それが正しく分類されるかどうかを実際に確認して見る予定です。


(2015/Oct/02 追記)
続きはこちらです。



自分は自己紹介する時に「言語マニア」である、ということがあります。

ある程度モノにしている言語は日本語と英語。読むだけなら韓国語とフランス語、かじった程度ではアラビア語。かじった直後に断念したのがヒエログリフ(象形文字)。 言語という意味では更に加えて Java, PHP, JavaScript, C, C++, (Visual)Basic, LotusScript, Perl, Pascal, Fortran, CASL,  ... あたりのプログラミング言語も使えます。が、今回は前者の話です。

最近はウェブの翻訳サービスを使うことも多いのですが、外国語を勉強するには実際に使うのが近道だと思ってます。英語のアルファベットはパソコンで普通に入力できますが、フランス語アルファベットには特殊な表記をするものがあったり、韓国語のハングルに至っては普通には入力できません(よね?)。どうせならパソコンでも勉強中の文字入力をできるようにして、それらの言語でパワポの資料を作ってみたりできるとカッコいいです。


というわけで、Windows パソコンで日本語/英語以外の文字が入力できるようにするための設定方法を紹介します。ちなみに多言語入力は Windows XP 以降から標準機能として可能になっていますが、以下の紹介画面は Windows 7 です。


まずコントロールパネルを開き、「地域と言語」を選択します:
2015071901


「キーボードと言語」タブから「キーボードの変更」ボタンをクリックします:
2015071902


「全般」タブの「インストールされているサービス」には現在使うことのできる、英語以外の言語サービスの一覧が表示されます(画面では日本語だけです)。ここに韓国語を追加してみます。「追加」ボタンをクリックします:
2015071903


「韓国語」 - 「キーボード」 - 「Microsoft IME」にチェックを入れて「OK」ボタンをクリックします:
2015071904


先ほどの画面に戻り、「インストールされているサービス」に「韓国語」が追加されていることを確認します。必要であれば、同様に他の言語も追加します。最後に「適用」ボタンをクリックしてから「OK」ボタンをクリックします。これで準備は完了です:
2015071905


では実際に韓国語を入力してみます。メモ帳を起動しておきます:
2015071906


ここでキーボードの 左Alt + Shift を押す度に使用言語が切り替わっていくはずです。韓国語を入力するには図のように "KO" と書かれた表記になるまで切り替えます。これでハングル入力モードになりました:
2015071907


日本語入力モードでも日本語と英語を切り替えて入力するように、ハングル入力モードでも同様の切り替えを意識する必要があります。ハングル入力モードで 右Alt を押す度にハングルと英語の切り替えができます。ハングルを入力する場合は「A」ではなく「가」という表記に切り替えます。
2015071908


この状態でメモ帳内で適当にキーボードを叩くと、ハングルが入力されていくはずです(ちなみにこの内容は適当に打っただけなので意味無いです):
2015071909


キーボード配列をまだ覚えていない場合はソフトウェアキーボードを参照することも可能です。そのためにはまずソフトウェアキーボードを有効にする必要があります。言語バーの▼印をクリックし、メニューから "Soft Keyboard" にチェックを入れます:
2015071910


チェックすると言語バーにソフトウェアキーボードボタンが現れます:
2015071911


ここをクリックすると画面内にソフトウェアキーボードが表示され、ここからハングルを入力することもできますし、このキーボード配列を参照しながら目的の文字をキーボード入力する(ための勉強をする)こともできます:
2015071912


同様にしてアラビア語なども導入し、言語を切り替えて入力することで多言語テキストを作成することも可能です。ちなみにアラビア語はちゃんと(?)右から左に入力されていきます:
2015071913


実際問題として、たまに外国人が日本語のローマ字変換でパワポの資料を作っているのを目の当たりにすると、それだけで尊敬してしまいます。ただでさえ難しい外国語である日本語を、それもローマ字変換とか・・・ そんな感じで自分も色んな言語が操れるようになったらいいなあ、と思ってます。


余談ですが、この多言語テキストが標準機能として入力できるようになったのは Windows XP からでした。当時アラビア語を勉強していた自分にとって Windows XP は神 OS でした。開発者としてはシステムデバッグが楽な Windows 2000 も気に入っていたのですが、この機能を知って乗り換えを決意したものでした。


このページのトップヘ