Azure Machine Learning で Twitterのつぶやきデータから各アカウントの嗜好にあったアニメタイトルのリコメンドを行う

![スクリーンショット 2015-09-15 17.12.09.png](https://qiita-image-store.s3.amazonaws.com/0/36931/4f87b43a-5871-3621-3d92-fe3f31d3e215.png)

https://studio.azureml.net/
http://gallery.azureml.net/

#Azure Machine Learningとは？

Azure Machine Learning(AzureML)はマイクロソフトのAzureプラットフォームの内の機械学習サービスです（クラウドAI）。
機械学習のプログラムを書かなくてもデータをAzureMLに投入しモデルの定義だけすれば機械学習の機能が利用できます。
対抗馬として[Amazon Machine Learning](https://aws.amazon.com/jp/machine-learning/)がありますが、先行リリースしたAzureMLのほうが機能は豊富です。



![スクリーンショット 2015-09-15 17.52.46.png](https://qiita-image-store.s3.amazonaws.com/0/36931/27209f7d-74c3-7c96-3dc2-4b81a7b8213f.png)


*Azure Machine Learning Studio*でのモデリングの画面（ブラウザからモデリングできます）



## 対象のTwitterのデータ

8月15日から9月8日まで(24日分)の「2015年夏期クールのアニメ作品」に関するつぶやきデータ(**1100万レコード**)


![スクリーンショット 2015-09-15 18.09.04.png](https://qiita-image-store.s3.amazonaws.com/0/36931/c681d393-712a-6311-cd3f-86d6e4f5abc5.png)


![スクリーンショット 2015-09-15 18.08.20.png](https://qiita-image-store.s3.amazonaws.com/0/36931/2fd4663f-4cc3-2673-21de-51f903586a5d.png)

### TwitterのデータCSVをGoogle BigQueryのテーブルに変換

TwitterのデータはStreamingAPIでCSVに格納したものを用意します。

#### CSVの構造

| id| name |tweet_text| source| retweet_count |favorite_count|created_at|
|:-----------|:------------|:------------|:-----------|:------------|:------------|:------------|
| 640177573004079104       |        twitter_acount |    始まったー！！ #charlotte #シャーロット    |<a href="http://twitter.com/download/iphone" rel="nofollow">Twitter for iPhone</a> |        0 |         0 |     Sun Sep 06 00:00:01 JST 2015    |



次にデータベースに格納しSQLで集計するためにGoogle BigQueryを使用します。

#### Google BigQueryに読み込ませるDDL

|カラム名|形式|
|:------|:----|
|id|INTEGER|
|name|STRING|
|tweet_text|STRING|
|source|STRING|
|retweet_count|STRING|
|favorite_count|INTEGER|
|created_at|STRING|


Google BigQueryでCSVファイルを上げてテーブルに変換するまでは以下の記事に以前書いたので参考にしてください。

[Google BigQueryで今期アニメに関するツイートを分析するぞい！](http://qiita.com/AKB428/items/4c4eefff213201ce05e4)


### TwitterテーブルをAzureMLの協調フィルタリングに読み込ませるために「評価テーブル」に加工

AzureMLでリコメンドを行うため今回は「協調フィルタリング」のユーザーベースレコメンドという機械学習アルゴリズムを使用します。


AzureMLではこのようなデータ形式にする必要があります。

|ユーザー|商品|評価|
|:-----|:----|:---|
|User1|ポンカレー|4|
|User2|ポンカレー|2|
|User2|ジャバカレー|4|
|User3|インドカリー|5|

「誰がどの商品に何点評価したか？」というデータ形式です。（ユーザーと商品でユニークレコード）

これをツイッターのアニメデータに適用し「誰がどの作品について何回つぶやいたか？」というテーブル形式にします。
ただし、評点に差がありすぎたり、評点が大きすぎるとAzureMLでエラーがでるので評点は5にリミットをかけます。（100回つぶやいても評点は5）。何度か試した結果２０以上はスタックオーバーフローが出ました（データによるとは思いますが参考までに）。


|TwitterAccount|title|score|
|:-----|:----|:---|
|000kasyojudo|アイドルマスター シンデレラガールズ 2nd SEASON|1|
|000koma|下ネタという概念が存在しない退屈な世界|5|
|000koma|オーバーロード|5|
|000koma|がっこうぐらし|5|
|000ld|がっこうぐらし|2|
|000mikkel000|オーバーロード|5|


先ほどのTwitterのテーブルを評点データに加工するSQLは以下です。


```sql
SELECT
  name,
  title,
  IF(sum(score) > 5, 5,  sum(score) ) as score
FROM (
  SELECT
    name,
    title,
    1 AS score,
  FROM (
    SELECT
      name,
      CASE
        WHEN tweet_text CONTAINS '城下町のダンデライオン' OR tweet_text CONTAINS 'ダンデライオン'  OR tweet_text CONTAINS '城下町のダンデライオン' OR tweet_text CONTAINS '城下町のダンデライオン' OR tweet_text CONTAINS 'dande_anime' THEN '城下町のダンデライオン'
        WHEN tweet_text CONTAINS '六花の勇者' OR tweet_text CONTAINS '六花の勇者'  OR tweet_text CONTAINS '六花の勇者' OR tweet_text CONTAINS '六花の勇者' OR tweet_text CONTAINS 'rokka_anime' THEN '六花の勇者'       
        WHEN tweet_text CONTAINS '干物妹！うまるちゃん' OR tweet_text CONTAINS 'うまるちゃん'  OR tweet_text CONTAINS '干物妹！うまるちゃん' OR tweet_text CONTAINS '干物妹！うまるちゃん' OR tweet_text CONTAINS 'umaru_anime' THEN '干物妹！うまるちゃん'
        WHEN tweet_text CONTAINS 'がっこうぐらし' OR tweet_text CONTAINS 'がっこうぐらし'  OR tweet_text CONTAINS 'がっこうぐらし' OR tweet_text CONTAINS 'がっこうぐらし' OR tweet_text CONTAINS 'がっこうぐらし' THEN 'がっこうぐらし'
        WHEN tweet_text CONTAINS 'アイドルマスター シンデレラガールズ 2nd SEASON' OR tweet_text CONTAINS 'シンデレラガールズ'  OR tweet_text CONTAINS 'デレマス' OR tweet_text CONTAINS 'モバマス' OR tweet_text CONTAINS 'imas_cg' THEN 'アイドルマスター シンデレラガールズ 2nd SEASON'
        WHEN tweet_text CONTAINS 'GATE 自衛隊 彼の地にて、斯く戦えり' OR tweet_text CONTAINS 'ゲート'  OR tweet_text CONTAINS 'GATE' OR tweet_text CONTAINS 'GATE 自衛隊 彼の地にて、斯く戦えり' OR tweet_text CONTAINS 'gate_anime' THEN 'GATE 自衛隊 彼の地にて、斯く戦えり'
 　　WHEN tweet_text CONTAINS 'Charlotte(シャーロット)' OR tweet_text CONTAINS 'シャーロット'  OR tweet_text CONTAINS 'Charlotte(シャーロット)' OR tweet_text CONTAINS 'Charlotte(シャーロット)' OR tweet_text CONTAINS 'シャーロット ' THEN 'Charlotte(シャーロット)'
        WHEN tweet_text CONTAINS '監獄学園(プリズンスクール)' OR tweet_text CONTAINS 'プリズンスクール'  OR tweet_text CONTAINS '監獄学園(プリズンスクール)' OR tweet_text CONTAINS '監獄学園(プリズンスクール)' OR tweet_text CONTAINS 'プリズン' THEN '監獄学園(プリズンスクール)'
        WHEN tweet_text CONTAINS '下ネタという概念が存在しない退屈な世界' OR tweet_text CONTAINS '下セカ'  OR tweet_text CONTAINS '下ネタという概念が存在しない退屈な世界' OR tweet_text CONTAINS '下ネタという概念が存在しない退屈な世界' OR tweet_text CONTAINS 'shimoseka' THEN '下ネタという概念が存在しない退屈な世界'
　　 WHEN tweet_text CONTAINS 'オーバーロード' OR tweet_text CONTAINS 'オーバーロード'  OR tweet_text CONTAINS 'オーバーロード' OR tweet_text CONTAINS 'オーバーロード' OR tweet_text CONTAINS 'overlord_anime' THEN 'オーバーロード'
      ELSE NULL END AS title
    FROM [2015_C3a.2015_C7a] ) )
WHERE
  title IS NOT NULL group by name, title order by name

```

2015年夏期のアニメは40作品程度ありますが、数が多いと男女のアニメがまざったりするので今回は独断と偏見でメジャー作品と思われる作品タイトルに絞っています。


### 評点データCSVをGoogle Cloud Storageからダウンロード

出力結果のレコードは40万レコードあるのでGoogle BigQueryからデータを保存できません。
一度テーブルにデータを保存しGoogle Cloud Storageにエクスポートします。

![スクリーンショット 2015-09-15 19.42.07.png](https://qiita-image-store.s3.amazonaws.com/0/36931/7758fb9c-5ebf-0a26-6fbb-645610e1121e.png)

「Save as Table」を押下

![スクリーンショット 2015-09-15 19.42.26.png](https://qiita-image-store.s3.amazonaws.com/0/36931/1ed10c55-1189-af9e-de9b-32a54326ad83.png)

「Destination table」にテーブル名を記入



![スクリーンショット 2015-09-15 19.46.10.png](https://qiita-image-store.s3.amazonaws.com/0/36931/5f4eb086-9dce-e652-4acb-6187ed3647f5.png)

Export Tableを押下



![スクリーンショット 2015-09-15 19.46.52.png](https://qiita-image-store.s3.amazonaws.com/0/36931/40510d2f-105e-0f19-fd0d-f01f4df44208.png)

Google Cloud Storage にCSVファイルをエクスポートする。


### (参考) Azureプラットフォームなのに、あえてGoogle BigQueryを使う理由

![スクリーンショット 2015-09-15 19.49.39.png](https://qiita-image-store.s3.amazonaws.com/0/36931/5b4184af-4425-6ef9-4ab7-4bffd87598e4.png)

クラウドAIにデータを格納する場合、対象となる機械学習のアルゴリズムに合わせてデータを加工する必要は必ずあります。
対象がビッグデータの場合は通常のRDSでは処理がおいつかないため、Google BigQuery、Amazon Refshiftに代表されるMPPデータベースを使うのがベターです。しかしMicrosoftのAzureプラットフォームにはMPPデータベースは存在せず、SQL Serverを無理やり使うかHDInsight(Azure上で動くHortonworksのHadoop)を用意してHive or Sparkを使う必要があります。
Azure公式サイトによればHDInsightは20分でクリックインストールできるらしいですが、SQLをぶん投げたいためにわざわざHDInsightを構築するのは大げさです。


![スクリーンショット 2015-09-15 19.52.18.png](https://qiita-image-store.s3.amazonaws.com/0/36931/4633525f-29c1-e87b-d580-c4883a10c264.png)



http://azure.microsoft.com/ja-jp/services/hdinsight/


|クラウドAI|データ加工のために使うべきプラットフォーム|個人的お勧め度|
|:----------------------|:-------|:-----------------|
|Amazon Machine Learning|Redshift |(・∀・)|
|Azure Machine Learning|Google BigQuery|(・∀・)|
|Azure Machine Learning|Azure SQL Server|(´・ω・`)|
|Azure Machine Learning|Azure HDInsight|(´・ω・`)|




## Azure Machine Learning Studioに「評価テーブル」をアップロード

https://studio.azureml.net/
Azure Machine Learning Studioにログインします。

![スクリーンショット 2015-09-15 19.56.37.png](https://qiita-image-store.s3.amazonaws.com/0/36931/8f88cb85-974a-b185-0ee9-7a4ca4d913dc.png)
「my experiments」をクリック

![スクリーンショット 2015-09-15 19.57.37.png](https://qiita-image-store.s3.amazonaws.com/0/36931/bbff4f8d-3d10-09ed-f3ae-61c66e99c437.png)

左のサイドメニューの「DATASETS」をクリック


![スクリーンショット 2015-09-15 19.59.11.png](https://qiita-image-store.s3.amazonaws.com/0/36931/8aa628b6-b571-b93d-86d3-5bbeb6038cdc.png)


左下の「＋」をクリック



![スクリーンショット 2015-09-15 19.59.56.png](https://qiita-image-store.s3.amazonaws.com/0/36931/cc09b62a-eb25-99b8-4138-ebc13861aa08.png)

「FROM LOCAL FILE」をクリック


![スクリーンショット 2015-09-15 20.01.19.png](https://qiita-image-store.s3.amazonaws.com/0/36931/810a29aa-7e54-4aa2-b8ba-99318c57ad61.png)

ローカルのファイルを選択する。
DATA TYPEは拡張子から判定してるため、拡張子がないファイルを選択する場合は自分で選択する必要がある。



![スクリーンショット 2015-09-15 20.04.02.png](https://qiita-image-store.s3.amazonaws.com/0/36931/59f79c2b-726c-69c5-4a7d-edd0c67bdbe3.png)

アップロードすると下のバーに進捗が表示される。
ファイルを機械学習専用のデータ形式に変換しているためかはわからないがサイズに比べてかなりアップロードには時間がかかる。

completedが表示されるまで待つ。

![スクリーンショット 2015-09-15 20.06.03.png](https://qiita-image-store.s3.amazonaws.com/0/36931/a8e92d14-f539-a2c3-362b-bac7137ed206.png)


##Azure Machine Learning Studioでモデル作成、レコメンド


![スクリーンショット 2015-09-15 20.07.30.png](https://qiita-image-store.s3.amazonaws.com/0/36931/16beef2a-fa54-1005-0ccf-1cf1cb135a96.png)


左メニューから「EXPERIMENT」を選択し左下の「+」ボタンを押下

キャンバスが表示されるので以下のパーツをキャンバスに配置していく。

- ① Saved Datasets -> My Datasetsを選択し先ほどアップロードしたファイルを配置
- ② Machine Learning -> Train -> MatchBox Recommender
- ③ Data Transformation -> Manipulation -> Project Columns
- ④ Machine Learning -> Score -> Score MatchBox Recommender
- ⑤ Data Format Conversions -> Convert to CSV

配置したらこの絵のように紐づける


![スクリーンショット 2015-09-15 20.29.21.png](https://qiita-image-store.s3.amazonaws.com/0/36931/5c0c2e4a-63ee-aba3-0161-34a0e952afb9.png)

### 各種パーツの設定

#### MatchBox Recommender


![スクリーンショット 2015-09-15 20.36.42.png](https://qiita-image-store.s3.amazonaws.com/0/36931/a405fe7f-f3d9-b6ad-19e5-3fc9150557f6.png)
デフォルト設定のまま



#### Project Columns


![スクリーンショット 2015-09-15 20.34.31.png](https://qiita-image-store.s3.amazonaws.com/0/36931/2e64891a-be8b-288f-4884-4960a2802a9f.png)
Launch column selectorを押下



![スクリーンショット 2015-09-15 20.35.22.png](https://qiita-image-store.s3.amazonaws.com/0/36931/409fca9a-81b4-5829-8381-c74a6c8c24aa.png)
nameをカラムに指定


#### Score MatchBox Recommender



![スクリーンショット 2015-09-15 20.38.38.png](https://qiita-image-store.s3.amazonaws.com/0/36931/4983c04d-89ae-8a18-e6bf-0679a26549b9.png)

Recommended item selectionを「From All items」にする



### RUNを実行

キャンバスの配置と設定が終わったらRUNを押下し機械学習エンジンを実行します。
データ量が大きいのとテーブルの正規化をしていないこともありますが、40万レコード（40万ユーザー）に11商品のうち５商品を推薦するのに１０〜３０分程度かかります。
Azureのサーバーで動作しているのでブラウザを閉じても大丈夫です。時間がかかりそうだったらブラウザを一旦閉じましょう。


## レコメンドの結果確認


### Score MatchBox Recommenderで一部データを確認

Score MatchBox Recommenderを右クリックし「Scored dataset -> Visualize」を選択するとリコメンドの先頭データを閲覧できます。
Item1が一番そのアカウントに推薦すべき作品になります。

![スクリーンショット 2015-09-15 20.45.58.png](https://qiita-image-store.s3.amazonaws.com/0/36931/d4204a24-d63c-8122-e5a1-9e2584b1a1b6.png)



### CSVファイルをダウンロードして確認

「Convert to CSV」を選択し右クリックResult datasetをクリックしDownloadを選択しブラウザからダウンロード。

![スクリーンショット 2015-09-15 20.49.30.png](https://qiita-image-store.s3.amazonaws.com/0/36931/df649da3-4674-ffd7-e05f-f85810a23c0a.png)


![スクリーンショット 2015-09-15 20.57.53.png](https://qiita-image-store.s3.amazonaws.com/0/36931/3bda925f-ee93-28c3-eb3b-23934f2481a6.png)


協調フィルタリングでの推薦のため、あるユーザーが**「がっこうぐらし」**についてしかTwitterでつぶやいていなくても、**「アイドルマスター」**を第一推薦作品としてリコメンドできています。






## 作成したリコメンドデータの活用方法

作成したリコメンドモデルはそのままAzure　WEBサービスとしてデプロイでき、ユーザーIDを引数にリコメンドできたりしますが挙動が多少怪しいのとAzure APIサーバーは従量課金対象になるためあまりお勧めしません。

データをSQLサーバーにつっこんで自前で作ったリコメンドサーバー(SinatraとかPlayとか)がそれを読み込みAPIでJSONなどを返すというアプローチが今は安全でベストな方法だと思います。


## Azure MLの所感

機械学習の前提知識が多少は必要とはいえ、機械学習アルゴリズムを実装したエンジンを用意する必要がなく、データを突っ込んで
アルゴリズムを選択してブラウザでポトペタすればマイクロソフトの巨大AIインフラを利用できるのは素晴らしいと思います。
ブラウザでエンジンを起動すると３０分〜１時間待たされるのは旧世代の大型コンピューターのイメージ彷彿とさせます。

個人で強力な巨人の力（クラウドAI）を使える素晴らしい時代になったので、いい使い方をどんどん考案したいと思えるいいサービスだと思います。