**
一、定义:
**
K-means是一种无监督学习,对未标记的数据(即没有定义类别或组的数据)进行分类。 该算法的目标是在数据中找到由变量K标记的组。该算法迭代地工作基于所提供的特征,将每个数据点分配给K个组中的一个。 基于特征相似性对数据点进行聚类。
**
二、工作流程
**
- 随机选取K个样本作为聚类中心;
- 计算各样本与各个聚类中心的距离;
- 将各样本回归于与之距离最近的聚类中心;
- 求各个类的样本的均值,作为新的聚类中心;
- 判定:若类中心不再发生变动或者达到迭代次数,算法结束,否则回到第二步。
**
三、k-means算法的描述如下
**
当任意一个点的簇分配结果发生改变时,对数据集中的每个点,对每个质心,计算质心与数据点之间的距离将数据点分配到距离其最近的簇对每一个簇,计算簇中所有点的均值并将均值作为质心。
**
四、代码如下
**
bool KMeans::Cluster()
{
std::vector<st_pointxyz> v_center(mv_center.size());
do
{
for (int i = 0, pntCount = mv_pntcloud.size(); i < pntCount; ++i)
{
double min_dist = DBL_MAX;
int pnt_grp = 0;
for (int j = 0; j < m_k; ++j)
{
double dist = DistBetweenPoints(mv_pntcloud[i].pnt, mv_center[j]);
if (min_dist - dist > 0.000001)
{
min_dist = dist;
pnt_grp = j;
}
}
m_grp_pntcloud[pnt_grp].push_back(st_point(mv_pntcloud[i].pnt, pnt_grp));
}
//保存上一次迭代的中心点
for (size_t i = 0; i < mv_center.size(); ++i)
{
v_center[i] = mv_center[i];
}
if (!UpdateGroupCenter(m_grp_pntcloud, mv_center))
{
return false;
}
if (!ExistCenterShift(v_center, mv_center))
{
break;
}
for (int i = 0; i < m_k; ++i){
m_grp_pntcloud[i].clear();
}
} while (true);
return true;
}