Python/Matplotlibでグラフを描いてみよう04(クラスタリング結果をグラフで可視化)

Python/Matplotlibでグラフを描いてみよう04(クラスタリング結果をグラフで可視化)

クラスタリングで分類した結果をグラフにしてみよう




k-meansで分類した結果でグラフを作成する方法

PythonでMatplotlibを使ったグラフ作成練習その4をやるよ。ナノネ、今回はクラスタリングの結果をグラフで可視化してみよう。

クラスタリングって、分類分けするやつだったよね。名前は知ってたけど、これまで使ったことなかったね。

クラスタリングは教師なし学習のひとつで、指定したクラスタ数でいい感じにデータを分類分けしてくれるよ。

クラスタリングにはskelearnのk-meanを使ってみよう。ただし、今回もグラフの作成練習がメインなのでクラスタリングの細かい説明は省略するね。

ラジャー。いつもパッケージをインポートしておくよ。データはまたIrisを使うんでしょ。

In [0]:
from sklearn import datasets
from sklearn import cluster
import matplotlib.pyplot as plt
%matplotlib inline
In [0]:
# ********************************
# 動作テスト環境 @2019/05
# ********************************
# Google Colaboratory
# Ubuntu 18.04.2 LTS
# Python 3.6.7
# :: matplotlib 3.0.3
# :: scikit-learn 0.21.1
In [0]:
iris = datasets.load_iris()
data = iris.data

クラスタリング結果をグラフに可視化

k-meansは任意のクラスタ数を指定するだけで、とりあえず簡単に実行できるよ。パラメータはいろいろあるみたいだけど、今回はデフォルトでエィッ!

In [4]:
n_clusters = 3
model = cluster.KMeans(n_clusters=n_clusters)
model.fit(data)
Out[4]:
KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,
       n_clusters=3, n_init=10, n_jobs=None, precompute_distances='auto',
       random_state=None, tol=0.0001, verbose=0)

これだけ??

分類結果のラベルはlabels_を参照すればOK。今回はクラスタ数に3を指定したから、0、1、2の3つに分類されているよ。

In [5]:
results = model.labels_ # クラスタのラベル
results
Out[5]:
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0,
       0, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0,
       0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 2], dtype=int32)

クラスタの重心もグラフに表示したいので、一応中身をチェック。重心はcluster_centers_を参照すればOK。

In [6]:
centers = model.cluster_centers_ # クラスタの重心
centers
Out[6]:
array([[6.85      , 3.07368421, 5.74210526, 2.07105263],
       [5.006     , 3.428     , 1.462     , 0.246     ],
       [5.9016129 , 2.7483871 , 4.39354839, 1.43387097]])

あとは分類結果をいつも作っている散布図でプロットすれば完成かな。

In [7]:
colors = ['red', 'blue', 'green']

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111)

for i in range(n_clusters):
  ax.scatter(data[:, 0][results==i], data[:, 1][results==i], color=colors[i], alpha=0.5)
  ax.scatter(centers[i, 0], centers[i, 1], marker='x', color=colors[i], s=300)

ax.set_title('k-means(Iris)', size=16)
ax.set_xlabel(iris.feature_names[0], size=14)
ax.set_ylabel(iris.feature_names[1], size=14)

plt.show()

ちゃんと3つに分けてくれたみたい。バツ(×)のところが、クラスタの重心だね。

SepalLength、SepalWidth、PetalLength、PetalWidthで6通りの軸の組み合わせがあるから、全部一辺にプロットしてみよう。

In [8]:
from sklearn import datasets
from sklearn import cluster
import matplotlib.pyplot as plt
%matplotlib inline

# *****************
# iris data    ****
# *****************
iris = datasets.load_iris()
data = iris.data
feature_names = iris.feature_names

# *****************
# k-means      ****
# *****************
n_clusters = 3
model = cluster.KMeans(n_clusters=n_clusters)
model.fit(data)
results = model.labels_
centers = model.cluster_centers_

# *****************
# Graph        ****
# *****************

# プロットするデータの組み合わせリスト
# 0:sepal length (cm) 1:sepal width (cm) 2:petal length (cm) 3:petal width (cm)
pattern = [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]] # 6通り(4Combi2)
colors = ['red', 'blue', 'green']

# plot
fig, ax = plt.subplots(2, 3, figsize=(10, 6)) # (2行3列でグラフ6個分)

for i in range(6):
  
  row = i // 3
  col = i % 3
  
  x_col_index, y_col_index = pattern[i] # プロットするデータの組み合わせ
  
  x = data[:, x_col_index] # x軸データ
  y = data[:, y_col_index] # y軸データ
                
  xlabel = feature_names[x_col_index] # x軸データ特徴名称
  ylabel = feature_names[y_col_index] # y軸データ特徴名称
                
  for cluster in range(n_clusters):
    # data plot(o)
    ax[row, col].scatter(
        x=x[results == cluster],
        y=y[results == cluster],
        color = colors[cluster],
        marker='o',
        alpha=0.2)
    
    # center plot(x)
    ax[row, col].scatter(
        centers[cluster, x_col_index],
        centers[cluster, y_col_index],
        color=colors[cluster],
        marker='x',
        s=300)
    
  ax[row, col].set_title('Graph-{}'.format(i+1), size=15)
  ax[row, col].set_xlabel(xlabel, size=12)
  ax[row, col].set_ylabel(ylabel, size=12)

plt.tight_layout()
plt.show()

クラスタリングを使ったグラフの作成練習は以上で。

今回はバッテンマークを付けただけだったような感じだけど。お疲れ様でした。またね!







スポンサーリンク

0 件のコメント :

コメントを投稿