間違いがありました…。

先日書いた kmeans() 関数についての記事ですが、
kmeans 関数の 'singleton' オプション - ひらのの日記
間違いがありました。。すいません。
何も考えずにこう書いちゃったのですが↓

kmeans() のアルゴリズムは、朱鷺の杜↓
k-means法 - 機械学習の「朱鷺の杜Wiki」
に書かれているのと多分同じなので、以後、このサイトの表記を使うことにします。

実は Matlab だと、朱鷺の杜でいうところの「3」のアルゴリズムが微妙に違ってて、距離に "重み付け" がなされています。

誤:
全てのデータ  \mathbf{x}\in X を,各クラスタのセントロイド \mathbf{x}_i との距離  ||\mathbf{x}-\mathbf{x}_i|| を最小にするクラスタ X_i へ割り当てる


正: *1
データ  \mathbf{x}\in X を,(クラスタ X_i に対し定義される) 以下の評価関数  \varphi を最小にするクラスタX_i へ割り当てる.
 \varphi(X_i) := \alpha ||\mathbf{x}-\mathbf{x}_i||^2 (  x_i X_i のセントロイドとする. )
ここで, \alpha は以下のように定義される.

  1.  x が所属するクラスターが決まっていない場合: \alpha = 1
  2.  x が所属するクラスターが決まっている場合:まず,  x が所属しているクラスターを X_j とし, X_j の持つデータ数を  m とする. このとき, 以下のように定める.
    1.  i = j のとき: \alpha = m/(m - 1). ただし,  m = 1 のときは,  \alpha = 1.
    2.  i \neq j のとき: \alpha = m/(m + 1).

ソースコードを見たので、多分間違ってないと思うんだけど、、間違ってたら訂正します。


ぼくのような素人から見ると、ややこしいことやってるな〜と思うけど、こうやって、評価関数が、

設定されることで、所属するクラスターの変更が頻繁に起きるようになる、というメリットがあるのではないか…と個人的には思っています。


この 2 つの方法で結果が違ってくる例はいくらでも作ることが出来て、1 次元の場合でも、次のような例があります。

1 次元ユークリッド空間上に 4 点  p_1 = -2,  p_2 = 0,  p_3 = 0,  p_4 = 1 を取り、 X = \{p_1, p_2, p_3, p_4\} とする。
 X を、2 つのクラスタ X_1,  X_2 に分ける。
ここで、 X_1 の種  x_1 = -1 X_2 の種  x_2 = 1 とする。


このとき、クラスタリングの実行結果は以下のように異なってくる。

  • 「朱鷺の杜」版: X_1 = \{p_1, p_2, p_3\},  X_2 = \{p_4\}
  • Matlab 版: X_1 = \{p_1\},  X_2 = \{p_2, p_3, p_4\}



…それにしても、、こういうアルゴリズムって統一できないものなのでしょうかねぇ?
(もしくは、「違うことやってる!」ということがちゃんと分かる名前にするとか。)
「Kmeans」といったときに、人によっててんでばらばらのアルゴリズムを指している、というのはちょっとヤバイんじゃないか…と思います。
何となく、「宇治茶」騒動を連想してしまいます。
参考:宇治茶 - Wikipedia

*1:ユークリッド距離の場合です。