scikit-learn でクラスタ分析 (K-means 法)

Last update: 2016-05-29

本ページでは、Python の機械学習ライブラリの scikit-learn を用いてクラスタ分析を行う手順を紹介します。

クラスタ分析とは

クラスタ分析 (クラスタリング, Clustering) とは、ラベル付けがなされていないデータに対して、近しい属性を持つデータをグループ化する手法です。例をあげると、以下のような活用方法があり、マーケティング施策や商品の企画開発などに活用することます。

  • 製品ごとの特徴 (自動車であれば、価格や定員、燃費、排気量、直近の販売台数) を用いて類似の製品をグループ化
  • 店舗の特徴 (スーパーであれば、売上や面積、従業員数、来客数、駐車場の数) から類似の店舗をグループ化
  • 顧客の特徴 (銀行であれば、性別、年齢、貯蓄残高、毎月の支出、住宅ローンの利用有無など) を用いて似たような利用傾向の顧客をグループ化

クラスタ分析には大別して、K-Means に代表される「非階層的クラスタ分析」と Ward 法 (ウォード法) に代表される「階層的クラスタリング」の2種類が存在します。本ページでは、非階層的クラスタ分析の代表例である K-Means 法を用いたクラスタリングについて解説します。

非階層的クラスタリング
非階層的クラスタリング (例: K-Means 法) では、決められたクラスタ数にしたがって、近い属性のデータをグループ化します。以下の図では、3つのクラスタに分類しましたが、それぞれの色でどのクラスタに分類されたかを示しています。
kmeans

階層的クラスタリング
階層的クラスタリング (例: Ward 法) では、クラスタリングの結果を木構造で出力する特徴があります。縦方向の長さ (深さ) は類似度を示し、長いほど類似度が低く、短いほど類似度が高いことを示します。
ward


K-Means法とは

K-Means 法 (K-平均法ともいいます) は、基本的には、以下の 3 つの手順でクラスタリングを行います。

  1. 初期値となる重心点をサンプルデータ (データセット全体からランダムに集めた少量のデータ) から決定。
  2. 各サンプルから最も近い距離にある重心点を計算によって求め、クラスタを構成。
  3. 2.で求めたクラスタごとに重心を求め、2. を再度実行する。2. ~ 3. を決められた回数繰り返し実行し、大きな変化がなくなるまで計算。

scikit-learn を用いたクラスタ分析

scikit-learn には、K-means 法によるクラスタ分析を行うクラスとして、sklearn.cluster.KMeans クラスが用意されています。

sklearn.cluster.KMeans クラスの使い方

sklearn.cluster.KMeans クラスの引数
実行時に、以下のパラメータを制御できます。

n_clusters クラスタ数。(デフォルト値: 8)
max_iter 繰り返し回数の最大値。 (デフォルト値: 300)
n_init 初期値選択において、異なる乱数のシードで初期の重心を選ぶ処理の実行回数。 (デフォルト値: 10)
init 初期化の方法。’k-means++”, ‘random’ もしくは ndarray を指定。 (デフォルト値: ‘k-means++’)
tol 収束判定に用いる許容可能誤差。 (デフォルト値: 0.0001)
precompute_distances 距離 (データのばらつき具合) を事前に計算するか。 ‘auto’, True, False から指定。 (デフォルト値: ‘auto’)
verbose 1 を指定すると、詳細な分析結果を表示。 (デフォルト値: 0)
random_state 乱数のシードを固定する場合に指定。数値もしくは integer or numpy.RandomState で指定。 (デフォルト値: None)
copy_x 距離を事前に計算する場合、メモリ内でデータを複製してから実行するかどうか。 (デフォルト値: True)
n_jobs 初期化を並列処理する場合の多重度。-1 を指定するとすべての CPU を使用。 (デフォルト値: 1)

sklearn.cluster.KMeans クラスのメソッド
以下のメソッドを用いて、クラスタリングの計算を行います。

fit(X[, y]) クラスタリングの計算を実行する。
fit_predict(X[, y]) 各サンプルに対する、クラスタ番号を求める。
fit_transform(X[, y]) クラスタリングの計算を行い、X を分析に用いた距離空間に変換して返す。
get_params([deep]) 計算に用いたパラメータを返す。
predict(X) X のサンプルが属しているクラスタ番号を返す
set_params(**params) パラメータを設定する
transform(X[, y]) X を分析に用いた距離空間に変換して返す。

scikit-learn を用いたクラスタ分析の実行例

scikit-learn を用いてクラスタ分析を行う手順を紹介します。

今回使用するデータ
今回は、UC バークレー大学の UCI Machine Leaning Repository にて公開されている、「Wholesale customers Data Set (卸売業者の顧客データ)」を利用します。

データセットの構成は以下のようになっています。各行が顧客 1 件を指し、440 件の顧客データが格納されています。

Channel 販売チャネル。1: Horeca (ホテル・レストラン・カフェ), 2: 個人向け小売
Region 各顧客の地域。1: リスボン市, 2: ポルト市, 3: その他
Fresh 生鮮品の年間注文額
Milk 生鮮品の年間注文額
Grocery 食料雑貨の年間注文額
Frozen 冷凍食品の年間注文額
Detergents_Paper 衛生用品と紙類の年間注文額
Delicassen 惣菜の年間注文額

データセットの詳細は以下にて確認可能です。

分析用コード

以下のコードを実行して、クラスタ分析を実行できます。今回は、440 件の顧客を購買傾向に基づいて、4 つのクラスタに分類します。
(※ K-Means 法は初期値に乱数を使用する関係上、必ずしも以下の結果通りにクラスタ番号が決定するとは限りません)

上記のように、440 件の各顧客にクラスタ番号 (0, 1, 2, 3) が付与されたことがわかります。


各クラスタの特徴を確認

クラスタ分析の結果を利用し、各クラスタがどのような特徴があるのかを確認します。ここでは、集計作業を楽に行うため、Pandas のデータフレームを利用します。


Matplotlib でクラスタの傾向を可視化

先ほど求めた、各クラスタの各部門商品の購買額の平均値を Matplotlib を用いて傾向を可視化すると以下のようになります。

Matplotlib で積み上げ棒グラフを出力

出力結果

k-means_plot

結果から、それぞれ次のように説明できます。

  • クラスタ番号 = 0 に分類された顧客 (79 人) は、Grocery (食料雑貨品) と Detergents_Paper (衛生用品と紙類) の購買額が比較的高いことがわかります。
  • クラスタ番号 = 1 に分類された顧客 (291 人) は、全体的に購買額が低い傾向にあります。
  • クラスタ番号 = 2 に分類された顧客 (7 人) は、全てのジャンルで購買額が高いと言えます。
  • クラスタ番号 = 3 に分類された顧客 (63 人) は、Fresh (生鮮食品) やFrozen (冷凍食品) の購買額が比較的高いことがわかります。

上記のように、クラスタ分析は簡単にデータのみからあらゆる発見を行うことに適している汎用的な手法だと言えます。皆さんが会社や研究で扱っているデータもこのように分析することで、新たな発見があるかもしれないでしょう。

参考・引用:
2.3. Clustering — scikit-learn 0.17.1 documentation
sklearn.cluster.KMeans — scikit-learn 0.17.1 documentation

See also