クラスタリング結果をビジュアライゼーション/評価する関数を作成

# クラスタリングした結果をビジュアライゼーションし、評価する

vaeなどでクラスタリングした結果をビジュアライゼーションし、評価値を表示する関数を実装した。

正解ラベルとクラスタリング結果であるクラスタ番号を多数決でリラベルし、
擬似的なconfusion matrixを描画、accuracyを計算する。
また、NMIとARIによる評価値も表示する。
どれだけうまくクラスタリングしたかを評価できる関数を作ったつもり。

```python
# 必要なライブラリのインポート
import numpy as np
import pandas as pd
import sklearn
# Jupyter notebookを利用している際に、notebook内にplot結果を表示するようにする
import matplotlib.pyplot as plt
%matplotlib inline
```


```python
df_result_dense = pd.read_csv('result-dense.csv')
df_result_dense
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>Unnamed: 0</th>
      <th>labels</th>
      <th>k-means</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>0</td>
      <td>7</td>
      <td>2</td>
    </tr>
    <tr>
      <th>1</th>
      <td>1</td>
      <td>2</td>
      <td>5</td>
    </tr>
    <tr>
      <th>2</th>
      <td>2</td>
      <td>1</td>
      <td>9</td>
    </tr>
    <tr>
      <th>3</th>
      <td>3</td>
      <td>0</td>
      <td>3</td>
    </tr>
    <tr>
      <th>4</th>
      <td>4</td>
      <td>4</td>
      <td>7</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>9995</th>
      <td>9995</td>
      <td>2</td>
      <td>5</td>
    </tr>
    <tr>
      <th>9996</th>
      <td>9996</td>
      <td>3</td>
      <td>0</td>
    </tr>
    <tr>
      <th>9997</th>
      <td>9997</td>
      <td>4</td>
      <td>7</td>
    </tr>
    <tr>
      <th>9998</th>
      <td>9998</td>
      <td>5</td>
      <td>4</td>
    </tr>
    <tr>
      <th>9999</th>
      <td>9999</td>
      <td>6</td>
      <td>6</td>
    </tr>
  </tbody>
</table>
<p>10000 rows × 3 columns</p>
</div>




```python
def relabel(ans, labels):
    df = pd.DataFrame()
    df['ans'] = ans
    df['labels'] = labels
    relabel(df, 'ans', 'labels')

def relabel(df, ans, label):
    # ansに一番近いラベリングをし直す
    # df[ans]に正答、df[labels]にクラスタラベルが入っていることを期待している
    labels = df[label].unique()
    label_dic = {}
    for i in labels:
        counts = df[df[label] == i][ans].value_counts()
        label_dic[i] = counts.index[0]
    display(label_dic)
    return list(pd.Series(df[label]).replace(label_dic))
```


```python
relabel_k_means = relabel(df_result_dense, 'labels', 'k-means')
df_result_dense['relabel_k_means'] = relabel_k_means
```


    {2: 7, 5: 2, 9: 1, 3: 0, 7: 4, 1: 9, 4: 5, 8: 8, 6: 6, 0: 3}



```python
from sklearn.metrics import accuracy_score
print(accuracy_score(df_result_dense['labels'],df_result_dense['k-means']))
print(accuracy_score(df_result_dense['labels'],df_result_dense['relabel_k_means']))
```

    0.1841
    0.9309



```python
ans = df_result_dense['labels']
labels = df_result_dense['k-means']
relabels = df_result_dense['relabel_k_means']
```


```python
def eval_cluster(ans, labels, relabels):
    import seaborn as sns
    from sklearn.metrics import confusion_matrix

    plt.title('no-relabel')
    sns.heatmap(confusion_matrix(ans, labels), annot=True, fmt='d')
    plt.show()

    from sklearn.metrics import normalized_mutual_info_score
    print("nmi: " + str(normalized_mutual_info_score(ans, labels)))
    from sklearn.metrics.cluster import adjusted_rand_score
    print("ari: " + str(adjusted_rand_score(ans, labels)))

    plt.title('relabel')
    sns.heatmap(confusion_matrix(ans, relabels), annot=True, fmt='d')
    plt.show()
    print("acc: " + str(accuracy_score(ans, relabels)))

```


```python
eval_cluster(ans, labels, relabels)
```


![output_7_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490869/8e8507a9-20df-cf89-c918-a3501b158521.png)



    nmi: 0.8804532777228216
    ari: 0.8405114317316403

![output_7_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490869/f0eecc4b-6042-c002-82a6-4ce6ffe08555.png)

    acc: 0.9309



```python

```