BluemixのRetrieve&Rankで日本語を試してみた

# Retrieve&Rankで(無理やり)日本語を使ってみた
Bluemixでは様々なWatson APIが使えるようになっているが、その中に質問に対して適切な回答を返してくれるAPIであるRetrieve&Rank(RR)というものがある。
が、現在まだ日本語が使えるのかどうかドキュメントを見てもわからなかったので無理やり使ってみた。

# 結局できたのか？
結論から言うとエラーは出ずに構成できて、それなりに動いているような気がする。が、本当にこれで大丈夫なのかはわからないので、正式な日本語対応のアナウンスを待つのが吉か。とにかくやってみたいという人がいるかもしれないので、参考までに書いておく。

# やっていること
RRのベースは[Apache Solr(ソーラー)](https://ja.wikipedia.org/wiki/Apache_Solr)である。ということで、Solrで日本語を使う場合のお作法をマネして設定ファイルを作って、それを使ってRRを構成してみたらなんとなく動いたっぽい、という話。ちなみにこの設定ファイルは私のまわりのすごいが作ってくれました。どうもありがとうございます。
設定ファイル作成手順をまとめるとこんな感じ。

1. サンプルのsolr-config(cranfield_solr_config.zip)を展開
2. schema.xmlを編集
3. 日本語用のストップワード、辞書ファイルを追加する
4. zipにまとめ、RR構成時のsolr-configとして使用する

## schema.xmlの編集
solrで日本語を使えるようにする方法は、[Google先生に聞いてみる](https://www.google.co.jp/search?q=solr+%E6%97%A5%E6%9C%AC%E8%AA%9E+schema.xml&ie=utf-8&oe=utf-8&gws_rd=cr&ei=QlleVuDZE4XlmAWZ2pnoCQ)といろいろ出てくる。例えば[こちら](http://shinodogg.com/?p=5920)とか[こちら](http://d.hatena.ne.jp/lettas0726/20110711/1310375789)とか参考になるのではないだろうか。
つまり何をしているかというと、

 - 日本語用のfieldTypeを定義する
 - 日本語を使うfieldのtypeに上記fieldTypeを設定
 - copyFieldを追加する
 - dynamicFieldを追加する

という感じ。

ということで、必要なとこだけ抜き出すと、サンプルのschema.xmlはこうなっていた。

```xml:BEFORE
  <field name="body" type="watson_text_en" indexed="true" stored="true" required="false" multiValued="true" />
  <copyField source="body" dest="text"/>
  <copyField source="body" dest="watson_text"/>
  <dynamicField name="*_en" type="text_en" indexed="true" stored="true" multiValued="true"/>
  <fieldType name="watson_text_en" indexed="true" stored="true" class="com.ibm.watson.hector.plugins.fieldtype.WatsonTextField">
      <analyzer type="index">
          <tokenizer class="solr.StandardTokenizerFactory"/>
          <filter class="solr.LowerCaseFilterFactory"/>
          <filter class="solr.EnglishPossessiveFilterFactory"/>
          <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
          <filter class="solr.PorterStemFilterFactory"/>
      </analyzer>
      <analyzer type="query">
          <tokenizer class="solr.StandardTokenizerFactory"/>
          <filter class="solr.StopFilterFactory"
          ignoreCase="true"
          words="lang/stopwords_en.txt"
          />
          <filter class="solr.LowerCaseFilterFactory"/>
          <filter class="solr.EnglishPossessiveFilterFactory"/>
          <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
          <filter class="solr.PorterStemFilterFactory"/>
      </analyzer>
  </fieldType>
```

これを、日本語対応にするには、以下のように変更・追加する。

```xml:AFTER
  <field name="body"     type="watson_text_ja" indexed="true" stored="true" required="false" multiValued="true" />
  <copyField source="body"    dest="text"/>
  <copyField source="body"     dest="watson_text"/>
  <fieldType name="watson_text_ja" indexed="true" stored="true" omitNorms="false" omitTermFreqAndPositions="false" storeOffsetsWithPositions="true" class="com.ibm.watson.hector.plugins.fieldtype.WatsonTextField" >
    <analyzer>
      <tokenizer class="solr.JapaneseTokenizerFactory" mode="search"/>
      <filter class="solr.JapaneseBaseFormFilterFactory"/>
      <filter class="solr.JapanesePartOfSpeechStopFilterFactory" tags="lang/stoptags_ja.txt"/> 
      <filter class="solr.CJKWidthFilterFactory"/>
      <filter class="solr.StopFilterFactory" words="lang/stopwords_ja.txt" ignoreCase="true"/> 
      <filter class="solr.JapaneseKatakanaStemFilterFactory" minimumLength="4"/>
      <filter class="solr.LowerCaseFilterFactory"/>
    </analyzer>
  </fieldType>

```

## ストップワードと辞書の登録
設定ファイルをながめていると、`lang/stoptags_ja.txt`とか`lang/stopwords_ja.txt`とか出てきた。これも入れないといけないらしい。
本家のsolrをダウンロードして展開した先の`example\files\conf\lang`以下に`stoptags_ja.txt`、`stopwords_ja.txt`があるのでこれらをコピーする。ついでに`userdict_ja.txt`も日本語設定っぽいのでコピーしておく。

## zipで圧縮
ここまで準備ができたら、zipしておく。名前は何でもいいので`japanese-config.zip`とかにしておけばいいんじゃないだろうか。

# RRの構成
作成した日本語設定ファイルを使ってRRを構成してみる。

## 日本語設定ファイルのロード
RRの構成でsolr-configを読み込ませるときに、作成した設定ファイルを渡す。

```shell
curl -k -X POST -H "Content-Type: application/zip" -u "<RRのユーザーID>:<パスワード>" "https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters/<クラスターID>/config/<config-name>" --data-binary @./japanese-config.zip
```

## コレクションの作成
あとはコレクション作成時にアップロードしたconfigを指定すればよい。

```shell
curl -k -X POST -H "Content-Type: application/zip" -u "<RRのユーザーID>:<パスワード>" "https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters/<クラスターID>/solr/admin/collections" -d "action=CREATE&name=<コレクション名>&collection.configName=japanese-config"
```

## ドキュメントのロード
こんな感じで作成したドキュメントをロードしてみる。

```shell
curl -k -X POST -H "Content-Type: application/json" -u "<RRのユーザーID>:<パスワード>" "https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters/<クラスターID>/<コレクション名>/update" --data-binary @./<ドキュメント名>
```

# 日本語検索のテスト
Rankerのトレーニングをしていないが、ひとまず日本語で問い合わせてみた。
ブラウザーから、以下のURLにアクセス。

```
https://<RRのユーザーID>:<パスワード>@gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters/<クラスターID>/solr/<コレクション名>/select?q=<質問文>&wt=json&fl=id,title
```

curlでやりたいなら以下のように入力。

```
curl -k -u "<RRのユーザーID>:<パスワード>"  "https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters/<solrクラスターID>/solr/<コレクション名>/select" --data-urlencod "q=Android&wt=json&fl=id,title,body"
```


回答が得られればひとまずOK。あとはRankerを作成してトレーニングして・・・となるのだけど、こっちの手順は英語も日本語も同じなのでこの記事では割愛。

# おわりに
動いたけれども、これで正しく日本語解析ができているかどうかはわからない。だけど、結果だけ見るとちゃんと動いているように感じる。でも公式なガイドが出るまでは安心できないね。

さて、ようやくRRの準備ができたのでRRを構成してRankerで問い合わせるところとか整理したい。