K-means(K均值)算法 简单实现 二维/三维结果展示

1. 简介

k-means算法是一种聚类算法,所谓聚类,即根据相似性原则,将具有较高相似度的数据对象划分至同一类簇,将具有较高相异度的数据对象划分至不同类簇。
聚类与分类最大的区别在于,聚类过程为无监督过程,即待处理数据对象没有任何先验知识,而分类过程为有监督过程。

k-means是最简单的聚类算法之一,应用十分广泛,k代表类簇个数,means代表类簇内数据对象的均值。
k-means以距离作为相似性的评价指标,其基本思想是按照样本之间的距离将样本聚成不同的簇,两个样本的距离越近,其相似度就越大,则它们越有可能在同一个类簇,从而得到独立的簇作为聚类目标。
样本数据对象间距离的计算有很多种,k-means算法通常采用欧氏距离来计算数据对象间的距离。
具体算法流程 参见:https://blog.csdn.net/mrharvey/article/details/18085163

2.代码实现

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

size = 30 ##取值范围

##计算欧式距离
def distEuclid(x,y):
    return np.sqrt(np.sum((x-y)**2))

##随机产生n个dim维度的数据 (这里为了展示结果 dim取2或者3)
def genDataset(n,dim):
    data = []
    while len(data)<n:
        p = np.around(np.random.rand(dim)*size,decimals=2)
        data.append(p)
    return data

## 初始化簇中心点 一开始随机从样本中选择k个 当做各类簇的中心
def initCentroid(data,k):
    num,dim = data.shape
    centpoint = np.zeros((k,dim))
    l = [x for x in range(num)]
    np.random.shuffle(l)
    for i in range(k):
        index = int(l[i])
        centpoint[i] = data[index]
    return centpoint

##进行KMeans分类
def KMeans(data,k):
    ##样本个数
    num = np.shape(data)[0]
    
    ##记录各样本 簇信息 0:属于哪个簇 1:距离该簇中心点距离 
    cluster = np.zeros((num,2))
    cluster[:,0]=-1
    
    ##记录是否有样本改变簇分类
    change = True
    ##初始化各簇中心点
    cp = initCentroid(data,k)

    while change:
        change = False
        
        ##遍历每一个样本
        for i in range(num):
            minDist = 9999.9
            minIndex = -1
            
            ##计算该样本距离每一个簇中心点的距离 找到距离最近的中心点
            for j in range(k):
                dis = distEuclid(cp[j],data[i])
                if dis < minDist:
                    minDist = dis
                    minIndex = j
            
            ##如果找到的簇中心点非当前簇 则改变该样本的簇分类
            if cluster[i,0]!=minIndex:
                change = True
                cluster[i,:] = minIndex,minDist
        
        ## 根据样本重新分类  计算新的簇中心点
        for j in range(k):
            pointincluster = data[[x for x in range(num) if cluster[x,0]==j]]
            cp[j] = np.mean(pointincluster,axis=0)
    
    print("finish!")
    return cp,cluster

##展示结果  各类簇使用不同的颜色  中心点使用X表示
def Show(data,k,cp,cluster):
    num,dim = data.shape
    color = ['r','g','b','c','y','m','k']
    ##二维图
    if dim==2:
        for i in range(num):
            mark = int(cluster[i,0])
            plt.plot(data[i,0],data[i,1],color[mark]+'o')
            
        for i in range(k):
            plt.plot(cp[i,0],cp[i,1],color[i]+'x')
    ##三维图
    elif dim==3:
        ax = plt.subplot(111,projection ='3d')
        for i in range(num):
            mark = int(cluster[i,0])
            ax.scatter(data[i,0],data[i,1],data[i,2],c=color[mark])
            
        for i in range(k):
            ax.scatter(cp[i,0],cp[i,1],cp[i,2],c=color[i],marker='x')
        
    plt.show()


num = 50 ##点个数    
k=4 ##分类个数
data = np.array(genDataset(num,3))
cp,cluster = KMeans(data,k)
Show(data,k,cp,cluster)

3.结果

二维 随机50个点 k=4
K-means(K均值)算法 简单实现 二维/三维结果展示_第1张图片

三维 随机30个点 k=4
K-means(K均值)算法 简单实现 二维/三维结果展示_第2张图片

你可能感兴趣的:(MachineLearning,kmeans,python)