基于Python的K-means聚类算法

来源:互联网 发布:英国大城市知乎 编辑:程序博客网 时间:2024/05/19 09:38

K-means聚类的基本原理就不多阐述了,这里直接讲解如何实现。


效果图(红色节点代表聚类中心,蓝色节点和绿色节点代表不同的两类):






可以看到,初始时绿色节点很少且大多聚集于左下方,随着聚类中心的移动,绿色节点区域越来越大,直到最后会稳定下来。


一、建节点类

由于该聚类算法是基于二维的,因此基本元素就是节点,这里就将每个节点作为一个类Node。

其中nearest_node是一个list,其含义是:

①如果该节点是普通节点,则存储其归属的聚类中心;

②如果该节点是聚类中心,则存储对应的普通节点。

class Node:x = 0y = 0distance = 0nearest_node = []def __init__(self):self.x = random.uniform(0, 1)self.y = random.uniform(0, 1)self.nearest_node = []def distance(self, Node):x1 = (self.x - Node.x) * (self.x - Node.x)y1 = (self.y - Node.y) * (self.y - Node.y)distance = math.sqrt(x1 + y1)return distance

二、计算节点归于哪个聚类中心

利用Node类中的distance方法计算每个普通节点归属于哪个聚类中心。

for i in range(0, len(node)):min = 999index = 0for j in range(0, len(center)):if node[i].distance(center[j]) < min:min = node[i].distance(center[j])index = jcenter[index].nearest_node.append(node[i])node[i].nearest_node.append(center[index])


三、更新聚类中心位置

对每一个聚类中心而已,找到其对应的所有普通节点,求出它们的平均位置(即x坐标和y坐标的位置)。

接着就以这个平均位置作为自身新的位置。

for i in range(0, len(center)):x_total = 0y_total = 0x_new = 0y_new = 0for item in center[i].nearest_node:x_total += item.xy_total += item.yprint x_totalprint y_totalx_new = x_total / len(center[i].nearest_node)y_new = y_total / len(center[i].nearest_node)center[i].x = x_newcenter[i].y = y_new

四、画出拓扑图,标记聚类中心

如果是聚类中心,则用红色节点表示;

如果是第一类普通节点,则用蓝色节点表示;

如果是第二类普通节点,则用绿色节点表示。

for item in node:if item.nearest_node[0] == center[0]:plt.plot(item.x, item.y, 'bo')if item.nearest_node[0] == center[1]:plt.plot(item.x, item.y, 'go')item.nearest_node = []for item in center:plt.plot(item.x, item.y, 'ro')item.nearest_node = []plt.show()


源码:https://github.com/qjzhzw/K-means