kmeans与kmeans++的python实现

一.kmeans聚类:

基本方法流程

1.首先随机初始化k个中心点

2.将每个实例分配到与其最近的中心点,开成k个类

3.更新中心点,计算每个类的平均中心点

4.直到中心点不再变化或变化不大或达到迭代次数

优缺点:该方法简单,执行速度较快。但其对于离群点处理不是很好,这是可以去除离群点。kmeans聚类的主要缺点是随机的k个初始中心点的选择不够严谨,因为是随机,所以会导致聚类结果准确度不稳定。

二.kmeans++聚类:

kmeans++方法是针对kmeans的主要缺点进行改进,通过在初始中心点的选择上改进不足。

中心点的选择:

1.首先随机选择一个中心点

2.计算每个点到与其最近的中心点的距离为dist,以正比于dist的概率,随机选择一个点作为中心点加入中心点集中,重复直到选定k个中心点

3.计算同kmeans方法

三.评估方法

误差平方和可以评估每次初始中心点选择聚类的优劣,公式如下:

计算每个点到它自己的类的中心点的距离的平方和,外层是不同类间的和。根据每次初始点的选择聚类结果计算SSE,SSE值越小结果越好。

四.代码

  1 #!/usr/bin/python
  2 # -*- coding: utf-8 -*-
  3 import math
  4 import codecs
  5 import random
  6
  7 #k-means和k-means++聚类,第一列是label标签,其它列是数值型数据
  8 class KMeans:
  9
 10     #一列的中位数
 11     def getColMedian(self,colList):
 12         tmp = list(colList)
 13         tmp.sort()
 14         alen = len(tmp)
 15         if alen % 2 == 1:
 16             return tmp[alen // 2]
 17         else:
 18             return (tmp[alen // 2] + tmp[(alen // 2) - 1]) / 2
 19
 20     #对数值型数据进行归一化,使用绝对标准分[绝对标准差->asd=sum(x-u)/len(x),x的标准分->(x-u)/绝对标准差,u是中位数]
 21     def colNormalize(self,colList):
 22         median = self.getColMedian(colList)
 23         asd = sum([abs(x - median) for x in colList]) / len(colList)
 24         result = [(x - median) / asd for x in colList]
 25         return result
 26
 27     ‘‘‘
 28     1.读数据
 29     2.按列读取
 30     3.归一化数值型数据
 31     4.随机选择k个初始化中心点
 32     5.对数据离中心点距离进行分配
 33     ‘‘‘
 34     def __init__(self,filePath,k):
 35         self.data={}#原始数据
 36         self.k=k#聚类个数
 37         self.iterationNumber=0#迭代次数
 38         #用于跟踪在一次迭代改变的点
 39         self.pointsChanged=0
 40         #误差平方和
 41         self.SSE=0
 42         line_1=True
 43         with codecs.open(filePath,‘r‘,‘utf-8‘) as f:
 44             for line in f:
 45                 # 第一行为描述信息
 46                 if line_1:
 47                     line_1=False
 48                     header=line.split(‘,‘)
 49                     self.cols=len(header)
 50                     self.data=[[] for i in range(self.cols)]
 51                 else:
 52                     instances=line.split(‘,‘)
 53                     column_0=True
 54                     for ins in range(self.cols):
 55                         if column_0:
 56                             self.data[ins].append(instances[ins])# 0列数据
 57                             column_0=False
 58                         else:
 59                             self.data[ins].append(float(instances[ins]))# 数值列
 60         self.dataSize=len(self.data[1])#多少实例
 61         self.memberOf=[-1 for x in range(self.dataSize)]
 62
 63         #归一化数值列
 64         for i in range(1,self.cols):
 65             self.data[i]=self.colNormalize(self.data[i])
 66
 67         #随机从数据中选择k个初始化中心点
 68         random.seed()
 69         #1.下面是kmeans随机选择k个中心点
 70         #self.centroids=[[self.data[i][r] for i in range(1,self.cols)]
 71         #                for r in random.sample(range(self.dataSize),self.k)]
 72         #2.下面是kmeans++选择K个中心点
 73         self.selectInitialCenter()
 74
 75         self.assignPointsToCluster()
 76
 77     #离中心点距离分配点,返回这个点属于某个类别的类型
 78     def assignPointToCluster(self,i):
 79         min=10000
 80         clusterNum=-1
 81         for centroid in range(self.k):
 82             dist=self.distance(i,centroid)
 83             if dist<min:
 84                 min=dist
 85                 clusterNum=centroid
 86         #跟踪改变的点
 87         if clusterNum!=self.memberOf[i]:
 88             self.pointsChanged+=1
 89         #误差平方和
 90         self.SSE+=min**2
 91         return clusterNum
 92
 93
 94     #将每个点分配到一个中心点,memberOf=[0,1,0,0,...],0和1是两个类别,每个实例属于的类别
 95     def assignPointsToCluster(self):
 96         self.pointsChanged=0
 97         self.SSE=0
 98         self.memberOf=[self.assignPointToCluster(i) for i in range(self.dataSize)]
 99
100     # 欧氏距离,d(x,y)=math.sqrt(sum((x-y)*(x-y)))
101     def distance(self,i,j):
102         sumSquares=0
103         for k in range(1,self.cols):
104             sumSquares+=(self.data[k][i]-self.centroids[j][k-1])**2
105         return math.sqrt(sumSquares)
106
107     #利用类中的数据点更新中心点,利用每个类中的所有点的均值
108     def updateCenter(self):
109         members=[self.memberOf.count(i) for i in range(len(self.centroids))]#得到每个类别中的实例个数
110         self.centroids=[
111             [sum([self.data[k][i] for i in range(self.dataSize)
112                   if self.memberOf[i]==centroid])/members[centroid]
113              for k in range(1,self.cols)]
114             for centroid in range(len(self.centroids))]
115
116     ‘‘‘迭代更新中心点(使用每个类中的点的平均坐标),
117     然后重新分配所有点到新的中心点,直到类中成员改变的点小于1%(只有不到1%的点从一个类移到另一类中)
118     ‘‘‘
119     def cluster(self):
120         done=False
121         while not done:
122             self.iterationNumber+=1#迭代次数
123             self.updateCenter()
124             self.assignPointsToCluster()
125             #少于1%的改变点,结束
126             if float(self.pointsChanged)/len(self.memberOf)<0.01:
127                 done=True
128         print("误差平方和(SSE): %f" % self.SSE)
129
130     #打印结果
131     def printResults(self):
132         for centroid in range(len(self.centroids)):
133             print(‘\n\nCategory %i\n=========‘ % centroid)
134             for name in [self.data[0][i] for i in range(self.dataSize)
135                 if self.memberOf[i]==centroid]:
136                 print(name)
137
138     #kmeans++方法与kmeans方法的区别就是初始化中心点的不同
139     def selectInitialCenter(self):
140         centroids=[]
141         total=0
142         #首先随机选一个中心点
143         firstCenter=random.choice(range(self.dataSize))
144         centroids.append(firstCenter)
145         #选择其它中心点,对于每个点找出离它最近的那个中心点的距离
146         for i in range(0,self.k-1):
147             weights=[self.distancePointToClosestCenter(x,centroids)
148                      for x in range(self.dataSize)]
149             total=sum(weights)
150             #归一化0到1之间
151             weights=[x/total for x in weights]
152
153             num=random.random()
154             total=0
155             x=-1
156             while total<num:
157                 x+=1
158                 total+=weights[x]
159             centroids.append(x)
160         self.centroids=[[self.data[i][r] for i in range(1,self.cols)] for r in centroids]
161
162     def distancePointToClosestCenter(self,x,center):
163         result=self.eDistance(x,center[0])
164         for centroid in center[1:]:
165             distance=self.eDistance(x,centroid)
166             if distance<result:
167                 result=distance
168         return result
169
170     #计算点i到中心点j的距离
171     def eDistance(self,i,j):
172         sumSquares=0
173         for k in range(1,self.cols):
174             sumSquares+=(self.data[k][i]-self.data[k][j])**2
175         return  math.sqrt(sumSquares)
176
177 if __name__==‘__main__‘:
178     kmeans=KMeans(‘filePath‘,3)
179     kmeans.cluster()
180     kmeans.printResults()
时间: 2024-10-26 02:58:20

kmeans与kmeans++的python实现的相关文章

K-Means clusternig example with Python and Scikit-learn(推荐)

https://www.pythonprogramming.net/flat-clustering-machine-learning-python-scikit-learn/ Unsupervised Machine Learning: Flat Clustering K-Means clusternig example with Python and Scikit-learn This series is concerning "unsupervised machine learning.&q

4. K-Means和K-Means++实现

1. K-Means原理解析 2. K-Means的优化 3. sklearn的K-Means的使用 4. K-Means和K-Means++实现 1. 前言 前面3篇K-Means的博文从原理.优化.使用几个方面详细的介绍了K-Means算法,本文用python算法,详细的为读者实现一下K-Means.代码是本人修改完成,效率虽远不及sklearn,但是它的作用是在帮助同学们能从代码中去理解K-Means算法.后面我会慢慢的把所有的机器学习方面的算法,尽我所能的去实现一遍. 2. KMeans

Kmeans、Kmeans++和KNN算法比較

K-Means介绍 K-means算法是聚类分析中使用最广泛的算法之中的一个.它把n个对象依据他们的属性分为k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高:而不同聚类中的对象相似度较小.其聚类过程能够用下图表示: 如图所看到的.数据样本用圆点表示,每一个簇的中心点用叉叉表示.(a)刚開始时是原始数据.杂乱无章,没有label,看起来都一样.都是绿色的. (b)如果数据集能够分为两类.令K=2.随机在坐标上选两个点,作为两个类的中心点.(c-f)演示了聚类的两种迭代.先划分,把每一个

Kmeans聚类算法及其 Python实现

python Kmeans聚类之后如何给数据贴上聚类的标签? 用了二分Kmeans 来聚类 质心和聚类的簇都得到了,不知道如何给每一条数据贴上具体的标签? 这个链接下的代码,可以作为参考: http://blog.csdn.net/fzch_struggling/article/details/45009097#算法实验 原文地址:https://www.cnblogs.com/eternallql/p/8127403.html

kmeans算法思想及其python实现

第十章 利用k-均值聚类算法对未标注的数据进行分组 一.导语 聚类算法可以看做是一种无监督的分类方法,之所以这么说的原因是它和分类方法的结果相同,区别它的类别没有预先的定义.簇识别是聚类算法中经常使用的一个概念,使用这个概念是为了对聚类的结果进行定义. 聚类算法几乎可以用于所有的对象,并且簇内的对象越相似,效果越好. 二.K-均值聚类算法的基本概念 K-均值聚类算法它的目的是将数据分成k个簇.它的一般过程是如下: 随机的选择k个数据点作为初始的质心 当任意一个簇的分配结果发生变化的情况下 对于每

K-means clustering (K-means聚类)

问题: K-所有值聚类是无监督学习算法 设数据集.当中,. 如果这个数据能够分为类. 把这个问题模型化: , 当中代表第类的聚点(中心点.均值). 该模型能够用EM算法进行训练: 初始化,. E步:固定.最小化,显然 . 当中. M步:固定.最小化 ,, . 直至收敛. ----------------------------------------------------- 以下介绍一款机器学习软件,便于理解各种机器学习算法,下载完后.解压. 第一步: 双击,进入图形界面. 第二步:在空白处,

Spark2.0机器学习系列之8: 聚类分析(K-Means,Bisecting K-Means,LDA,高斯混合模型)

在写这篇文章之前,先说一些题外话. 许多机器学习算法(如后面将要提到的LDA)涉及的数学知识太多,前前后后一大堆,理解起来不是那么容易. 面对复杂的机器学习模型,尤其是涉及大量数学知识的模型,我们往往要花费大量的时间和精力去推导数学算法(公式),如果过分沉湎于此会忽略了很多背后也许更重要的东西,正所谓只见树木,不见森林,而这是缺乏远见,是迷茫的. 我们需要深入理解模型背后的逻辑和所蕴含的或简或繁的思想.某些思想甚至可能是很美的思想,很伟大的思想.这些理解,使得面对复杂的问题时候,面对陌生问题时,

Python—kmeans算法学习笔记

一.   什么是聚类 聚类简单的说就是要把一个文档集合根据文档的相似性把文档分成若干类,但是究竟分成多少类,这个要取决于文档集合里文档自身的性质.下面这个图就是一个简单的例子,我们可以把不同的文档聚合为3类.另外聚类是典型的无指导学习,所谓无指导学习是指不需要有人干预,无须人为文档进行标注. 二.聚类算法:from sklearn.cluster import KMeans def __init__(self, n_clusters=8, init='k-means++', n_init=10,

二分kmeans python实现

今天要对一个1000个个记录,每个记录有n个属性的文本进行聚类,采用的是二分k均值方法. 算法思想: 我参考了Pang-Ning Tan数据挖掘导论里P317 相对于kmeans的优点是不受其初始质心的影响. #coding utf-8#python 3.4#2015-4-3#Fitz Yin #yinruyi.hm@gmail.comfrom sklearn.cluster import KMeans import numpy as np def makedict(f): #建立行号和每行数据