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

最初に「何がやりたいのか」を書いておきます。例えば、
 「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 追記)
続きはこちらです。