<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 第11章 クラスタ分析 - ラベルなしデータの分析
https
Step1:  k-means法の手続き
クラスタの中心の初期値として、サンプル点からk個のセントロイドをランダムに選び出す
各サンプルを最も近いセントロイドμ(i)に割り当てる
セントロイドに割り当てられたサンプルの中心にセントロイドを移動する
サンプル点へのクラスタの割り当てが変化しなくなるか、ユーザー定義の許容値またはイテレーションの最大回数に達するまで、ステップ2〜3を繰り返す
Step2:  11.1.1 k-means++ 法
Step3:  11.1.2 ハードクラスタリングとソフトクラスタリング
11.1.1 エルボー法を使ってクラスタの最適な個数を求める
Step4:  11.1.4 シルエット図を使ってクラスタリングの性能を数値化する
シルエット分析(silhouette analysis)
シルエット係数(silhouette coefficient)
Step5:  11.2 クラスタを階層木として構成する
階層的クラスタリング(hierarchical clustering)
樹形図(dendrogram)
2つのアプローチ
凝集型(agglomerative)
単連結法(single linkage)
完全連結法(complete linkage)
分割型(divisive)
Step6:  11.2.1 距離行列で階層的クラスタリングを実行する
Step7:  11.2.2 樹形図をヒートマップと組み合わせる
Step8:  11.3 DBSCANを使って高密度の領域を特定する
DBSCAN(Density-based Spatial Clustering of Applications with Noise)
コア点(core point)
ボーダー点(border point)
ノイズ点(noise point)
<ASSISTANT_TASK:>
Python Code:
# 単純な2次元のデータセットを生成する
from sklearn.datasets import make_blobs
X, y = make_blobs(n_samples=150,   # サンプル点の総数
                  n_features=2,    # 特徴量の個数
                  centers=3,       # クラスタの個数
                  cluster_std=0.5, # クラスタ内の標準偏差
                  shuffle=True,    # サンプルをシャッフル
                  random_state=0)  # 乱数生成器の状態を指定
import matplotlib.pyplot as plt
plt.scatter(X[:, 0], X[:, 1], c='white', marker='o', s=50)
plt.grid()
plt.show()
Explanation: 第11章 クラスタ分析 - ラベルなしデータの分析
https://github.com/rasbt/python-machine-learning-book/blob/master/code/ch11/ch11.ipynb
よく知られている k-means(k平均法)を使って類似点の中心を見つけ出す
階層的クラスタ木をボトムアップ方式で構築する
密度に基づくクラスタリングアプローチを使ってオブジェクトの任意の形状を識別する
11.1 k-means 法を使った類似度によるオブジェクトのグループ化
k-means法(k-means algorithm)
プロトタイプベース(prototype-based)クラスタリング
セントロイド(centroid): 特徴量が連続値の場合に、類似する点の「中心」を表す
メドイド(medoid): 特徴量がカテゴリ値の場合に、最も「代表的」または最も頻度の高い点を表す
階層的(hierarchical)クラスタリング
密度(density-based)ベースクラスタリング
クラスタリングの品質を評価する
エルボー法(elbow method)
シルエット図(silhouette plot)
End of explanation
from sklearn.cluster import KMeans
km = KMeans(n_clusters=3,   # クラスタの個数
            init='random',  # セントロイドの初期値をランダムに選択
            n_init=10,      # 異なるセントロイドの初期値を用いた実行回数
            max_iter=300,   # 最大イテレーション回数
            tol=1e-04,      # 収束と判定するための相対的な許容誤差
            random_state=0) # セントロイドの初期化に用いる乱数生成器の状態
y_km = km.fit_predict(X)    # クラスタの中心の計算と各サンプルのインデックスの予測
Explanation: k-means法の手続き
クラスタの中心の初期値として、サンプル点からk個のセントロイドをランダムに選び出す
各サンプルを最も近いセントロイドμ(i)に割り当てる
セントロイドに割り当てられたサンプルの中心にセントロイドを移動する
サンプル点へのクラスタの割り当てが変化しなくなるか、ユーザー定義の許容値またはイテレーションの最大回数に達するまで、ステップ2〜3を繰り返す
End of explanation
plt.scatter(X[y_km == 0, 0],   # グラフのxの値
            X[y_km == 0, 1],   # グラフのyの値
            s=50,              # プロットのサイズ
            c='lightgreen',    # プロットの色
            marker='s',        # マーカーの形
            label='cluster 1') # ラベル名
plt.scatter(X[y_km == 1, 0],
            X[y_km == 1, 1],
            s=50,
            c='orange',
            marker='o',
            label='cluster 2')
plt.scatter(X[y_km == 2, 0],
            X[y_km == 2, 1],
            s=50,
            c='lightblue',
            marker='v',
            label='cluster 3')
plt.scatter(km.cluster_centers_[:, 0],
            km.cluster_centers_[:, 1],
            s=250,
            marker='*',
            c='red',
            label='centroids')
plt.legend()
plt.grid()
plt.show()
Explanation: 11.1.1 k-means++ 法
End of explanation
# 歪み(SSE)の値を取得
print('Distortion: {:.2f}'.format(km.inertia_))
distortions = []
for i in range(1, 11):
    km = KMeans(n_clusters=i,    # クラスタの個数
                init='k-means++', # k-measn++ 法によりクラスタ中心を選択
                n_init=10,       # 異なるセントロイドの初期値を用いた実行回数
                max_iter=300,    # 最大イテレーション回数
                random_state=0)
    km.fit(X)
    distortions.append(km.inertia_)
    
plt.plot(range(1, 11), distortions, marker='o')
plt.xlabel('Number of clusters')
plt.ylabel('Distortion')
plt.show()
Explanation: 11.1.2 ハードクラスタリングとソフトクラスタリング
11.1.1 エルボー法を使ってクラスタの最適な個数を求める
End of explanation
km = KMeans(n_clusters=3,
            init='k-means++',
            n_init=10,
            max_iter=300,
            tol=1e-04,
            random_state=0)
y_km = km.fit_predict(X)
import numpy as np
from matplotlib import cm
from sklearn.metrics import silhouette_samples
cluster_labels = np.unique(y_km) # y_km の要素の中で重複をなくす
n_clusters = cluster_labels.shape[0]
# シルエット係数を計算
silhouette_vals = silhouette_samples(X, y_km, metric='euclidean')
y_ax_lower, y_ax_upper = 0, 0
yticks = []
for i, c in enumerate(cluster_labels):
    c_silhouette_vals = silhouette_vals[y_km == c]
    c_silhouette_vals.sort()
    y_ax_upper += len(c_silhouette_vals)
    color = cm.jet(i / n_clusters) # 色の値をセット
    plt.barh(range(y_ax_lower, y_ax_upper), # 水平の棒グラフを描画
             c_silhouette_vals,            # 棒の幅
             height=1.0,                   # 棒の高さ
             edgecolor='none',             # 棒の端の色
             color=color)                  # 棒の色
    yticks.append((y_ax_lower + y_ax_upper) / 2) # クラスタラベルの表示位置を追加
    y_ax_lower += len(c_silhouette_vals)
    
silhouette_avg = np.mean(silhouette_vals) # シルエット係数の平均値
plt.axvline(silhouette_avg, color='red', linestyle='--') # 係数の平均値には線を引く
plt.yticks(yticks, cluster_labels + 1) # クラスタラベルを表示
plt.ylabel('Cluster')
plt.xlabel('Silhouette coefficient')
plt.show()
km = KMeans(n_clusters=2,
            init='k-means++',
            n_init=10,
            max_iter=300,
            tol=1e-04,
            random_state=0)
y_km = km.fit_predict(X)
plt.scatter(X[y_km == 0, 0],
            X[y_km == 0, 1],
            s=50,
            c='lightgreen',
            marker='s',
            label='cluster 1')
plt.scatter(X[y_km == 1, 0],
            X[y_km == 1, 1],
            s=50,
            c='orange',
            marker='o',
            label='cluster 2')
plt.scatter(km.cluster_centers_[:, 0],
            km.cluster_centers_[:, 1],
            s=250,
            marker='*',
            c='red',
            label='centroids')
plt.legend()
plt.grid()
plt.show()
import numpy as np
from matplotlib import cm
from sklearn.metrics import silhouette_samples
cluster_labels = np.unique(y_km) # y_km の要素の中で重複をなくす
n_clusters = cluster_labels.shape[0]
# シルエット係数を計算
silhouette_vals = silhouette_samples(X, y_km, metric='euclidean')
y_ax_lower, y_ax_upper = 0, 0
yticks = []
for i, c in enumerate(cluster_labels):
    c_silhouette_vals = silhouette_vals[y_km == c]
    c_silhouette_vals.sort()
    y_ax_upper += len(c_silhouette_vals)
    color = cm.jet(i / n_clusters) # 色の値をセット
    plt.barh(range(y_ax_lower, y_ax_upper), # 水平の棒グラフを描画
             c_silhouette_vals,            # 棒の幅
             height=1.0,                   # 棒の高さ
             edgecolor='none',             # 棒の端の色
             color=color)                  # 棒の色
    yticks.append((y_ax_lower + y_ax_upper) / 2) # クラスタラベルの表示位置を追加
    y_ax_lower += len(c_silhouette_vals)
    
silhouette_avg = np.mean(silhouette_vals) # シルエット係数の平均値
plt.axvline(silhouette_avg, color='red', linestyle='--') # 係数の平均値には線を引く
plt.yticks(yticks, cluster_labels + 1) # クラスタラベルを表示
plt.ylabel('Cluster')
plt.xlabel('Silhouette coefficient')
plt.show()
Explanation: 11.1.4 シルエット図を使ってクラスタリングの性能を数値化する
シルエット分析(silhouette analysis)
シルエット係数(silhouette coefficient)
End of explanation
import pandas as pd
import numpy as np
np.random.seed(123)
variables = ['X', 'Y', 'Z']
size = 5 # データサイズ
labels = ['ID_{}'.format(i) for i in range(size)]
X = np.random.random_sample([size, 3]) * 10 # 5行3列のサンプルデータを生成
df = pd.DataFrame(X, columns=variables, index=labels)
df
Explanation: 11.2 クラスタを階層木として構成する
階層的クラスタリング(hierarchical clustering)
樹形図(dendrogram)
2つのアプローチ
凝集型(agglomerative)
単連結法(single linkage)
完全連結法(complete linkage)
分割型(divisive)
End of explanation
from scipy.spatial.distance import pdist, squareform
# pdist で距離を計算、squareform で対称行列を作成
row_dist = pd.DataFrame(squareform(pdist(df, metric='euclidean')),
                        columns=labels, index=labels)
row_dist
from scipy.cluster.hierarchy import linkage
row_clusters = linkage(df.values, method='complete', metric='euclidean')
# 1、2列目は最も類似度が低いメンバー
# distanceはそれらのメンバーの距離
# 4列目は各クラスタのメンバーの個数
pd.DataFrame(row_clusters,
             columns=['row label 1', 'row label 2', 'distance', 'no. of items in clus.'],
             index=['cluster {}'.format(i + 1) for i in range(row_clusters.shape[0])])
# 樹形図を表示
from scipy.cluster.hierarchy import dendrogram
import matplotlib.pyplot as plt
row_dendr = dendrogram(row_clusters, labels=labels)
plt.ylabel('Euclidean distance')
plt.show()
Explanation: 11.2.1 距離行列で階層的クラスタリングを実行する
End of explanation
# plot row dendrogram
fig = plt.figure(figsize=(8, 8), facecolor='white')
axd = fig.add_axes([0.09, 0.1, 0.2, 0.6])
# note: for matplotlib < v1.5.1, please use orientation='right'
row_dendr = dendrogram(row_clusters, orientation='left')
# reorder data with respect to clustering
df_rowclust = df.ix[row_dendr['leaves'][::-1]]
axd.set_xticks([])
axd.set_yticks([])
# remove axes spines from dendrogram
for i in axd.spines.values():
        i.set_visible(False)
# plot heatmap
axm = fig.add_axes([0.23, 0.1, 0.6, 0.6])  # x-pos, y-pos, width, height
cax = axm.matshow(df_rowclust, interpolation='nearest', cmap='hot_r')
fig.colorbar(cax)
axm.set_xticklabels([''] + list(df_rowclust.columns))
axm.set_yticklabels([''] + list(df_rowclust.index))
# plt.savefig('./figures/heatmap.png', dpi=300)
plt.show()
Explanation: 11.2.2 樹形図をヒートマップと組み合わせる
End of explanation
from sklearn.datasets import make_moons
X, y = make_moons(n_samples=200, noise=0.05, random_state=0)
plt.scatter(X[:, 0], X[:, 1])
plt.show()
f, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 3))
# k-means 法で分類してプロット
km = KMeans(n_clusters=2, random_state=0)
y_km = km.fit_predict(X)
ax1.scatter(X[y_km == 0, 0], X[y_km == 0, 1],
            c='lightblue', marker='o', s=40, label='cluster 1')
ax1.scatter(X[y_km == 1, 0], X[y_km == 1, 1],
            c='red', marker='s', s=40, label='cluster 2')
ax1.set_title('K-means clustering')
# 完全連結法法で分類してプロット
from sklearn.cluster import AgglomerativeClustering
ac = AgglomerativeClustering(n_clusters=2,
                             affinity='euclidean',
                             linkage='complete')
y_ac = ac.fit_predict(X)
ax2.scatter(X[y_ac == 0, 0], X[y_ac == 0, 1], c='lightblue',
            marker='o', s=40, label='cluster 1')
ax2.scatter(X[y_ac == 1, 0], X[y_ac == 1, 1], c='red',
            marker='s', s=40, label='cluster 2')
ax2.set_title('Agglomerative clustering')
plt.legend()
plt.show()
from sklearn.cluster import DBSCAN
db = DBSCAN(eps=0.2, min_samples=5, metric='euclidean')
y_db = db.fit_predict(X)
plt.scatter(X[y_db == 0, 0], X[y_db == 0, 1],
            c='lightblue', marker='o', s=40,
            label='cluster 1')
plt.scatter(X[y_db == 1, 0], X[y_db == 1, 1],
            c='red', marker='s', s=40,
            label='cluster 2')
plt.legend()
plt.show()
Explanation: 11.3 DBSCANを使って高密度の領域を特定する
DBSCAN(Density-based Spatial Clustering of Applications with Noise)
コア点(core point)
ボーダー点(border point)
ノイズ点(noise point)
End of explanation
<END_TASK>