K-means详解及python实现

原创 2018年04月17日 11:15:04

K-means算法是很典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。


算法过程如下:

1)从N个文档随机选取K个文档作为质心

2)对剩余的每个文档测量其到每个质心的距离,并把它归到最近的质心的类

3)重新计算已经得到的各个类的质心

4)迭代2~3步直至新的质心与原质心相等或小于指定阈值,算法结束

具体如下:

输入:k, data[n];

(1) 选择k个初始中心点,例如c[0]=data[0],…c[k-1]=data[k-1];

(2) 对于data[0]….data[n],分别与c[0]…c[k-1]比较,假定与c[i]差值最少,就标记为i;

(3) 对于所有标记为i点,重新计算c[i]={ 所有标记为i的data[j]之和}/标记为i的个数;

(4) 重复(2)(3),直到所有c[i]值的变化小于给定阈值

python代码如下:

# file name: K_means
# function: K_均值聚类算法
# author: 宋志勇
# time:2017.10.07


# -*- coding: UTF-8 -*-
import numpy
import random
import matplotlib.pyplot as plt


def findCentroids(data_get, k):    # 随机获取k个质心

    return random.sample(data_get, k)


def calculateDistance(vecA, vecB):    # 计算向量vecA和向量vecB之间的欧氏距离

    return numpy.sqrt(numpy.sum(numpy.square(vecA - vecB)))


def minDistance(data_get, centroidList):
    # 计算data_get中的元素与centroidList中k个聚类中心的欧式距离,找出距离最小的
    # 将该元素加入相应的聚类中

    clusterDict = dict()  # 用字典存储聚类结果
    for element in data_get:
        vecA = numpy.array(element)  # 转换成数组形式
        flag = 0  # 元素分类标记,记录与相应聚类距离最近的那个类
        minDis = float("inf")  # 初始化为最大值

        for i in range(len(centroidList)):
            vecB = numpy.array(centroidList[i])
            distance = calculateDistance(vecA, vecB)  # 两向量间的欧式距离
            if distance < minDis:
                minDis = distance
                flag = i  # 保存与当前item距离最近的那个聚类的标记

        if flag not in clusterDict.keys():  # 簇标记不存在,进行初始化
            clusterDict[flag] = list()
        clusterDict[flag].append(element)  # 加入相应的类中

    return clusterDict  # 返回新的聚类结果


def getCentroids(clusterDict):

    centroidList = list()
    for key in clusterDict.keys():
        centroid = numpy.mean(numpy.array(clusterDict[key]), axis=0)  # 求聚类中心即求解每列的均值
        centroidList.append(centroid)

    return numpy.array(centroidList).tolist()


def calculate_Var(clusterDict, centroidList):
    # 计算聚类间的均方误差
    # 将类中各个向量与聚类中心的距离进行累加求和

    sum = 0.0
    for key in clusterDict.keys():
        vecA = numpy.array(centroidList[key])
        distance = 0.0
        for item in clusterDict[key]:
            vecB = numpy.array(item)
            distance += calculateDistance(vecA, vecB)
        sum += distance

    return sum


def showCluster(centroidList, clusterDict):
    # 画聚类结果

    colorMark = ['or', 'ob', 'og', 'ok', 'oy', 'ow']  # 元素标记
    centroidMark = ['dr', 'db', 'dg', 'dk', 'dy', 'dw']  # 聚类中心标记
    for key in clusterDict.keys():
        plt.plot(centroidList[key][0], centroidList[key][1], centroidMark[key], markersize=12)  # 画聚类中心
        for item in clusterDict[key]:
            plt.plot(item[0], item[1], colorMark[key])  # 画类下的点

    plt.show()


data = [[0.0, 0.0], [3.0, 8.0], [2.0, 2.0], [1.0, 1.0], [5.0, 3.0],
        [4.0, 8.0], [6.0, 3.0], [5.0, 4.0], [6.0, 4.0], [7.0, 5.0]]


if __name__ == '__main__':

    centroidList = findCentroids(data, 3)  # 随机获取3个聚类中心
    clusterDict = minDistance(data, centroidList)  # 第一次聚类迭代
    newVar = calculate_Var(clusterDict, centroidList)  # 计算均方误差值,通过新旧均方误差来获得迭代终止条件
    oldVar = -0.0001  # 初始化均方误差

    print('***** 第1次迭代 *****')
    for key in clusterDict.keys():
        print('聚类中心: ', centroidList[key])
        print('对应聚类: ',clusterDict[key])
    print('平均均方误差: ', newVar)
    showCluster(centroidList, clusterDict)  # 展示聚类结果

    k = 2
    while abs(newVar - oldVar) >= 0.0001:  # 当连续两次聚类结果差距小于0.0001时,迭代结束
        centroidList = getCentroids(clusterDict)  # 获得新的聚类中心
        clusterDict = minDistance(data, centroidList)  # 新的聚类结果
        oldVar = newVar
        newVar = calculate_Var(clusterDict, centroidList)

        print('***** 第%d次迭代 *****' % k)

        for key in clusterDict.keys():
            print('聚类中心: ', centroidList[key])
            print('对应聚类: ', clusterDict[key])
        print('平均均方误差: ', newVar)
        showCluster(centroidList, clusterDict)  # 展示聚类结果

        k += 1

得到的结果如下


Python实现K-Means聚类算法

一、算法简介 1、K-Means算法是硬聚类算法,是典型的基于原型的目标函数聚类方法的代表,它是数据点到原型的某种距离作为优化的目标函数,利用函数求极值的方法得到迭代运算的调整规则。 2、K-Mean...
  • u013063099
  • u013063099
  • 2017-02-27 16:43:29
  • 1285

k-means算法Python

  • 2015年12月08日 22:07
  • 115KB
  • 下载

k-means python实现及数据.zip

  • 2018年03月19日 22:41
  • 13KB
  • 下载

python实现的k-means算法

  • 2009年06月15日 12:24
  • 3KB
  • 下载

聚类之均值聚类(k-means)算法的python实现

聚类之均值聚类(k-means)算法的python实现    最近在学习机器学习算法,主要参考了周志华老师的《机器学习》这本教材。最近读了聚类这一章节,为了加深对机器学习算法的了解,用python实现...
  • u013266697
  • u013266697
  • 2016-10-16 19:08:28
  • 8688

Python实现K-means聚类算法

  • 2014年05月27日 09:11
  • 5KB
  • 下载

k-means算法详解

k-means算法详解 主要内容 k-means算法简介 k-means算法详解 k-means算法优缺点分析 1、k-means算法简介   k-means算法是一种聚类算法,所谓聚类,即根据相...
  • zhihua_oba
  • zhihua_oba
  • 2017-06-28 11:04:39
  • 1353

机器学习实战——python实现k-means聚类算法

k-means聚类算法k-means是发现给定数据集的k个簇的算法,也就是将数据集聚合为k类的算法。算法过程如下: 1)从N个文档随机选取K个文档作为质心 2)对剩余的每个文档测量其到每个质心的距离,...
  • chenge_j
  • chenge_j
  • 2017-05-12 17:15:32
  • 906

机器学习算法---无监督学习,k-means聚类

聚类属于无监督学习,以往的回归、朴素贝叶斯、SVM等都是有类别标签y的,也就是说样例中已经给出了样例的分类。而聚类的样本中却没有给定y,只有特征x,比如假设宇宙中的星星可以表示成三维空间中的点集。聚类...
  • chinwuforwork
  • chinwuforwork
  • 2016-06-12 11:41:02
  • 1356

机器学习笔记-聚类分析之K-means算法案例及其Python实现

引言: 数据挖掘的本质是“计算机根据已有的数据做出决策”,其对社会的价值不必多言,相关的应用已经有很多,包括垃圾邮件拦截、客户价值分析等。 尽管数据挖掘实现过程的细节千差万别,但是从思路来...
  • lilu916
  • lilu916
  • 2017-06-10 17:46:30
  • 3412
收藏助手
不良信息举报
您举报文章:K-means详解及python实现
举报原因:
原因补充:

(最多只允许输入30个字)