2012-02-01 15 views
2

私は、対話型遺伝的アルゴリズムでApache Commons Mathのk-means ++ clustererを使用して、ユーザーが評価する個体の数を減らしています。距離を使ってk-means ++の重心を計算するには?

コモンズ数学は非常に使いやすくなっています。ユーザーは Clusterableインターフェイスを実装するだけで済みます。これには2つの方法があります:

double distanceFrom(T p)これはかなり明確です。T centroidOf(Collection<T> p)は、ユーザーがクラスタの重心を選択できるようにします。

ユークリッド点で使用する場合、重心は非常に計算が容易です。しかし、染色体上では、それらの意味が必ずしも明確ではないので、それは非常に困難です。

私の質問:問題のドメインに依存せず、セントロイドを選択する効率的な一般的な方法はありますか? (例えば、距離を使用して)


EDIT

は、[OK]を、今ここに重心計算のための私のコードです。 アイデア:他のすべての点との距離が最も小さい点は、重心に最も近い点です。

public T centroidOf(Collection<T> c) { 
    double minDist = Double.MAX_VALUE; 
    T minP = null; 

    // iterate through c 
    final Iterator<T> it = c.iterator(); 
    while (it.hasNext()) { 
    // test every point p1 
    final T p1 = it.next(); 
    double totalDist = 0d; 
    for (final T p2 : c) { 
     // sum up the distance to all points p2 | p2!=p1 
     if (p2 != p1) { 
     totalDist += p1.distanceFrom(p2); 
     } 
    } 

    // if the current distance is lower that the min, take it as new min 
    if (totalDist < minDist) { 
     minDist = totalDist; 
     minP = p1; 
    } 
    } 
    return minP; 
} 

答えて

1

k平均は、平均化メトリック(例えば、ユークリッド)を必要とします。このようなメトリックとスペースを定義することなく、ポイントの平均が実際にスペース内のポイントであるかどうかは分かりません。

しかし、k-medoidsを使用すると、元の点のみをメドイドの候補とみなすことができます(k-meansは、必ずしも元の点にあるとは限りません)。このアルゴリズムは、ペアごとの相違度を最小にする点(すなわち、distanceFrom)を探す。

+0

ヒントをお寄せいただきありがとうございます。新しいポイントを作成せずに集団のポイントを重心として使用したい。しかし、私はこの実装を使いたいと思っています。唯一の問題は、 'centroidOf()'メソッドを実装する方法です。現時点では、コレクションのポイントをランダムに選択しています。 – Stephan

+0

リンクにアルゴリズムがあります。 – cyborg

+0

私はあなたのリンクのために答えを受け入れます。目的の実装が元の質問に表示されます。 – Stephan

関連する問題