2012-02-01 33 views
2

我在交互式遗传算法中使用Apache Commons Math中的k-means ++聚类器来减少用户评估的个人数量。如何使用距离计算k-means ++中的质心?

Commons Math使其非常易于使用。用户只需要实现接口即可。它有两种方法:

double distanceFrom(T p)这很清楚,并且T centroidOf(Collection<T> p),它允许用户选择群集的质心。

如果用于欧几里得点,质心很容易计算。但是在染色体上它很难,因为它们的含义并不总是很清楚。

我的问题:是否有一种有效的通用方法来选取质心,而不取决于问题域? (例如,通过使用距离)


编辑

好吧,这里是我现在的重心计算代码。 想法:与所有其他点的距离最近的点离质心最近。

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,它只考虑原始点作为medoids的候选项(而k-均值找到不一定在原始点上的均值/质心)。该算法寻找其最小化成对相异点(即,distanceFrom)。

+0

感谢您的提示。我想用人口中的一点作为质心而不创建新的点。但我也想使用这个实现。唯一的问题是如何实现'centroidOf()'方法?目前我正在随机选择一个集合点。 – Stephan 2012-02-02 01:01:56

+0

链接中有一个算法。 – cyborg 2012-02-02 05:15:12

+0

由于您的链接,我接受答案。原始问题现在显示了所需的实现。 – Stephan 2012-02-03 12:13:42