教師なし学習

jooyeonk2 執筆者 Jooyeon Kim

教師なし学習(Unsupervised Learning)は、教師データ(外部から与えられた条件)を用いずにデータ構造を推定することを目的とします。
このチュートリアルでは、教師なし学習としてクラスタリングを取り上げます。
クラスタリングは教師なし学習の代表的な例であり、類似したデータを一つの集合(クラスタ)として集めることで全体のデータセットをいくつかのクラスタに分類する手法です。
ここでは、クラスタリングのうち階層型・非階層型クラスタリングの仕組みを理解し、それぞれを実践できるようになることを目指します。

階層型クラスタリング


階層型クラスタリングは、複数の要素からなるクラスタの階層を構築することで要素をグルーピングする手法です。
一般的に全要素が一つのクラスタになるまで併合するボトムアップ方式と、一つのクラスタからサブクラスタに分岐していくトップダウン方式がありますが、ここでは一般的に使われるボトムアップ方式だけを記述します。

ボトムアップ方式の階層型クラスタリング(以下、階層型クラスタリング)のクラスタリングの流れは、一番近い要素またはサブクラスタ間を繋ぎ、また距離を計算する、ということの繰り返しであり、デンドログラムというダイアグラムで表現されます。デンドログラムの例を、下記に示します。
Dendrogram

得られたデンドログラムと指定した基準値から、データのクラスタリングができます。例えば、この図では基準値を4.5にすると{(a,b,c,d), (e)}、基準値を2.7にすると{(a,b),(c,d),(e)}のようにクラスタリングができます。

階層型クラスタリングを行うためには、要素またはサブクラスタ間の距離を定義する必要がありますが、このために

  1. ‘距離’のメトリックを定義する。
  2. 複数の要素からなるサブクラスタ間の距離を定義する。

必要があります。

まず、要素またはサブクラスタ間の距離には多様なメトリックがありますが、代表的に

  1. ユークリッド距離
  2. コサイン距離
  3. マンハッタン距離
  4. マハラノビス距離
  5. ジャカール係数

などがあります。データの特性を考えてメトリックを選ぶといいです。

次に、複数の要素からなるサブクラスタ間の距離を定める基準を決める必要があるますが、代表的に、

  1. 最小最短距離法:一番近い要素と要素間の距離をサブクラスタ間の距離とする。
  2. 最長距離法:一番遠い要素と要素間の距離をサブクラスタ間の距離とする。
  3. 群平均法:すべての要素と要素間の距離の平均値をサブクラスタ間の距離とする。

などの方法があります。色々なものを試して一番良い結果を出すものを使えばいいです。

階層型クラスタリングの実装


import numpy as np
from scipy.cluster.hierarchy import dendrogram, linkage
from scipy.spatial.distance import pdist
import matplotlib.pyplot as plt

a=np.random.random((10,5))+2
b=np.random.random((10,5))+5
c=np.random.random((10,5))+8
X=np.concatenate((a,b,c))

p= pdist(X, metric="euclidean") #ユークリッド距離を採用する
Z= linkage(p, method="single") #最小最短距離法をmethodで指定する

dendrogram(Z)

plt.show()

例のコードを実行すると、Screen Shot 2014-02-24 at 22.23.32のようなデンドログラムが得られます。1から5までの基準値を指定することで3つのクラスタが得られます。

非階層型クラスタリング


代表的な非階層型クラスタリング手法であるK-means法は、最初にクラスタ数(n)を指定してから要素をクラスタリングします。具体的には、以下のような手順でクラスタリングします。

  1. まず、要素をランダムにn個のクラスタに分類し、各クラスタの中心点(Centroid)を計算します。
  2. 次に、指定した反復回数に達するまで、または収束するまで以下の事項を反復します。

    1. 各要素を一番近い中心点のクラスタに分類する。
    2. 各クラスタの新しい中心点を計算する。

非階層型クラスタリングの実装


import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

a=np.random.random((100,2))+2
b=np.random.random((100,2))+5
c=np.random.random((100,2))+8
X=np.concatenate((a,b,c))

k_means= KMeans(init='random', n_clusters=3) #init:初期化手法、n_clusters=クラスタ数を指定
k_means.fit(X)
Y=k_means.labels_  #得られた各要素のラベル

plt.figure(figsize=(10,5))
plt.scatter(*zip(*X), c= k_means.labels_, vmin=0, vmax=2, s=12)

plt.show()

例のコードの実行すると、Screen Shot 2014-02-25 at 0.06.56のように、指定した数のクラスタが出てきます。

課題


階層型クラスタリング/被階層型クラスタリングを行うプログラムをそれぞれ(クラスタリングのライブラリを用いずに)実装し、適切なデータセットに対して、それぞれの手法でクラスタリングを行い、結果について考察せよ。