機械学習の過程をD3.jsで可視化する

# 機械学習の過程をD3.jsで可視化する
## はじめに(お決まりのやつ)
こんにちは。
そしてはじめまして、dr_paradiです。
 [CYBIRDエンジニア Advent Calendar 2014 - Qiita](http://qiita.com/advent-calendar/2014/cybird)の12日目です。


CYBIRDエンジニアの昨日の記事は [SayakaIto](http://qiita.com/SayakaIto)さん(いつもお世話になっております)の[ルカによる福音書24章](http://qiita.com/SayakaIto/items/2c95c3c81d68a3290c85)でした。最近入った私としては昔のCYBIRDの話（というかITビジネス黎明期）のお話は非常に参考になります。

## 本日の要約
今回、私は[D3.js](http://d3js.org/)というわりと人気なJavaScriptライブラリを用いて、
代表的なクラスタリングアルゴリズムであるK-meansを可視化したお話をします。

ソースとデモはこちらです。

[Visualization of K-means](http://bl.ocks.org/keisuke-osone/099f07d2b967b4e29aef)
> [bl.ocks.org](http://bl.ocks.org/)を用いています。

## 自己紹介
フルスタックデータアナリスト(自称)として活躍中です。
１年前くらいのデータヴィジュアライゼーションハッカソンで[野球の守備の可視化アプリ](http://www.slideshare.net/keisukeosone/ss-27435588)を作成しました。

## データ可視化 (Data Visualization) について 
弊社のデータアナリストの仕事としては、

* 仮説立案 (どのようなデータからどのような知見が得られそうか)
* データ処理 (いわゆる集計とかマエショリ)
* 分析 (統計とか機械学習とか)
* アウトプット (レポートやアルゴリズムなど)

があります。
 
最後のアウトプットでデータを可視化し、レポートにまとめ、プレゼンテーションを行うため、可視化の善し悪しがデータ分析者の最終的な成果を大きく左右します。

いくら分析の精度や妥当性が高くとも可視化の出来次第で、提案が受け入れられないという事も大いにあります。 

参考: [悪い可視化の事例集](http://viz.wtf/)

## 機械学習について 
データ分析業務の中では、知識発見的なアプローチを求められる事もあり、

「ビッグデータからデータマイニングして」
※(いろいろなログを集めた大量のデータから教師なし学習で施策などに役立つ知識を出して欲しいという意味だと思われる)
と言われ、機械学習の利用を迫られることもままあります。


説明する側にとっても、説明を受ける側にとっても「機械学習」という言葉はなかなか威圧感があり、とっつきづらい印象があります。
そこで、可視化の力を借りて、アルゴリズムのイメージをしやすくしました。

概要を知らずに、「内容を知らないけどクラスタリング使って分析しました」と説明するよりは説得力が増すかと思います。

## クラスタリングの可視化
本題の機械学習の可視化の過程になります。
今回用いる、代表的なクラスタリングのアルゴリズムであるK-meansは、その名の通り与えられたデータを「K」個の重心(mean) をもつ集合(クラスタ)に分割する手法です。

今回作成したデモの場合は、入力データとしてランダムに選んだ3点を中心にガウス分布を生成します。
※現場でKは[ヒューリスティック](http://d.hatena.ne.jp/keyword/%A5%D2%A5%E5%A1%BC%A5%EA%A5%B9%A5%C6%A5%A3%A5%C3%A5%AF)に決めます。

![スクリーンショット 2014-12-09 10.37.54.png](https://qiita-image-store.s3.amazonaws.com/0/17505/9fad6619-fa9b-752f-d5b1-279925603fcb.png)

このサンプルデータを3つのクラスタに分けて行きます。

## K-meansの流れ
K-meansのアルゴリズムは以下の通りです。


1. 任意のクラスタ数Kを決めた後に各データに対してランダムでクラスタを割り振る(今回は3)
※ランダムじゃないアルゴリズムもあります。
![スクリーンショット 2014-12-09 10.38.04.png](https://qiita-image-store.s3.amazonaws.com/0/17505/f97bee5a-ce7b-337b-1751-943dbc446e79.png)



1. 各クラスタの重心を計算する(算術平均(ユークリッド距離))
![スクリーンショット 2014-12-09 10.38.12.png](https://qiita-image-store.s3.amazonaws.com/0/17505/3705167a-900c-74cc-80e2-47381e4c2797.png)



1. 各データに対して重心が最も近いクラスタに割り当て直す
![スクリーンショット 2014-12-09 10.38.22.png](https://qiita-image-store.s3.amazonaws.com/0/17505/0cabf668-af04-d41b-72b1-6502c4bac238.png)


1. 移動しなくなるまで2.3 を繰り返す
![スクリーンショット 2014-12-09 10.38.31.png](https://qiita-image-store.s3.amazonaws.com/0/17505/495efc7d-b877-8585-1727-79ecbd30fe41.png)


1. 移動しなくなったら終了
![スクリーンショット 2014-12-09 10.38.46.png](https://qiita-image-store.s3.amazonaws.com/0/17505/06a60ac9-05a1-c699-2772-1040678eba2c.png)

### 解説

発生する計算は上記の2番くらいで、難しい事はしていません。

```lang:kmeans.js
// ユークリッド距離の計算
distance = Math.sqrt(
    Math.pow((centroidArr[i - 1].x - d.x), 2) + 
    Math.pow((centroidArr[i - 1].y - d.y), 2)
);
```

ピタゴラスの定理さえできれば問題ないですね。

## まとめ
言葉で説明したり数式を眺めたりするよりは、理解するのが簡単だったかと思います。

実際の分析では、多次元情報をクラスタリングすることになるので、
簡単に可視化できませんが、デモのような二次元での可視化でも処理のイメージをつけるのは重要です。

また、あまりアルゴリズムの詳細を知らずにRやSPSSなどのライブラリを使っている方にとっても、どういった処理をしているかを理解する手助けになれば幸いです。

今後、入力などに気をつかって間違いを起こしづらくなること間違いありません。

実際の分析では、クラスタリングの出番が多くあります。
私が行った例では、とあるサービスのアンケートの分析を行う際に、
ユーザの属性を元にクラスタリングして、クラスタ毎の回答を形態素解析して頻度を抽出して実際の施策やキャンペーンの参考にすることができました。

## おわりに(お決まりのやつ)
 [CYBIRDエンジニア Advent Calendar 2014 - Qiita](http://qiita.com/advent-calendar/2014/cybird)は、[Satoshi_Nakamura](http://qiita.com/Satoshi_Nakamura)さんの記事です！
だいぶメジャーなネタに寄せてると話していたので、インフラについて熱く語ってくれる事間違いありません。