《机器学习实战》学习笔记-[13]-无监督学习-利用K-均值聚类对未标注数据分组
2017-08-13 17:27
1001 查看
《机器学习实战》学习笔记-[13]-无监督学习-利用K-均值聚类对未标注数据分组
一种无监督的分类学习(unsupervised classification)在不知道目标已知分类的(这正是与分类的最大不同)的前提下,将相似对象归到同一个类簇中。其中相似的度量需要相应的相似度计算方法。备注:无监督学习不需要训练过程
(2)K-均值聚类
寻找给定数据集的K个簇的算法,其中K是用户给定的,簇由质心(centroid,即簇中所有点的中心)描述。
优点:易于实现
缺点:可能收敛到局部最小值,在数据量大时收敛慢
数值类型:数值型
(3)算法流程
随机选择k个初识点作为质心
将数据集中的每个点分配到一个簇中(为每个点找到其最近的质点,“最近”的度量需要距离计算方法,比如欧式距离,其他距离可参考:机器学习中的各种距离)
每个簇的质心更新为该簇中所有点的均值
若本轮中有点的簇分配发生改变,重复2,直到所有点不再变化
备注这里随机选择可以在每一维度(特征)下,先计算改特征的最大和最小值,在此范围内随机产生K个值最为K个随机点该特质的取值
例如:
【[1(min),2,3]
。。。。
[2(max),3,4]】
对于第一个特征取1到2之间的K个随机数作为随机质点的第一列
伪代码如下:
(4)前面提到缺点:可能收敛到局部最小值,在数据量大时收敛慢,如何度量聚类的效果呢
为此,对于每个点的所属簇的结果以如下结构存储,对于每个点:[记录所属簇的序号,该点与簇质点的距离平方也叫误差平法和SSE(Sum of Squared Error)]。其中SSE值越小表示数据点越接近质心。
当SSE很大时,将最大SSE所在簇的点过滤出来,对这些点进行K=2的K-均值聚类,此时为保持K值不变,可以合并某两个簇
簇合并原则具体见(5)
(5)簇合并
方法1:合并最近质心
方法2:合并两个使得SSE增幅最小的质心(合并所有两两簇并计算SEE,取最佳)
测试:
5次循环后:
1
2
3
4
5
centroids:
[[-2.46154315 2.78737555]
[ 2.6265299 3.10868015]
[-3.53973889 -2.89384326]
[ 2.65077367 -2.79019029]]
clusterAssment:
[[ 1. 2.3201915 ]
[ 0. 1.39004893]
[ 3. 7.46974076]
[ 2. 3.60477283]
[ 1. 2.7696782 ]
[ 0. 2.80101213]
[ 3. 5.10287596]
。。。。。。
一、基础
(1)聚类一种无监督的分类学习(unsupervised classification)在不知道目标已知分类的(这正是与分类的最大不同)的前提下,将相似对象归到同一个类簇中。其中相似的度量需要相应的相似度计算方法。备注:无监督学习不需要训练过程
(2)K-均值聚类
寻找给定数据集的K个簇的算法,其中K是用户给定的,簇由质心(centroid,即簇中所有点的中心)描述。
优点:易于实现
缺点:可能收敛到局部最小值,在数据量大时收敛慢
数值类型:数值型
(3)算法流程
随机选择k个初识点作为质心
将数据集中的每个点分配到一个簇中(为每个点找到其最近的质点,“最近”的度量需要距离计算方法,比如欧式距离,其他距离可参考:机器学习中的各种距离)
每个簇的质心更新为该簇中所有点的均值
若本轮中有点的簇分配发生改变,重复2,直到所有点不再变化
备注这里随机选择可以在每一维度(特征)下,先计算改特征的最大和最小值,在此范围内随机产生K个值最为K个随机点该特质的取值
例如:
【[1(min),2,3]
。。。。
[2(max),3,4]】
对于第一个特征取1到2之间的K个随机数作为随机质点的第一列
伪代码如下:
创建K个点作为初始的质点(一般随机选择) 当任意一个点的簇分配结果发生变化:(也就是直到所有点的簇分配不再变化结束循环) 对于数据中每个数据点 对每个质心 计算质心与数据点之间的距离 将数据分配到距离最近的簇 对每个簇,利用本簇中所有点的均值作为新的质心
(4)前面提到缺点:可能收敛到局部最小值,在数据量大时收敛慢,如何度量聚类的效果呢
为此,对于每个点的所属簇的结果以如下结构存储,对于每个点:[记录所属簇的序号,该点与簇质点的距离平方也叫误差平法和SSE(Sum of Squared Error)]。其中SSE值越小表示数据点越接近质心。
当SSE很大时,将最大SSE所在簇的点过滤出来,对这些点进行K=2的K-均值聚类,此时为保持K值不变,可以合并某两个簇
簇合并原则具体见(5)
(5)簇合并
方法1:合并最近质心
方法2:合并两个使得SSE增幅最小的质心(合并所有两两簇并计算SEE,取最佳)
二、实现
from numpy import * import time import matplotlib.pyplot as plt def loadDataSet(filename): dataMat = [] fr = open(filename) for line in fr.readlines(): curLine = line.strip().split('\t') fltLine = list(map(float, curLine)) # 转为浮点数存储 dataMat.append(fltLine) return dataMat # 计算两个点间的欧式距离 def distEclud(vecA, vecB): return sqrt(sum(power(vecA - vecB,2))) # 随机质点生成 def randCent(dataSet, k): n = shape(dataSet)[1] # 列数,也即特征的个数 centroids = mat(zeros((k, n))) # k行,n维 for j in range(n): # 对每一特征维度 求随机数 minJ = min(dataSet[:, j]) rangeJ = float(max(dataSet[:, j]) - minJ) centroids[:,j] = mat(minJ + rangeJ * random.rand(k,1)) return centroids def kMeans(dataSet,k,distMeans = distEclud, createCent = randCent): m = shape(dataSet)[0] #待分簇的数据个数 clusterAssment = mat(zeros((m, 2))) #m个数据点的分类簇结果 #其中第一列是簇编号,第二列是SSE #产生随机k质点 centroids = createCent(dataSet,k) #直到所有点不能再改变簇 clusterChanged = True cnt = 0 while clusterChanged: clusterChanged = False cnt = cnt + 1 print(cnt) #对于每个点 for i in range(m): minDist = inf minIndex = -1 # 对所有质点计算距离,求最小距离和所在簇 for j in range(k): distJI = distMeans(centroids[j, :], dataSet[i, :]) if distJI < minDist: minDist = distJI minIndex = j # 判断本次循环,改点是否所属簇改变 if clusterAssment[i, 0] != minIndex: clusterChanged = True # 更新簇信息(不分区是否改变) clusterAssment[i, :] = minIndex, minDist ** 2 for centItr in range(k): # recalculate centroids ptsClust = dataSet[nonzero(clusterAssment[:, 0].A == centItr)[0]] centroids[centItr, :] = mean(ptsClust, axis=0) # 对列(本特质维度)求均值 return centroids, clusterAssment def showCluster(dataSet, k, centroids, clusterAssment): numSamples, dim = dataSet.shape if dim != 2: print("Sorry! I can not draw because the dimension of your data is not 2!") return 1 mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr'] if k > len(mark): print("Sorry! Your k is too large! please contact Zouxy") return 1 # draw all samples for i in range(numSamples): markIndex = int(clusterAssment[i, 0]) plt.plot(dataSet[i, 0], dataSet[i, 1], mark[markIndex]) mark = ['Dr', 'Db', 'Dg', 'Dk', '^b', '+b', 'sb', 'db', '<b', 'pb'] # draw the centroids for i in range(k): plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize=12) plt.show()
测试:
import os from numpy import * from ML_Learn.com.ML.Cluster.kMeans import kMeans #导入训练数据集 inputMat = mat(kMeans.loadDataSet(os.getcwd() + '/resource/testSet.txt')) centroids,clusterAssment = kMeans.kMeans(inputMat,4) print("centroids:\n",centroids) print("clusterAssment:\n",clusterAssment) kMeans.showCluster(inputMat, 4, centroids, clusterAssment)
5次循环后:
1
2
3
4
5
centroids:
[[-2.46154315 2.78737555]
[ 2.6265299 3.10868015]
[-3.53973889 -2.89384326]
[ 2.65077367 -2.79019029]]
clusterAssment:
[[ 1. 2.3201915 ]
[ 0. 1.39004893]
[ 3. 7.46974076]
[ 2. 3.60477283]
[ 1. 2.7696782 ]
[ 0. 2.80101213]
[ 3. 5.10287596]
。。。。。。
相关文章推荐
- 《机器学习实战》学习笔记-[14]-无监督学习-利用二分K-均值聚类对未标注数据分组
- 机器学习实战笔记-利用K均值聚类算法对未标注数据分组
- 机器学习实战 第十章 利用K-均值聚类算法对未标注数据分组
- 机器学习实战 - 读书笔记(10) - 利用K-均值聚类算法对未标注数据分组
- 《机器学习实战》笔记之十——利用K均值聚类算法对未标注数据分组
- 第10章 利用K-均值聚类算法对未标注数据分组
- 数据挖掘学习笔记1——系统聚类与K-均值聚类
- 利用K-均值聚类算法对未标注数据分组
- 第十章 利用k-均值聚类算法对未标注数据分组
- 《机器学习实战》学习笔记-[15]-无监督学习-利用Apriori进行关联分析
- 机器学习——利用K-均值聚类算法对未标注数据分组
- 机器学习之利用K b24b -均值聚类算法对未标注数据分组
- 【机器学习实战】 利用K-均值聚类算法对未标注数据分组
- 机器学习之利用K-均值聚类算法对未标注数据分组模型探讨
- [数据挖掘课程笔记]无监督学习——聚类(clustering)
- SQL Server 2008 学习笔记(二)利用语句修改数据表
- Flask学习总结笔记(12) -- 利用ajax进行前后端数据交互
- python-MySQL学习笔记-第四章-利用Connector/Python来查询数据
- 《机器学习实战》代码片段学习6 k均值聚类与二分k均值聚类
- Delphi 2010学习笔记(13)---数据类型(指针)---2011-01-20