聚类-kmeans

在这里插入图片描述在这里插入图片描述

# -*- coding: utf-8 -*-
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd 

#计算距离
def GetDistance(v1,v2):
    distance =np.sqrt(np.sum( (v1-v2)**2))
    return distance
def kmeans(data,k):
    nSamples , dim =data.shape
    #初始化K个质心
    Centroids = np.zeros((k,dim))
    indexs = []
    indexs = np.random.randint(0,nSamples,size =k)
    Centroids = data[indexs , :]   
    ClusterData = np.array(np.zeros((nSamples,)),dtype = int)
    minIndex = 0
    ClusterChanged = True
    while ClusterChanged :
        #计算每个样本与质心的距离
        ClusterChanged = False
        for i in range(nSamples) :
            minDistance =1000000  #定义一个很大的值
            for j in range(k) :
                distance = GetDistance(data[i,:] , Centroids[j,:])
                if minDistance > distance :
                    minDistance = distance
                    minIndex = j #样本的归属
            if ClusterData[i,] != minIndex :
                ClusterChanged =True
                ClusterData[i,] = minIndex
        #更新质心
        for j in range(k) :
            clusterindexs = np.nonzero(ClusterData[:,] ==j)
            Centroids[j,] = np.mean(data[clusterindexs,:] , axis =1)
    ShowCluster(data, Centroids, ClusterData,k)
    return Centroids , ClusterData
def ShowCluster(data, Centroids, ClusterData,k) :
    markdata = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']  
    markcentroid = ['*r', '*b', '*g', '*k', '*b', '+b', 'sb', 'db', '<b', 'pb'] 
    if k  > len(markcentroid):
        print("类别超出索引")
        return 0
    nSameples, dim = data.shape
    #绘制每个样本点
    for i in range(nSameples) :
        plt.plot(data[i,0],data[i,1],markdata[ClusterData[i,]])
    #绘制质心
    for j in range(k):
        plt.plot(Centroids[j,0],Centroids[j,1],markcentroid[j],markersize = 20)
if __name__ == "__main__":
    filepath = "D:\ZS\study\PythonWorkPlace\聚类\kmeans.txt"
    data=np.genfromtxt(filepath , delimiter = " ")
    Centroids,clusterData = kmeans(data,5)