2017-11-26

Rで機械学習:K-meansでアヤメの種類を分類する

「非階層クラスター分析」とは

 非階層クラスター分析とは、異なる性質のものが混ざり合った集団から、互いに似た性質のものを集め、クラスターを作る1つの方法です。階層クラスター分析とは異なり、階層構造を持たず、あらかじめいくつのクラスターに分けるかを決定し、決めた数のクラスターにサンプルを分割する方法です。具体的には下記のようなイメージです

何を読み取るのかが重要--統計言語「R」でクラスター分析 - (page 3) - ZDNet Japan https://japan.zdnet.com/article/35052079/3/


k-means(k平均法)とは


K-meansアルゴリズムは分類対象のデータと、データの距離の計算方法と、分類するカテゴリの数さえ設定できればクラスタリングが可能な非常に高速で手頃なクラスタリング手法です。

ざっくりK-meansを説明すると、分類対象のデータにランダムにラベル付を行い、ラベル毎にデータの中心(重心)を算出し、分類対象の全てのデータに対し尤も近い重心のラベルに再割当てするアルゴリズムです。

k-meansは, 既知のクラスタ数を cとして, 幾つかの距離 (ユーグリッド距離 etc)に基づい
てクラスタリングを行います。


d次元特徴空間に個々のパターン x1,x2…,xk が分布しており, 各パターンは異なる c種のいずれかのクラスに所属していることとします。

k平均法(kへいきんほう、英: k-means clustering)は、非階層型クラスタリングのアルゴリズム。クラスタの平均を用い、与えられたクラスタ数k個に分類することから、MacQueen がこのように命名した。k-平均法(k-means)、c-平均法(c-means)とも呼ばれる。

K meansの計算


計算手順は下記となります。

STEP1 : 初期状態としてd次元特徴空間上に各クラスタに対応する c個のプロトタイプ [2]を設定する。
STEP2 : 全てのパターンに対して所属クラスタの割り当てを行う。各Piを固定してeをδkについて最小化する。
STEP3 : プロトタイプの更新を行う。各δkを固定してeをPiについて最小化する。
STEP4 : クラスタの再割当てが発生しなければ収束と判定する。そうでない場合は STEP2に戻る。

K meansの欠点

欠点としては下記が挙げられる。
  1. クラスタ数をあらかじめ設定しないとならない。従って, 最適なクラスタ数を探索する必要がある。
  2. 初期値の設定が不完全な場合, 大域的最適解ではなくて局所的最適解に収束してしまう。

RでK-meansの非階層クラスタリングを実践



  • Rの標準データセットである、iris(あやめのデータ)を利用する
    • Sepal.Length: がく片の長さ
    • Sepal.Width : がく片の幅
    • Petal.Length: 花びらの長さ
    • Petal.Width : 花びらの幅
    • Species:種類
      • setosa
      • versicolor
      • virginica
  • 種類のデータを抜いて、 Sepal.Length Sepal.Width Petal.Length Petal.Widthから種類をK-meansでクラスタリングできるか試してみる
> dat <- iris #Rのデータセットにプリセットで存在する
> head(dat)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

  • K-meansで非階層化クラスタリングを行う

> dat.km <- kmeans(dat[,1:4],3)#Speciesを抜いたデータ、引数の3はクラスターの数を指定
> dat.km$cluster
  [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 2 3 3 3 3 3 3 3 3 3
 [63] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 3 2 2 2 2 3 2 2 2 2 2 2 3 3 2 2 2 2 3 2 3 2 3
[125] 2 2 3 3 2 2 2 2 2 3 2 2 2 2 3 2 2 2 3 2 2 2 3 2 2 3

  • 全てのデータが3つにカテゴリ分けされていることがわかる。
  • 今度は今のカテゴリをグラフィカルに表示する

> library(cluster)
> clusplot(dat, dat.km$cluster, color=TRUE, shade=TRUE, labels=2, lines=0)
  • 1, 2, 3と似たようなものを分けて、クラスタリングしてくれた
  • でも、ちょっと2と3で重複するエリアが存在する
  • 今度は、このクラスタリングが十分の精度でできていたのか比較する
    • クラスタリング結果の3種類のグループ
    • もともとのSpeciesに存在した3種類
  • これをクロス集計で比較することによって、k-meansでちゃんと分割できていたかを見る
 result <- dat.km$cluster
> answer <- iris[,5] # Piecesのデータ
> ctable
            result
answer        1  2  3
  setosa     50  0  0
  versicolor  0  2 48
  virginica   0 36 14

  • グラフを見たとおりそうだけど、2と3の重複エリアが存在しているため、完全にクラスタリングに成功しているわけではなさそう
  • しかし、それでもsetosaは完全にクラスターできているようだった。
  • もしかしたら、irisの中でも、完全に種類によってサイズが違うものだけで見たら、ちゃんとクラスタリングできたかもしれない

注目の投稿

 PythonのTweepyを利用して、Twitter APIを利用している。 その中で、ハマったポイントをメモしておく。 まず、Searchに関して。 Twitter検索は、クライアントアプリ側では、全期間の検索が可能になっている。 一方で、APIを利用する際は、過去1週間しか...