クラスタリングについて

クラスタリングを学習することによって、顧客を特徴によって分割できます。うまく分割できれば、それぞれ別のモデルを作って精度を上げられます。

クラスタリング(clustering)とは、機械学習の1種でデータ間の類似度にもとづいて、データをグループ分けする手法です。この単語は機械学習や統計学の文脈以外でも使われることが多いため、これらの分野で用いられる際にはクラスタ分析やデータ・クラスタリングと呼ばれるのが通例となっています。

https://www.tryeting.jp/column/1049/#:~:text=%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0%EF%BC%88clustering%EF%BC%89%E3%81%A8%E3%81%AF%E3%80%81,%E9%80%9A%E4%BE%8B%E3%81%A8%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82

機械学習において、「正解がないデータを扱う学習」を教師なし学習といいます。主に教師なしで分類する方法を言う。
ここでは、教師なし学習の1つであるk-means法を使って、クラスタリング(グループ分け、セグメンテーション)をしてみましょう。

顧客をクラスタリングすることで、クラスター(グループ、セグメント)ごとの販売傾向がわかり、販売促進に役立てられます。

%run 1.ipynb
df.head()
前回からの引継ぎ
# クラスタリングする
from sklearn.cluster import k_means

n_clusters = 2
centroid, label, inertia = k_means(df, n_clusters, random_state=0)
centroid, label, inertia

(array([[ 3878.18181818, 48025.        ,  4523.18181818,   611.47727273],
        [39687.14285714, 16130.35714286,  2213.75      ,   247.19642857]]),
 array([0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0,
        1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0,
        0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1,
        0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0,
        0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0], dtype=int32),
 39727838655.12175)
# ラベル0を取り出す
df0 = df[label == 0]
df0_mean = df0.mean()
df0_mean
Recruit       3878.181818
Custom       48025.000000
Shirt         4523.181818
Accessory      611.477273
dtype: float64
# ラベル1を取り出す
df1 = df[label == 1]
df1_mean = df1.mean()
df1_mean
Recruit      39687.142857
Custom       16130.357143
Shirt         2213.750000
Accessory      247.196429
dtype: float64

k-means法(sklearn.cluster.k_means)では、クラスターの数(n_clusters)を指定する必要があります。
今回は、2を指定します。

k-means法では、ランダムな初期値を使いますが、デフォルトでは、k-means++法という、初期値がなるべく離れるように工夫された方法を使います。

乱数を使うので、実行するたびに結果が変わることがあります。もし、何度実行しても同じ結果が欲しいのであれば、乱数の元であるrandom_stateに適当な値を指定してください。

返り値は、「クラスターごとの中心、クラスターのラベルの配列、中心との距離の自乗和」のタプルです。

  • centroid:クラスターごとの中心(行:クラスター、列:Recruit, Custom, Shirt, Accessory
  • label:クラスターのラベルの配列
  • inertia:中心との距離の自乗和(この値を最小化するようにクラスタリングします)
https://images.pyq.jp/repo/prod/ml_clustering/clustering_1.jpg

クラスターのラベルの配列を使って、顧客を2つに分けてみましょう。

df[label == 0]とするとラベルが0のものを取り出せます。

meanで平均を見ると、ラベル0はCustom系で、ラベル1がRecruit系と言えそうです。また、ラベル1の方が全体的に販売額が高そうです。

この分析から、ラベル0に分類された顧客を参考にしてカスタムメイド用のコーディネートを、ラベル1に分類された顧客を参考にしてリクルート用のコーディネートが考えられます。

sklearn.cluster.KMeansを使うとk-means法のモデルを作成して、分類と同じようにfitpredictも使えます。

from sklearn.cluster import KMeans
km = KMeans(n_clusters, random_state=0) # k-means法のモデル
km.fit(df) # 当てはめ
km.predict(df) # labelsと同様の結果が得られます

n_clusters = 2として、centroid, label, inertia = k_means(df, n_clusters, random_state=0)で2つにクラスタリングしました。

centroid, label, inertiaは、「クラスターごとの中心、クラスターのラベルの配列、中心との距離の自乗和」でしたね。

2つのクラスターを以下のようになりました。

  • ラベル0に割り当てられたクラスター:Customの売上が大きい
  • ラベル1に割り当てられたクラスター:Recruitの売上が大きい

また、売上に占める割合は小さいですが、ラベル0の方がShirtとAccessoryの売上が大きいこともわかります。

補足

df.sum()のようにDataFrameの多くのメソッドは、axisオプションで行方向(=0)か列方向(=1)を指定できます。
デフォルトは、行方向に計算し、結果は列ごとになります。df.sum(1)は、列方向に計算し、結果は行ごとになります。
行または列ではなく、表全体の要素の合計を調べるには、df.sum().sum()のようにできます。

コメント

タイトルとURLをコピーしました