更新 k-means聚类文档

This commit is contained in:
jiangzhonglian
2017-09-07 20:41:22 +08:00
parent 057916303b
commit ba51c628cb

View File

@@ -20,7 +20,7 @@ K-Means 是发现给定数据集的 K 个簇的聚类算法, 之所以称之为
### K-Means 术语
* 簇: 簇中的对象是相似的.
* 簇: 所有数据点点集合,簇中的对象是相似的
* 质心: 簇中所有点的中心(计算所有点的均值而来).
* SSE: Sum of Sqared Error平方误差和, SSE 值越小,表示越接近它们的质心. 由于对误差取了平方,因此更加注重那么远离中心的点.
@@ -29,7 +29,7 @@ K-Means 是发现给定数据集的 K 个簇的聚类算法, 之所以称之为
![K-Means 术语图](../images/10.KMeans/apachecn-k-means-term-1.jpg)
### K-Means 工作流程
1. 首先, 随机确定 K 个初始点作为质心.
1. 首先, 随机确定 K 个初始点作为质心(不是数据中的点).
2. 然后将数据集中的每个点分配到一个簇中, 具体来讲, 就是为每个点找到距其最近的质心, 并将其分配该质心所对应的簇. 这一步完成之后, 每个簇的质心更新为该簇说有点的平均值.
上述过程的 `伪代码` 如下:
@@ -96,7 +96,7 @@ def randCent(dataSet, k):
```python
# k-means 聚类算法
# 该算法会创建k个质心然后将每个点分配到最近的质心再重新计算质心。
# 这个过程重复数次,知道数据点的簇分配结果不再改变位置。
# 这个过程重复数次,直到数据点的簇分配结果不再改变位置。
# 运行结果(多次运行结果可能会不一样,可以试试,原因为随机质心的影响,但总的结果是对的, 因为数据足够相似,也可能会陷入局部最小值)
def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
m = shape(dataSet)[0] # 行数
@@ -132,10 +132,10 @@ def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
### K-Means 聚类算法的缺陷
在 kMeans 的函数测试中,可能偶尔会陷入局部最小值(局部最优的结果,但不是全局最优的结果).
所以为了客户 KMeans 算法收敛于局部最小值的问题有更厉害的大佬提出了另一个称为二分K-均值bisecting K-Means的算法.
所以为了克服 KMeans 算法收敛于局部最小值的问题有更厉害的大佬提出了另一个称为二分K-均值bisecting K-Means的算法.
### 二分 K-Means 聚类算法
该算法首先将有点作为一个簇,然后将该簇一分为二。
该算法首先将有点作为一个簇,然后将该簇一分为二。
之后选择其中一个簇继续进行划分,选择哪一个簇进行划分取决于对其划分时候可以最大程度降低 SSE平方和误差的值。
上述基于 SSE 的划分过程不断重复,直到得到用户指定的簇数目为止。
@@ -170,7 +170,7 @@ def biKMeans(dataSet, k, distMeas=distEclud):
sseSplit = sum(splitClustAss[:,1]) # 将二分 kMeans 结果中的平方和的距离进行求和
sseNotSplit = sum(clusterAssment[nonzero(clusterAssment[:,0].A!=i)[0],1]) # 将未参与二分 kMeans 分配结果中的平方和的距离进行求和
print "sseSplit, and notSplit: ",sseSplit,sseNotSplit
if (sseSplit + sseNotSplit) < lowestSSE:
if (sseSplit + sseNotSplit) < lowestSSE: # 总的(未拆分和已拆分)误差和越小,越相似,效果越优化,划分的结果更好(注意:这里的理解很重要,不明白的地方可以和我们一起讨论)
bestCentToSplit = i
bestNewCents = centroidMat
bestClustAss = splitClustAss.copy()