65.9K
CodeProject 正在变化。 阅读更多。
Home

Python 和 PyGame 中的数据聚类模拟

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2012年4月23日

CPOL

2分钟阅读

viewsIcon

21403

downloadIcon

438

使用 Python 进行 2D 数据聚类,并在 PyGame 中进行模拟。

引言

在本文中,我将解释 K-均值算法的实现,该算法被广泛应用于机器学习。 上图中,左侧是未聚类的数据,而右侧是聚类成 10 个簇的数据。为此,我创建了两个文件

  1. pyDataCluster.py
  2. clusterSimulation.py

文件 1 包含 K-均值算法的实现类,文件 2 是使用 pyGame(Python 的游戏库)编写的模拟文件。 pyDataCluster 类返回聚类后的数据,因此数据也可以在控制台中查看。

背景

机器学习是人工智能的一个高级步骤。 与创建复杂的算法相比,使用大量的先前数据和简单的算法可以获得优化的结果。 这个过程是学习算法的基础。 聚类是一种将数据分组到类别中的过程。 为了对数据进行分组,可以根据具体情况采用不同的参数。 在 K-均值算法中,我们通过使用每个簇的平均值来进行聚类,该平均值是通过获取原始数据然后重复处理直到平均值稳定为止计算得出的。

基本工作流程

基本工作流程如下

  1. 获取数据。
  2. 设置所需的簇数。
  3. 创建一个空的二维数组来存储聚类后的数据。
  4. 对于每个簇,获取一个随机点值,该值将作为初始平均值。
  5. 对于每个点,计算相对于平均值的距离。
  6. 将该点放入距离最小的簇中。
  7. 重新计算每个簇的平均值并更新平均值。
  8. 使用更新后的平均值重复步骤 5,直到连续两次重复的平均值相等。

Using the Code

让我们看一下代码。

首先,是聚类类

要在您的代码中使用此类,请执行以下操作

from pyDataCluster import *

data=[]
groups=10
for i in range(5000):
    data.append([random.randint(1,500),random.randint(1,500)])
    
cluster = pyDataCluster(groups,data)   

这将随机初始化数据,并创建一个名为 cluster 的对象,该对象包含 10 个组和数据数组。

finalCluster = cluster.finalCluster() # return the final cluster
clus = cluster.createCluster() # will return a cluster but not final  

初始化

类构造函数将初始化类变量。

def __init__(self,numberOfCluster,Data,initialPoints=[]):
        '''
        Constructor
        '''
        self.Kgroups=numberOfCluster
        self.Data=Data
        self.Cluster=[]
        self.Kmeans=initialPoints
        self.initialMeanPositions()
        self.terminat=True

您可以传递初始点,也可以不传递。 initialMeanPositons() 将为您初始化。

创建簇

def createCluster(self):
        self.clusterSpace()
        for i in self.Data:
            point=[i[0],i[1]]
            group=self.getClusterGroup(point)
            self.Cluster[group].append(i)
        self.setMeans()
        return(self.Cluster)

此函数是该类的主力。 它将在给定的平均点上创建数据簇。 反复调用此函数可以得到更好的簇。

最终簇

要获取最终簇,这将完成这项工作

 def finalCluster(self):
        while self.terminat:
            clus=self.createCluster()
        return(clus)  

此函数将循环运行,直到 setMeans 函数发出终止信号。

setMeans

要设置平均值,此函数将按照基本工作流程中所述完成这项工作

def setMeans(self):
        means=[]
        x=0
        y=0
        for i in self.Cluster:
            for j in i:
                x=x+j[0]
                y=y+j[1]
            means.append([math.floor(x/len(i)),math.floor(y/len(i))])
            x=0
            y=0
        if(self.Kmeans==means):
            self.terminat=False
        self.Kmeans=[]
        self.Kmeans=means

分配簇组

此函数将返回给定点所属的组索引

def getClusterGroup(self,point):
        dist=[]
        for i in self.Kmeans:
            dist.append(math.fabs(point[0]-i[0])+math.fabs(point[1]-i[1]))
        minIndex = dist.index(min(dist))
        return minIndex

空簇

每次运行,您都需要一个空簇,此函数将清除任何旧值并创建一个空簇

 def clusterSpace(self):
        self.Cluster=[]
        for i in range(self.Kgroups):
            self.Cluster.append([])

到此为止,聚类完成,现在是模拟部分。

clusterSimulation

这需要 PyGame 库,可以从他们的网站下载。

import pygame, sys, time
from pygame.locals import *
from pyDataCluster import *

data=[]
groups=10
for i in range(5000):
    data.append([random.randint(1,500),random.randint(1,500)])
    
cluster = pyDataCluster(groups,data)
Color=[]
for i in range(groups):
    
    while True:
        cl=((random.randint(0,255)),(random.randint(0,255)),(random.randint(0,255)))
        if cl not in Color:   
            Color.append(cl)
            break
pygame.init()
WINDOWWIDTH = 500
WINDOWHEIGHT = 500
BASICFONT = pygame.font.Font('freesansbold.ttf',50)
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Cluster Simulation')

BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
WHITE=(255,255,255)

while cluster.terminat:
        points=[]
        
        clus=cluster.createCluster()
        a=0
        for i in clus:
            
            for j in i:
                points.append({'rect':pygame.Rect(j[0],j[1],4,4),'color':Color[a]})
            a=a+1
        for p in points:        
                pygame.draw.rect(windowSurface, p['color'], p['rect'])
        pygame.display.update()
    #time.sleep(0.05)

while True:
    # check for the QUIT event
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()  

尝试更改数据量和组数,以查看效果。

© . All rights reserved.