机器学习算法-K-means聚类
2015-06-03 12:30
316 查看
引文: k均值算法是一种聚类算法,所谓聚类,他是一种无监督学习,将相似的对象归到同一个蔟中。蔟内的对象越相似,聚类的效果越好。聚类和分类最大的不同在于,分类的目标事先已知,而聚类则不一样。因为其产生的结果和分类相同,而只是类别没有预先定义。
算法的目的: 使各个样本与所在类均值的误差平方和达到最小(这也是评价K-means算法最后聚类效果的评价标准)
K-均值聚类
优点:容易实现
缺点:可能收敛到局部最小值,在大规模数据上收敛较慢
适合数据类型:数值型数据
下面代码应写在一个py文件里,我这里写在kMeans.py文件中。
文件的头部引入numpy
数据集加载代码
因为在k均值算法中要计算点到质心的距离,所以这里将距离计算写成一个函数,计算欧几里得距离公式:
d=(x2−x1)2+...+(z2−z1)2−−−−−−−−−−−−−−−−−−−−−√d=\sqrt{(x_2-x_1)^2+...+(z_2-z_1)^2}
函数代码如下:
接下来初始化k个蔟的质心函数centroid
K-means算法
测试:
输出结果:
===================
[[-3.66087851 2.30869657]
[ 3.24377288 3.04700412]
[ 2.52577861 -3.12485493]
[-2.79672694 3.19201596]]
[[-3.78710372 -1.66790611]
[ 2.6265299 3.10868015]
[ 1.62908469 -2.92689085]
[-2.18799937 3.01824781]]
[[-3.53973889 -2.89384326]
[ 2.6265299 3.10868015]
[ 2.65077367 -2.79019029]
[-2.46154315 2.78737555]]
===================
上面的结果给出了四个质心。可以看出,经过3次迭代之后K-均值算法收敛。质心会保存在第一个返回值中,第二个是每个点的簇分布情况。
附件:
上面测试的数据集为:
算法的目的: 使各个样本与所在类均值的误差平方和达到最小(这也是评价K-means算法最后聚类效果的评价标准)
K-均值聚类
优点:容易实现
缺点:可能收敛到局部最小值,在大规模数据上收敛较慢
适合数据类型:数值型数据
伪代码
#创建k个点作为起始质心(经常随机选择) #当任意一个点的蔟分配结果发生变化时 #对数据集中的每个数据点 #对每个质心 #计算质心到数据点之间的距离 #将数据点分配到距其最近的蔟 #对每个蔟,计算蔟中所有点的均值并将均值作为质心
代码实现
因为我们用到的是数值类型的数据,这里编写一个加载数据集的函数,返回值是一个矩阵形式。下面代码应写在一个py文件里,我这里写在kMeans.py文件中。
文件的头部引入numpy
from numpy import *
数据集加载代码
# 加载数据集文件,没有返回类标号的函数 def loadDataSet(fileName): dataMat = [] openfile = open(fileName) for line in openfile.readlines(): curLine = line.strip().split('\t') floatLine = map(float,curLine) dataMat.append(floatLine) return dataMat
因为在k均值算法中要计算点到质心的距离,所以这里将距离计算写成一个函数,计算欧几里得距离公式:
d=(x2−x1)2+...+(z2−z1)2−−−−−−−−−−−−−−−−−−−−−√d=\sqrt{(x_2-x_1)^2+...+(z_2-z_1)^2}
函数代码如下:
# 计算两个向量的欧氏距离 def distEclud(vecA,vecB): return sqrt(sum(power(vecA-vecB,2)))
接下来初始化k个蔟的质心函数centroid
# 传入的数据时numpy的矩阵格式 def randCent(dataMat, k): n = shape(dataMat)[1] centroids = mat(zeros((k,n))) for j in range(n): minJ = min(dataMat[:,j]) # 找出矩阵dataMat第j列最小值 rangeJ = float(max(dataMat[:,j]) - minJ) #计算第j列最大值和最小值的差 #赋予一个随机质心,它的值在整个数据集的边界之内 centroids[:,j] = minJ + rangeJ * random.rand(k,1) return centroids #返回一个随机的质心矩阵
K-means算法
#k-均值算法 def kMeans(dataMat,k,distE = distEclud , createCent=randCent): m = shape(dataMat)[0] # 获得行数m clusterAssment = mat(zeros((m,2))) # 初试化一个矩阵,用来记录簇索引和存储误差 centroids = createCent(dataMat,k) # 随机的得到一个质心矩阵蔟 clusterChanged = True while clusterChanged: clusterChanged = False for i in range(m): #对每个数据点寻找最近的质心 minDist = inf; minIndex = -1 for j in range(k): # 遍历质心蔟,寻找最近的质心 distJ1 = distE(centroids[j,:],dataMat[i,:]) #计算数据点和质心的欧式距离 if distJ1 < minDist: minDist = distJ1; minIndex = j if clusterAssment[i,0] != minIndex: clusterChanged = True clusterAssment[i,:] = minIndex,minDist**2 print centroids for cent in range(k): #更新质心的位置 ptsInClust = dataMat[nonzero(clusterAssment[:,0].A==cent)[0]] centroids[cent,:] = mean(ptsInClust, axis=0) return centroids, clusterAssment
测试:
dataMat = mat(loadDataSet('testSet.txt')) kMeans(dataMat,4)
输出结果:
===================
[[-3.66087851 2.30869657]
[ 3.24377288 3.04700412]
[ 2.52577861 -3.12485493]
[-2.79672694 3.19201596]]
[[-3.78710372 -1.66790611]
[ 2.6265299 3.10868015]
[ 1.62908469 -2.92689085]
[-2.18799937 3.01824781]]
[[-3.53973889 -2.89384326]
[ 2.6265299 3.10868015]
[ 2.65077367 -2.79019029]
[-2.46154315 2.78737555]]
===================
上面的结果给出了四个质心。可以看出,经过3次迭代之后K-均值算法收敛。质心会保存在第一个返回值中,第二个是每个点的簇分布情况。
附件:
上面测试的数据集为:
1.658985 4.285136 -3.453687 3.424321 4.838138 -1.151539 -5.379713 -3.362104 0.972564 2.924086 -3.567919 1.531611 0.450614 -3.302219 -3.487105 -1.724432 2.668759 1.594842 -3.156485 3.191137 3.165506 -3.999838 -2.786837 -3.099354 4.208187 2.984927 -2.123337 2.943366 0.704199 -0.479481 -0.392370 -3.963704 2.831667 1.574018 -0.790153 3.343144 2.943496 -3.357075 -3.195883 -2.283926 2.336445 2.875106 -1.786345 2.554248 2.190101 -1.906020 -3.403367 -2.778288 1.778124 3.880832 -1.688346 2.230267 2.592976 -2.054368 -4.007257 -3.207066 2.257734 3.387564 -2.679011 0.785119 0.939512 -4.023563 -3.674424 -2.261084 2.046259 2.735279 -3.189470 1.780269 4.372646 -0.822248 -2.579316 -3.497576 1.889034 5.190400 -0.798747 2.185588 2.836520 -2.658556 -3.837877 -3.253815 2.096701 3.886007 -2.709034 2.923887 3.367037 -3.184789 -2.121479 -4.232586 2.329546 3.179764 -3.284816 3.273099 3.091414 -3.815232 -3.762093 -2.432191 3.542056 2.778832 -1.736822 4.241041 2.127073 -2.983680 -4.323818 -3.938116 3.792121 5.135768 -4.786473 3.358547 2.624081 -3.260715 -4.009299 -2.978115 2.493525 1.963710 -2.513661 2.642162 1.864375 -3.176309 -3.171184 -3.572452 2.894220 2.489128 -2.562539 2.884438 3.491078 -3.947487 -2.565729 -2.012114 3.332948 3.983102 -1.616805 3.573188 2.280615 -2.559444 -2.651229 -3.103198 2.321395 3.154987 -1.685703 2.939697 3.031012 -3.620252 -4.599622 -2.185829 4.196223 1.126677 -2.133863 3.093686 4.668892 -2.562705 -2.793241 -2.149706 2.884105 3.043438 -2.967647 2.848696 4.479332 -1.764772 -4.905566 -2.911070
相关文章推荐
- Python使用minidom读写xml的方法
- 这就是搜索引擎--读书笔记五--索引的建立与更新
- BZOJ3339 Rmq Problem
- 操作系统中的虚拟内存技术及其实现代码
- ipython 学习笔记 2 network graph--NetworkX
- Android-StartService和BoundService的区别
- 错误LifecyclePhaseNotFoundException,Unknown lifecycle phase "mvn". You must specify a valid lifecycle
- 详解JavaScript中循环控制语句的用法
- selenium登录脚本
- 记录一个JS异常Uncaught NotFoundError
- 為ListView的Item設置不同的布局.
- java个人学习笔记:类属性,类方法
- php 类自动载入的方法
- R语言将源码包编译为二进制文件
- gSoap访问Web Service 实例
- wxpython基本控件-静态文本控件
- Android-Service通知与线程
- Python实现程序的单一实例用法分析
- IOS银联支付的流程
- weblogic部署struts2项目访问action404错误