K-means算法的实现

K-MEANS算法是一种经典的聚类算法,在模式识别得到了广泛的应用。算法中有两个关键问题需要考虑:一是如何评价对象的相似性,通常用距离来度量,距离越近越相似;另外一个是如何评价聚类的效果,通常采用误差平方和函数来作为评价准则。

算法过程:

输入:簇的数目K和包含n个对象的数据库。

输出:K个簇,使平方误差和最小

算法步骤:

(1):为每个聚类确定一个初始聚类中心,这样就有K个初始聚类中心

(2:将样本集中的样本按照最小距离原则分配到最邻近聚类

(3);使用每个聚类中的样本均值作为新的聚类中心

 (4):重复步骤(2)和(3),直到聚类中心不在变化

(5):结束,得到K个聚类

流程图

代码实现

  1 import numpy
  2 import random
  3 import codecs
  4 import copy
  5 import re
  6 import matplotlib.pyplot as plt
  7 #其次计算向量vecl和向量vec2之间的欧式距离
  8 def calcuDistance(vec1,vec2):
  9     return numpy.sqrt(numpy.sum(numpy.square(vec1-vec2)))
 10 #载入数据测试数据集,数据由文本保存,为二维坐标
 11 def loadDataSet():
 12     inFile = "F:/testSet.txt"  #数据集文件
 13     inDate = codecs.open(inFile,'r','utf-8').readlines()
 14     dataSet = list()
 15     for line in inDate:
 16         line = line.strip()
 17         strList = re.split('[ ]+',line) #删除多余的空格
 18                                         #print strList[0] ,strList[1]
 19         numList = list()
 20         for item in strList:
 21             num = float(item)
 22             numList.append(num)
 23 
 24         dataSet.append(numList)
 25     return dataSet
 26 
 27 #初始化K个聚类中心,随机获取
 28 def initCentroids(dataSet,k):
 29     return random.sample(dataSet,k)#从dataSe中随机获取K个数据项返回
 30 #对每个属于dataSet的item,计算item与centrodList中K个聚类中心的欧式距离,找出
 31 #距离最小的,并将item加入相应的簇中
 32 def minDistance(dataSet,centroidList):
 33     clusterDict = dict()  #用dict来保存聚类的结果
 34     for item in dataSet:
 35         vec1 = numpy.array(item) #转换成array形式
 36         flag = 0     #簇分类标记,记录与相应的簇距离最近的那个簇
 37         minDis = float("inf") #初始化为最大值
 38         for i in range(len(centroidList)):
 39             vec2 = numpy.array(centroidList[i])
 40             distance = calcuDistance(vec1,vec2) #计算相应的欧拉距离
 41             if distance < minDis:
 42                 minDis = distance
 43                 flag = i  #循环结束时,flag保存的是与当前item距离最近的那个簇标记
 44         if flag not in clusterDict.keys():#簇标记不存在,进行初始化
 45             clusterDict[flag] = list()
 46             clusterDict[flag].append(item) #加入相应的类别中
 47         return clusterDict
 48 
 49 #计算每列的均值,即找到聚类中心
 50 def getCentroids(clusterDict):
 51     #得到K个质心
 52     centroidList = list()
 53     for key in clusterDict.keys():
 54         centroid = numpy.mean(numpy.array(clusterDict[key]),axis=0)
 55         centroidList.append(centroid)
 56     return numpy.array(centroidList).tolist()
 57 #计算簇集合间的均方误差,将簇类中各个向量与质心的距离进行累加求和
 58 def getVar(clusterDict,centroidList):
 59     sum = 0.0
 60     for key in clusterDict.keys():
 61         vec1 = numpy.array(centroidList[key])
 62         distance = 0.0
 63         for item in clusterDict[key]:
 64             vec2 = numpy.array(item)
 65             distance += calcuDistance(vec1,vec2)
 66         sum += distance
 67     return sum
 68 
 69 #展示聚类结果
 70 def showCluster(centroidList,clusterDict):
 71     colorMark = ['or','ob','og','ok','oy','ow']
 72     #不同簇类的标记,'or'-->'o'代表圆形,’r'代表red,‘b’:blue
 73     centroidMark = ['dr','db','dg','dk','dy','dw'] #簇类中心标记同上‘d’代表菱形
 74     for key in clusterDict.keys():#画簇类中心点
 75         plt.plot(centroidList[key][0],centroidList[key][1],centroidMark[key],markersize=12)
 76         for item in clusterDict[key]:
 77             plt.plot(item[0],item[1],colorMark[key])#画簇类下的点
 78     plt.show()
 79 
 80 if __name__=='__main__':
 81 #    inFile = "F:/testSet.txt"  #数据集文件
 82     dataSet = loadDataSet() #载入数据集
 83     centroidList = initCentroids(dataSet,4) #初始化质心,设置K=4
 84     clusterDict = minDistance(dataSet,centroidList) #第一次聚类迭代
 85     newVar = getVar(clusterDict,centroidList) #获得均方误差值,通过新旧均方误差来获得迭代终止条件
 86     oldVar = -0.0001 #旧均方误差值初始化为-1
 87     print("------第一次迭代------")
 88     print( )
 89     print("簇类")
 90     for key in clusterDict.keys():
 91         print(key,'---->',clusterDict[key])
 92     print("K个均值向量:",centroidList)
 93     print("平方均方误差:",newVar)
 94     print( )
 95     showCluster(centroidList,clusterDict) #展示聚类结果
 96     k = 2
 97     while abs(newVar-oldVar) >= 0.0001: #当两次聚类结果小于0.0001时,迭代结束
 98         centroidList = getCentroids(clusterDict) #获得新的质心
 99         clusterDict = minDistance(dataSet,centroidList) #新的聚类结果
100         oldVar = newVar
101         newVar = getVar(clusterDict,centroidList)
102         print("----第%d次迭代结果--------" %k)
103         print( )
104         print("簇类")
105         for key in clusterDict.keys():
106             print(key, '---->', clusterDict[key])
107         print("K个均值向量:", centroidList)
108         print("平方均方误差:", newVar)
109         print()
110         showCluster(centroidList, clusterDict)  # 展示聚类结果
111         k += 1

目前,对于聚类算法的理解还不是很深刻。正在慢慢探索中。

转载于:https://www.cnblogs.com/tianqianlan/p/9963865.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值