はじめに
sklearn.clusterのKMeansでk平均法によるクラスタリングをすることができる。ここではsklearn.datasets.make_blobs
で作成したデータに対してクラスタリングを行う方法について説明する。
解説
モジュールのインポートなど
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
バージョン
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version
import matplotlib
print(matplotlib.__version__)
3.3.4
import sklearn
print(sklearn.__version__)
0.24.1
データの生成
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Generate sample data
n_samples = 1000
n_components = 5
X, y = make_blobs(n_samples=n_samples,
centers=n_components,
cluster_std=1,
random_state=10)
make_blobsによりデータを作成する。make_blobsについては下記記事で解説した。

データの塊の数を5とし、データのばらつき(標準偏差)を設定できるcluster_stdを1,random_stateを10とした。データを表示すると以下のようになる。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fig, ax = plt.subplots(dpi=140,figsize=(4,4))
ax.axis("equal")
plt.scatter(X[:, 0], X[:, 1], c=y, marker='o',alpha=0.5,s=55,linewidths=.1,edgecolor="k",cmap="turbo")
ax.set(xlabel="x",ylabel="y")
plt.savefig("kmeans_1_1.png",dpi=100)
plt.show()

クラスター数
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#n_clusters
n_clusters=5
kmeans_model_5 = KMeans(n_clusters)
n_clusters=10
kmeans_model_10 = KMeans(n_clusters)
fit_5 =kmeans_model_5.fit(X)
fit_10 =kmeans_model_10.fit(X)
y_5_ = fit_5.labels_
y_10_ = fit_10.labels_
Kmeans法ではクラスター数を自分で決める必要がある。ここでは、クラスター数を5と10にしたときの結果を示す。
KMeans(n_clusters)でモデルを設定する。設定したモデルに.fit(X)とすることでクラスタリングを行い、フィットした結果に.labels_とすることでラベルを得ることができる。
結果の表示
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fig, ax = plt.subplots(1,2,dpi=140,figsize=(8,4),sharex=True,sharey=True)
ax[0].set(xlabel="x",ylabel="y")
ax[0].scatter(X[:,0],X[:,1], c=y_5_,marker='o',alpha=0.5,s=55,linewidths=.1,edgecolor="k",cmap="turbo")
ax[0].scatter(fit_5.cluster_centers_[:,0],fit_5.cluster_centers_[:,1],s=60, marker='D',c='pink')
ax[0].set_title("n_clusters=5")
ax[1].set(xlabel="x",ylabel="y")
ax[1].scatter(X[:,0],X[:,1], c=y_10_,marker='o',alpha=0.5,s=55,linewidths=.1,edgecolor="k",cmap="turbo")
ax[1].scatter(fit_10.cluster_centers_[:,0],fit_10.cluster_centers_[:,1],s=60, marker='D',c='pink')
ax[1].set_title("n_clusters=10")
plt.savefig("kmeans_1_2.png",dpi=100)
plt.show()
cluster_centers_により、クラスタリングして最終的に収束した重心の位置の座標を得ることができる。

初期値
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#init
n_clusters=5
kmeans_model_pp = KMeans(n_clusters,init="k-means++",n_init=1,max_iter=1)
kmeans_model_random = KMeans(n_clusters,init="random",n_init=1,max_iter=1)
fit_p =kmeans_model_pp.fit(X)
fit_r =kmeans_model_random.fit(X)
y_p_ = fit_p.labels_
y_r_ = fit_r.labels_
クラスター中心の初期値をinitにより変更できる。デフォルトは”k-means++”で大体ちょうどいい位置に初期値が設定される。”random”はランダムに初期値が決定される。n_initは初期値を設定する回数でmax_iterは計算を行う回数となる。ここでは両方とも1として初期値の位置を確認する。
結果の表示
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fig, ax = plt.subplots(1,2,dpi=140,figsize=(8,4),sharex=True,sharey=True)
ax[0].set(xlabel="x",ylabel="y")
ax[0].scatter(X[:,0],X[:,1], c=y_p_,marker='o',alpha=0.5,s=55,linewidths=.1,edgecolor="k",cmap="turbo")
ax[0].scatter(fit_p.cluster_centers_[:,0],fit_p.cluster_centers_[:,1],s=60, marker='D',c='pink')
ax[0].set_title("init='k-means++'")
ax[1].set(xlabel="x",ylabel="y")
ax[1].scatter(X[:,0],X[:,1], c=y_r_,marker='o',alpha=0.5,s=55,linewidths=.1,edgecolor="k",cmap="turbo")
ax[1].scatter(fit_r.cluster_centers_[:,0],fit_r.cluster_centers_[:,1],s=60, marker='D',c='pink')
ax[1].set_title("init='random'")
plt.savefig("kmeans_1_3.png",dpi=100)
plt.show()

初期値がk-means++の時は計算回数1でもうまくクラスタリングができている。
randomの場合は初期値がランダムなので、1回の計算ではクラスタリングがうまくいっていないことがわかる。
収束の判断パラメータ tol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#tol
X, y = make_blobs(n_samples=n_samples,
centers=n_components,
cluster_std=2.5,
random_state=10)
n_clusters=5
kmeans_model_tole4 = KMeans(n_clusters,tol=0.0001)#default
kmeans_model_tole1 = KMeans(n_clusters,tol=0.1)
fit_4 =kmeans_model_tole4.fit(X)
fit_1 =kmeans_model_tole1.fit(X)
y_4_ = fit_4.labels_
y_1_ = fit_1.labels_
誤差がtolの値を下回った時に計算が終了する。ここではtol=0.1の場合とtol=0.0001でクラスタリングした結果を示す。
結果の表示
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fig, ax = plt.subplots(1,2,dpi=140,figsize=(8,4),sharex=True,sharey=True)
ax[0].set(xlabel="x",ylabel="y")
ax[0].scatter(X[:,0],X[:,1], c=y_4_,marker='o',alpha=0.5,s=55,linewidths=.1,edgecolor="k",cmap="turbo")
ax[0].scatter(fit_4.cluster_centers_[:,0],fit_4.cluster_centers_[:,1],s=60, marker='D',c='pink')
ax[0].set_title("tol=0.0001,Number of iterations="+str(fit_4.n_iter_)+"")
ax[1].set(xlabel="x",ylabel="y")
ax[1].scatter(X[:,0],X[:,1], c=y_1_,marker='o',alpha=0.5,s=55,linewidths=.1,edgecolor="k",cmap="turbo")
ax[1].scatter(fit_1.cluster_centers_[:,0],fit_1.cluster_centers_[:,1],s=60, marker='D',c='pink')
ax[1].set_title("tol=0.1,Number of iterations="+str(fit_1.n_iter_)+"")
plt.savefig("kmeans_1_4.png",dpi=100)
plt.show()
.n_iter_により計算回数を得ることができる。tolが0.0001の時の計算回数は6で、tolが0.1の時の計算回数は2回となっている。

参考


コメント