增加以上参数的目的,是防止kmeans算法陷入局部最优,即分类的结果不是最好的。局部最优的示例:
横向分类,纵向分类分别是两种分类结果。显然,横向分类是局部最优。
for( k = 1; k < K; k++ ) // k个中心
{
double bestSum = DBL_MAX;
int bestCenter = -1;
for( j = 0; j < trials; j++ ) // 多次尝试,选取最优,trials参数一般选取3
{
double p = (double)rng*sum0, s = 0;
for( i = 0; i < N-1; i++ )
if( (p -= dist[i]) <= 0 )
break; // 上面4行代码,逐行不理解他们的意思。整体看起来意思是随机选取一个新的中心,不知道是否有更深含义?
int ci = i;
for( i = 0; i < N; i++ )
{
tdist2[i] = std::min(distance(data + step*i, data + step*ci, dims), dist[i]); // 新、旧中心距离比较,取小的距离
s += tdist2[i]; // 求和,累加,计算出整体分类的紧密度(聚类的紧密度度量(聚类好坏的度量):所有对象到各自聚类中心的方差和),这里只有新旧两个类中心
}
if( s < bestSum ) // 保存最优结果
{
bestSum = s;
bestCenter = ci;
std::swap(tdist, tdist2);
}
}
centers[k] = bestCenter; // 计算出第k个结果
sum0 = bestSum;
std::swap(dist, tdist);
}
KMEANS_USE_INITIAL_LABELS是第一次采用用户自己设置的初始化的中心点进行运算,而后面的尝试则采用随机算法(或半随机)选取的中心。
并查集,用于划分数据,分类的标准是它们在同一个有联系的集合中(或它们的联系能形成一个树):
http://www.cnblogs.com/cherish_yimi/archive/2009/10/11/1580839.html
http://baike.baidu.com/view/521705.htm
Father仅仅是一个 指示 根节点 的数组,father[x]意思是 第x个元素的根节点是 father[x]