概要
k-means法とデンドログラムを表示するPythonのコードを作成しました。k-means法とデンドログラムは、データをクラスタリング(グループ化)するための代表的な手法です。クラスタリングは、データを似た特徴を持つグループに分けるために使用されます。k-means法は、ユーザーが指定したクラスタの数に基づいてデータを分割し、各クラスタの中心点(セントロイド)を見つけることを目的としています。一方、デンドログラムは、階層的クラスタリングを視覚化するための図であり、データがどのように逐次的にクラスタに結合されていくかを示します。
これらの手法は、マーケティング、バイオインフォマティクス、画像処理など、様々な分野で広く利用されています。
コード全文
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from scipy.cluster.hierarchy import dendrogram, linkage
# 無作為に身長と体重のデータを生成
np.random.seed(42) # 再現性のためシードを設定
heights = np.random.normal(170, 10, 50) # 平均170cm、標準偏差10cmの身長
weights = np.random.normal(65, 15, 50) # 平均65kg、標準偏差15kgの体重
# データフレームにまとめる
data = pd.DataFrame({'Height': heights, 'Weight': weights})
# データの標準化
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data[['Height', 'Weight']])
# k-meansクラスタリングの実行(標準化後のデータを使用)
kmeans = KMeans(n_clusters=3, random_state=42)
kmeans.fit(data_scaled)
data['Cluster'] = kmeans.labels_
# データをプロットしてクラスタリングの結果を視覚化
plt.figure(figsize=(8, 6))
plt.scatter(data['Height'], data['Weight'], c=data['Cluster'], cmap='viridis', s=50)
plt.xlabel('Height (cm)')
plt.ylabel('Weight (kg)')
plt.title('K-means Clustering of Height and Weight')
plt.show()
# 階層的クラスタリング(デンドログラム)の実行
linked = linkage(data_scaled, method='ward')
# デンドログラムの描画
plt.figure(figsize=(10, 7))
dendrogram(linked, orientation='top', labels=np.arange(1, 51), distance_sort='descending', show_leaf_counts=True)
plt.title('Dendrogram')
plt.xlabel('Sample Index')
plt.ylabel('Distance')
plt.show()
出力結果
コードのステップ・バイ・ステップの説明
以下のコードでは、k-means法とデンドログラムを使用して、無作為に生成された身長と体重のデータをクラスタリングします。コードをステップ・バイ・ステップで解説します。
1. 必要なライブラリのインポート
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from scipy.cluster.hierarchy import dendrogram, linkage
まず、クラスタリングに必要なライブラリをインポートします。numpyとpandasはデータの生成と操作に使用され、matplotlibはデータの視覚化に使用されます。sklearnからはk-means法の実行に必要なクラスを、scipyからは階層的クラスタリングのための関数をインポートします。
2. データの生成
# 無作為に身長と体重のデータを生成
np.random.seed(42) # 再現性のためシードを設定
heights = np.random.normal(170, 10, 50) # 平均170cm、標準偏差10cmの身長
weights = np.random.normal(65, 15, 50) # 平均65kg、標準偏差15kgの体重
ここでは、身長と体重のデータを正規分布に従って無作為に生成しています。np.random.seed(42)は、結果が再現可能になるようにランダムシードを設定しています。これにより、他の人が同じコードを実行した場合でも同じデータが生成されます。
3. データフレームへのまとめ
# データフレームにまとめる
data = pd.DataFrame({'Height': heights, 'Weight': weights})
生成した身長と体重のデータをpandasのデータフレームにまとめます。これにより、データの操作が容易になります。
4. データの標準化
# データの標準化
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data[['Height', 'Weight']])
クラスタリング前に、データのスケールを揃えるために標準化を行います。標準化とは、各変数の平均を0、標準偏差を1に変換する操作です。これにより、異なる単位のデータを同等に扱うことができます。
5. k-meansクラスタリングの実行
# k-meansクラスタリングの実行(標準化後のデータを使用)
kmeans = KMeans(n_clusters=3, random_state=42)
kmeans.fit(data_scaled)
data['Cluster'] = kmeans.labels_
ここでは、n_clusters=3で3つのクラスタにデータを分割するようにk-means法を適用しています。クラスタリングの結果として、各データポイントがどのクラスタに属するかがCluster列に追加されます。
6. k-meansの結果をプロット
# データをプロットしてクラスタリングの結果を視覚化
plt.figure(figsize=(8, 6))
plt.scatter(data['Height'], data['Weight'], c=data['Cluster'], cmap='viridis', s=50)
plt.xlabel('Height (cm)')
plt.ylabel('Weight (kg)')
plt.title('K-means Clustering of Height and Weight')
plt.show()
k-means法で得られたクラスタリングの結果を散布図で可視化します。c=data['Cluster']で各ポイントの色をクラスタ番号に基づいて設定し、cmap='viridis'でカラーマップを指定しています。
7. 階層的クラスタリング(デンドログラム)の実行
# 階層的クラスタリング(デンドログラム)の実行
linked = linkage(data_scaled, method='ward')
階層的クラスタリングを行い、データの結合プロセスをlinkage関数を用いて計算します。ここではmethod='ward'を指定しており、分散の最小化を基準にクラスタを結合します。
8. デンドログラムの描画
# デンドログラムの描画
plt.figure(figsize=(10, 7))
dendrogram(linked, orientation='top', labels=np.arange(1, 51), distance_sort='descending', show_leaf_counts=True)
plt.title('Dendrogram')
plt.xlabel('Sample Index')
plt.ylabel('Distance')
plt.show()
最後に、デンドログラムを描画して階層的クラスタリングの結果を視覚化します。デンドログラムは、データがどのようにしてクラスタに結合されていくかを示すもので、クラスタリングの階層構造を理解するのに役立ちます。
結論
k-means法とデンドログラムは、異なる視点からデータのクラスタリングを行うための強力なツールです。k-means法は指定したクラスタ数に基づいてデータを分割するのに対し、デンドログラムはデータがどのように階層的に結合されていくかを視覚的に示します。両方の手法を理解することで、データの内部構造やパターンをより深く洞察できるようになります。