K-meansクラスタリング

2016年に作った資料を公開します。もう既にいろいろ古くなってる可能性が高いです。

* 本実習では教師なし学習の一種であるK-meansクラスタリングを行ないます。
    * K-means とは何か、知らない人は下記リンク参照↓
        * [K-平均法のアルゴリズム](http://image.slidesharecdn.com/02-kver2-0-110528032516-phpapp02/95/02-kver20-9-728.jpg) 
        * [クラスタリングの定番アルゴリズム「K-means法」をビジュアライズしてみた](http://tech.nitoyon.com/ja/blog/2009/04/09/kmeans-visualise/)

### まずはサンプルデータの取得から


```python
# URL によるリソースへのアクセスを提供するライブラリをインポートする。
import urllib
# ウェブ上のリソースを指定する
url = 'https://raw.githubusercontent.com/maskot1977/ipython_notebook/master/toydata/SchoolScore.txt'
# 指定したURLからリソースをダウンロードし、名前をつける。
urllib.urlretrieve(url, 'SchoolScore.txt')
```




    ('SchoolScore.txt', <httplib.HTTPMessage instance at 0x104143e18>)




```python
import pandas as pd # データフレームワーク処理のライブラリをインポート
df = pd.read_csv("SchoolScore.txt", sep='\t', na_values=".") # データの読み込み
```

### 得られたデータを確認します。全体像も眺めます。


```python
df.head() #データの確認
```




<div>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>Student</th>
      <th>Japanese</th>
      <th>Math</th>
      <th>English</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>0</td>
      <td>80</td>
      <td>85</td>
      <td>100</td>
    </tr>
    <tr>
      <th>1</th>
      <td>1</td>
      <td>96</td>
      <td>100</td>
      <td>100</td>
    </tr>
    <tr>
      <th>2</th>
      <td>2</td>
      <td>54</td>
      <td>83</td>
      <td>98</td>
    </tr>
    <tr>
      <th>3</th>
      <td>3</td>
      <td>80</td>
      <td>98</td>
      <td>98</td>
    </tr>
    <tr>
      <th>4</th>
      <td>4</td>
      <td>90</td>
      <td>92</td>
      <td>91</td>
    </tr>
  </tbody>
</table>
</div>




```python
df.iloc[:, 1:].head() #解析に使うデータは２列目以降
```




<div>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>Japanese</th>
      <th>Math</th>
      <th>English</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>80</td>
      <td>85</td>
      <td>100</td>
    </tr>
    <tr>
      <th>1</th>
      <td>96</td>
      <td>100</td>
      <td>100</td>
    </tr>
    <tr>
      <th>2</th>
      <td>54</td>
      <td>83</td>
      <td>98</td>
    </tr>
    <tr>
      <th>3</th>
      <td>80</td>
      <td>98</td>
      <td>98</td>
    </tr>
    <tr>
      <th>4</th>
      <td>90</td>
      <td>92</td>
      <td>91</td>
    </tr>
  </tbody>
</table>
</div>




```python
# 図やグラフを図示するためのライブラリをインポートする。
import matplotlib.pyplot as plt
%matplotlib inline
from pandas import plotting # 高度なプロットを行うツールのインポート
plotting.scatter_matrix(df[df.columns[1:]], figsize=(6,6), alpha=0.8, diagonal='kde')   #全体像を眺める
plt.show()
```


![output_6_0.png](https://qiita-image-store.s3.amazonaws.com/0/211162/8437f75d-37e9-8101-b38f-c6b5e49c6cad.png)


### さていよいよ K-means クラスタリングの実行です。

* たくさんの学生を、合計点ではなく、国語・数学・英語の学力が似ている３クラスタに分類してクラス分けをしたいと思います。


```python
from sklearn.cluster import KMeans # K-means クラスタリングをおこなう
# この例では 3 つのグループに分割 (メルセンヌツイスターの乱数の種を 10 とする)
kmeans_model = KMeans(n_clusters=3, random_state=10).fit(df.iloc[:, 1:])
```


```python
# 分類結果のラベルを取得する
labels = kmeans_model.labels_
```


```python
# 分類結果を確認
labels
```




    array([2, 2, 0, 2, 2, 1, 2, 2, 1, 2, 2, 2, 1, 2, 2, 0, 1, 2, 0, 0, 1, 0, 1,
           1, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1], dtype=int32)



これでいちおう結果は得られました。ですが、これだけ見せられてもピンとこないので、結果を図示しましょう。

### 分類結果を図示する。


```python
# それぞれに与える色を決める。
color_codes = {0:'#00FF00', 1:'#FF0000', 2:'#0000FF'}
```


```python
# サンプル毎に色を与える。
colors = [color_codes[x] for x in labels]
```


```python
# 色分けした Scatter Matrix を描く。
plotting.scatter_matrix(df[df.columns[1:]], figsize=(6,6), color=colors, alpha=0.8, diagonal='kde')   #データのプロット
plt.show()
```


![output_15_0.png](https://qiita-image-store.s3.amazonaws.com/0/211162/5b4afaac-2fd5-0307-f10a-3db5c851d227.png)


いちおう色分けされました。なんとなく学力の似ているクラスタに分かれたような気がしますが、これでもまだピンとこないかもしれません。

### 主成分分析をして、K-meansの結果をマッピングする。

```python
#import sklearn #機械学習のライブラリ
from sklearn.decomposition import PCA #主成分分析器
#主成分分析の実行
pca = PCA()
pca.fit(df.iloc[:, 1:])
```




    PCA(copy=True, n_components=None, whiten=False)




```python
# データを主成分空間に写像 = 次元圧縮
feature = pca.transform(df.iloc[:, 1:])
```


```python
# 第一主成分と第二主成分でプロットする
plt.figure(figsize=(6, 6))
for x, y, name in zip(feature[:, 0], feature[:, 1], df.iloc[:, 0]):
    plt.text(x, y, name, alpha=0.8, size=10)
plt.scatter(feature[:, 0], feature[:, 1], alpha=0.8, color=colors)
plt.title("Principal Component Analysis")
plt.xlabel("The first principal component score")
plt.ylabel("The second principal component score")
plt.show()
```


![output_19_0.png](https://qiita-image-store.s3.amazonaws.com/0/211162/6fcd296c-5398-3782-bd74-6540a2ac53ac.png)


K-meansでどのように分かれたか、これで（さっきよりは）はっきり分かったかもしれません。

----------
## 課題
新しいノートを開いて、以下の課題を解いてください。

* __課題1__:  下記リンクのデータを用い、１５０個のアヤメをK-means法で３つのクラスタに分類してください。
    https://raw.githubusercontent.com/maskot1977/ipython_notebook/master/toydata/iris.txt
* __課題2__: 分類結果を Scatter Matrix で確認してください。
* __課題3__: 分類結果を主成分分析で確認してください。
* __課題4__: クラスタ数を４つや５つなどに変更するとどうなるか確認してください。


```python

```