



Author:Yvette  明明就;Email:yvette.tsai22@gmail.com

# K-means面试题

## 1. 聚类算法（clustering Algorithms）介绍

聚类是一种无监督学习—对大量未知标注的数据集，按数据的内在相似性将数据集划分为多个类别，使类别内的数据相似度较大而类别间的数据相似度较小。

聚类算法可以分为原型聚类（k均值算法（K-means）、学习向量量化、（Learning Vector Quantization -LVQ）、高斯混合聚类（Mixture-of-Gaussian），密度聚类（DBSCAN），层次聚类（AGNES）等。

## 2. kmeans原理详解

K-means是一种常见的聚类算法，也叫k均值或k平均。通过迭代的方式，每次迭代都将数据集中的各个点划分到距离它最近的簇内，这里的距离即数据点到簇中心的距离。

kmean步骤：

1. 随机初始化k个簇中心坐标
2. 计算数据集内所有点到k个簇中心的距离，并将数据点划分近最近的簇
3. 更新簇中心坐标为当前簇内节点的坐标平均值
4. 重复2、3步骤直到簇中心坐标不再改变（收敛了）

## 3.  优缺点及改进算法

优点：效率高、适用于大规模数据集

| 缺点           | 改进      | 描述                                                         |
| -------------- | --------- | ------------------------------------------------------------ |
| k值的确定      | ISODATA   | 当属于某个簇的样本数过少时把这个簇去除，<br>当属于某个簇的样本数过多、分散程度较大时把这个簇分为两个子簇|
| 对奇异点敏感   | k-median  | 中位数代替平均值作为簇中心                                   |
| 只能找到球状群 | GMM       | 以高斯分布考虑簇内数据点的分布                               |
| 分群结果不稳定 | K-means++ | 初始的聚类中心之间的相互距离要尽可能的远                     |

## 4. k值的选取


K-means算法要求事先知道数据集能分为几群，主要有两种方法定义k。

- 手肘法：通过绘制k和损失函数的关系图，选拐点处的k值。

- 经验选取人工据经验先定几个k，多次随机初始化中心选经验上最适合的。

通常都是以经验选取，因为实际操作中拐点不明显，且手肘法效率不高。


## 5. K-means算法中初始点的选择对最终结果的影响


K-means选择的初始点不同获得的最终分类结果也可能不同，随机选择的中心会导致K-means陷入局部最优解。


## 6. 为什么在计算K-means之前要将数据点在各维度上归一化

因为数据点各维度的量级不同。
举个例子，最近正好做完基于RFM模型的会员分群，每个会员分别有R（最近一次购买距今的时长）、F（来店消费的频率）和M（购买金额）。如果这是一家奢侈品商店，你会发现M的量级（可能几万元）远大于F（可能平均10次以下），如果不归一化就算K-means，相当于F这个特征完全无效。如果我希望能把常客与其他顾客区别开来，不归一化就做不到。



## 7.  K-means不适用哪些数据


1. 数据特征极强相关的数据集，因为会很难收敛（损失函数是非凸函数），一般要用kernal K-means，将数据点映射到更高维度再分群。
2. 数据集可分出来的簇密度不一，或有很多离群值（outliers），这时候考虑使用密度聚类。


## 8.  K-means 中常用的距离度量


K-means中比较常用的距离度量是欧几里得距离和余弦相似度。


## 9. K-means是否会一直陷入选择质心的循环停不下来（为什么迭代次数后会收敛）？


从K-means的第三步我们可以看出，每回迭代都会用簇内点的**平均值**去更新簇中心，所以最终簇内的平方误差和（SSE, sum of squared error）一定最小。 平方误差和的公式如下：
$$
L(X) = \sum_{i=1}^{k}{\sum_{j\in C_i}{(x_{ij}-\bar{x_i})^2}}
$$

## 10. 聚类和分类区别


1. 产生的结果相同（将数据进行分类）
2. 聚类事先没有给出标签（无监督学习）


## 11. 如何对K-means聚类效果进行评估


回到聚类的定义，我们希望得到**簇内数据相似度尽可能地大，而簇间相似度尽可能地小**。常见的评估方式：

|                   名称               |                            公式                           |  含义  |  如何比较   |
|:-------------------------------------| :------------------------------------------------------: | :----- | :----------- |
| sum of squares within clusters(SSW)  | $\sum_{i=1}^{K}{ \parallel x_i-c_{l_i} \parallel ^2}$    |所有簇内差异之和|越小越好|
| sum of squares between clusters(SSB) | $\sum_{i=1}^{K}{n_i \parallel c_i-\bar{x} \parallel ^2}$ |簇心与簇内均值差异的加权和|越大越好|
|Calinski-Harabasz                     | $\frac{\frac{SSB}{K-1}}{\frac{SSW}{N-K}}$                       |簇间距离和簇内距离之比（除数是惩罚项，因为SSW下降地比较快）|越大越好 |
|Ball&Hall                             |$\frac{SSW}{K}$                                           | 几乎同SSW|越小越好|
|Dunn’s index                          | $\frac{\min_{i=1}^M{\min_{j=i+1}^M{d(c_i, c_j)}}}{\max_{k=1}^M{diam(c_k)}}$ <br/>$where d(c_i, c_j)=\min_{x \in c_i, x' \in c_j}{\parallel x-x' \parallel}^2 and$ <br/> $diam(c_k)=\max_{x, x' \in c_k}{\parallel x-x' \parallel}^2$ |本质上也是簇间距离和簇内距离之比|越大越好|


另一个常见的方法是画图，将不同簇的数据点用不同颜色表示。这么做的好处是最直观，缺点是无法处理高维的数据，它最多能展示三维的数据集。
如果维数不多也可以做一定的降维处理（PCA）后再画图，但会损失一定的信息量。 

聚类算法几乎没有统一的评估指标，可能还需要根据聚类目标想评估方式，如对会员作分群以后，我想检查分得的群体之间是否确实有差异，这时候可以用MANOVA计算，当p值小于0.01说明分群合理。

## 12. K-means中空聚类的处理


如果所有的点在指派步骤都未分配到某个簇，就会得到空簇。如果这种情况发生，则需要某种策略来选择一个替补质心，否则的话，平方误差将会偏大。一种方法是选择一个距离当前任何质心最远的点。这将消除当前对总平方误差影响最大的点。另一种方法是从具有最大SEE的簇中选择一个替补的质心。这将分裂簇并降低聚类的总SEE。如果有多个空簇，则该过程重复多次。另外编程实现时，要注意空簇可能导致的程序bug。


## 参考资料

1. Mann A K, Kaur N. Review paper on clustering techniques[J]. Global Journal of Computer Science and Technology, 2013.
2. https://blog.csdn.net/hua111hua/article/details/86556322
3. REZAEI M. Clustering validation[J].
