【非階層型】K-means法でクラスタリングをしてみましょう。

今回は、K-means法を取り扱います。クラスター分析に使われる手法です。

実際にどのようにしてクラスターを分けているのかわからない方は多いと思います。

ビジュアライゼーションソフトのtableauの機能の一つ「クラスター分析」にも、自動的にK-means法でクラスタリングが行われています。

K-means法

クラスタリング

「顧客の属性を購買パターンに応じてセグメント化したい」

「アプリを利用する頻度でユーザーを分類したい」

クラスタリングは、以上の目的のためによく使われます。

データの集合をグループ化するタスクのことをクラスタリングといい、各グループはクラスターと呼ばれます。

同じクラスター内のデータは、他のクラスター内のデータよりも類似性が高くなります。(そういう分け方をしたから)

また、分類と何が違うのかというという問いに対しては、

分類:あらかじめ決められたクラスにデータを割り当てる

クラスタリング:あらかじめクラスは存在していない

という点が異なります。ただ、非階層型のクラスタリング(今回紹介するK-means法も)は、事前にクラスター数を指定する必要があることから、「なぜそのクラスター数」なのか?という意図を客観的に説明する必要はあります。

今回ご紹介する、K-means法はクラスタリング手法の一つです。

クラスタリングは、教師なし学習の一つです。教師なし学習については、【python】コサイン類似度は高校数学の知識で理解できます!で少し解説しています。

正解を与えずに、データの傾向のみからモデルを構築するのが教師なし学習でした。

コードの解説の前に、具体的に何をやっているかを図解します。

1:分けたいクラスターの数だけ、とりあえず点を置きます。

点を置く位置で最終的に作られるクラスターが変わる場合もありますが、今回は説明は割愛します。

2:点と各データの距離を測り、近い方のクラスターに分ける。

3:分けたクラスター内で平均をとり、新しい基準点に変える。

4:同じように新しい基準点と各データの距離を測り、近い方のクラスターに分ける

Code

ここまで、K-means法が何をやっているのか理解できたと思います。

実際にコードを書いていきましょう。以下の書籍の、ジム利用顧客データを扱います。

Python 実践データ分析 100本ノック [ 下山 輝昌 ]

価格:2,640円
(2022/7/12 23:44時点)

#pandasライブラリの読み込み
#csvデータの読み込み

import pandas as pd
customer = pd.read_csv("customer_join.csv")
customer.head()
customer.head()

customerのデータを5行分だけ出力させました。

クラスタリングに使うデータだけ抽出しましょう。

#k-means法を使う
#まずはクラスタリング用のデータの抽出
customer_clustering = customer[["mean","median","max","min","membership_period"]]

#k_means
#標準化が必要
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

#標準化の実行
sc = StandardScaler()
customer_clustering_sc = sc.fit_transform(customer_clustering)

#4つのクラスターに分ける
kmeans = KMeans(n_clusters=4, random_state=0)

#clustersにデータを代入する
clusters = kmeans.fit(customer_clustering_sc)

#元のデータにクラスタリング結果を反映させる
#clusterという列を作成する
customer_clustering["cluster"] = clusters.labels_
print(customer_clustering["cluster"].unique())
customer_clustering
customer_clustering.head()

次にk-means法を行います。

sklearnというライブラリを使います。

出力結果

ライブラリをインポートした後は、標準化を行います。

今回は、ジムを利用する顧客を4つに分けますので、n_clusters = 4です。

次の行で、clustersに「標準化した顧客データ(クラスタリング用に抽出済み)」をk-meansの関数にいれたものを代入します。

そして、customer_cluseteringというもとの行列にclusterというk-means法を使ってクラスタリングした列を追加します。

出力結果には、ちゃんと最後の列に「cluster」という列が追加されていることがわかります。

理論

ここでは、ちゃんとK-means法の数式をちゃんと知りたい方向けの理論パートです。

$$f(x)=argmin||x_{n}-μ_{k}||^2$$

まず、以上のような関数を作ります。

kは作りたいクラスターの個数です。

μは平均を表します。添字でkがついているので、クラスターの平均ですね。

実際のデータxと基準点\(μ_k\)の差の二乗のうち、小さい方を採用するという関数です。負の数に対応するために絶対値の2乗をとっているだけですね。

各データとそれが割り当てられるクラスタ中心の平方ユークリッド距離が最小化する最適化問題を解いています。

$$z_{n}=argmin||x_{n}-μ_{k}||^2$$

\(z_n\)に代入します。

$$\hat{μ}_k=\frac{1}{N_{k}}\sum_{z_{n}=k}x_{n}$$

そして、新しくクラスター内の平均を取ります。

\(z_n\)の代入に戻り、この処理を繰り返します。

以上がK-means法の処理になります。

このように、k-means法では繰り返しによりコスト関数を以下のように最適化しています。

・中心の割り当てでは、f(x)を最小化するようなクラスター(データ\(x_{i}\)が所属する)の推定

・中心の更新では、f(x)を最小にするような\(μ_{k}\)の推定

クラスタリングや主成分分析に関して詳しく学びたい方は、【共線性解決】pythonで主成分分析をやってみたをご覧ください。

今回取り上げたk-means法は、教師なし学習のクラスタリングの中でも「非階層型」と呼ばれる型に分類されます。

非階層型の短所として、事前にクラスターを何個作るかを指定してあげることが必要になります。そもそもどう分けるかを理解している必要はあります。

その代わり、次元数が多くても対応可能という長所はあります。

meritdemerit
非階層次元が多い場合にも対応する事前にクラスター個数を指定する
階層分類過程を視覚的に見れる計算量が多い

事前にクラスターの数を指定しない階層型ですが、正解データがなく解釈や評価が難しい教師なし学習では大きな問題点と思われるかもしれませんね。

実際に、k-means法によって得られるクラスタリング結果はクラスタリングの初期状態に大きく依存する局所最適解です。

大域的な最適解を求めるには、複数の初期状態でクラスタリングを行い、その中から最も良い結果を選ぶことが大切であり、その良し悪しは先ほどのコスト関数が小さいものを選べば良い、ということになります。

$$f(x)=argmin||x_{n}-μ_{k}||^2$$

FOLLOW ME !