机器学习——聚类(clustering):K-means算法(非监督学习)
来源:互联网 发布:怎样成为数据分析师 编辑:程序博客网 时间:2024/06/16 11:44
1、归类
聚类(clustering):属于非监督学习(unsupervised learning),是无类别标记(class label)
2、举例
3、K-means算法
(1)K-means算法是聚类(clustering)中的经典算法,数据挖掘的十大经典算法之一
(2)算法接收参数K,然后将事先输入的n个数据划分为K个聚类以便使得所获得的聚类满足:
同一聚类中的对象相似度较高,而不同聚类中的对象相似度较低。
(3)算法思想:以空间中K个点作为中心进行聚类,对最靠近它们的对象进行归类;
通过迭代的方法,逐渐更新各聚类中心的值,直至得到最好的聚类结果。
(4)算法的描述:
a、适当选择c个类的初始中心
b、在第K次迭代中,对任意一个样本,求其到c各中心的距离,将该样本归类到距离最短的中心所在的类。
c、利用均值等方法更新该类的中心值
d、对所有的c个聚类中心,如果利用b、c的迭代更新后,值保持不变,则迭代结束;否则继续迭代。
(5)算法的流程:
输入K,data[n]
a、选择K个初始中心,例如:c[0] = data[0],...,c[k-1] = data[k-1];
b、对于data[0]......data[n]分别c[0].....c[k-1]进行比较,假定与c[i]距离最小,就标记为i;
c、对于所有标记为i点,重新计算中心点c[i] = {所有标记为i的data[i]之和}/标记为i的个数;
d、重复b、c,直到所有的c[i]的值的变化小于给定的阈值。
4、举例
举例:将下面的4颗药分成两类,K值即为:2。
这里给出的特征值是2维的,可以表示在一个平面上;不论是几维的向量,都可以在一个超平面上表示出来。
(1)初始两类中心点分别为A(1,1)、B(2,1),对4个点分别计算到2个中心点的欧式距离,距离哪个类的距离小,就归为那一类。
矩阵D的第一行表示:4个点到第一个类中心(1,1)的距离,第二行表示:4个点到第二个类中心(2,1)的距离。
比较每个点到两类的距离,归为距离小的类,得到归类的矩阵如下:1表示:归为此类;0表示:不归为此类。
第一次归类结果为:A归为:第一类;B、C、D归为第二类。
(2)利用均值,重新计算每个聚类中心点坐标
c1=(1,1);c2 = ((2+4+5)/3,(1+3+4)/3)=(11/3,8/3)
更新每个聚类中心点坐标之后如下图:
(3)再次计算4个点到新的聚类中心点的距离,第二次归类结果为:A、B归为:第一类;C、D归为第二类。
(4)继续迭代,求新的聚类中心的坐标,继续分类,直到分类结果不再发生变化。
(5)最终的分类结果:A、B归为:第一类;C、D归为第二类。
5、K-means算法的优缺点:
优点:速度快、简单
缺点:最终结果跟初始点选择相关,容易陷入局部最优,需要知道K值,有可能在分类之前不知道要分成几类。
6、在Python中实现K-means算法的上述实例
(1)随机选取初始化中心点的情况
#!/usr/bin/env python# -*- coding:utf-8 -*-# Author:ZhengzhengLiuimport numpy as np#x:数据集是一个numpy数组(每行代表一个数据点,每列代表一个特征值),k:分类数,maxIt:迭代次数def kmeans(X,k,maxIt): numPoints, numDim = X.shape #返回数据集X的行数和列数 dataSet = np.zeros((numPoints,numDim+1)) #初始化新的数据集dataSet比X多一列,用来存放分标签 dataSet[:,:-1] = X #dataSet的所有行和除去最后一列的所有列的数值与X相同 #随机初始化k个中心点(利用randint函数从所有行实例中随机选出k个实例作为中心点) centroids = dataSet[np.random.randint(numPoints,size=k),:] #centroids = dataSet[0:2,:] #初始化前两个实例作为中心点(也可以随机选取初始化中心点) #为中心点最后一列初始化分类标记1到k centroids[:,-1] = range(1,k+1) iterations = 0 #循环次数 oldCentroids = None #旧的中心点 while not shouldStop(oldCentroids,centroids,iterations,maxIt): print("iterations:\n",iterations) #打印当前循环迭代次数 print("dataSet:\n",dataSet) #打印当前数据集 print("centroids:\n",centroids) #打印当前的中心 oldCentroids = np.copy(centroids) #将当前中心点赋值到旧中心点中 iterations += 1 #迭代次数加1 #依照中心点为每个实例归类 updateLabels(dataSet,centroids) #根据归类后数据集和k值,计算新的中心点 centroids = getCentroids(dataSet,k) return dataSet#迭代停止函数def shouldStop(oldCentroids,centroids,iterations,maxIt): if iterations > maxIt: return True #迭代次数比最大迭代次数大,则停止迭代 return np.array_equal(oldCentroids,centroids) #比较新旧中心点的值是否相等,相等返回True,迭代终止#依照中心点为每个实例归类def updateLabels(dataSet,centroids): numPoints, numDim = dataSet.shape #获取当前数据集的行列数 for i in range(0,numPoints): #当前行实例与中心点的距离最近的标记作为该实例的标记 dataSet[i,-1] = getLabelFromClosesCentroid(dataSet[i,:-1],centroids)def getLabelFromClosesCentroid(dataSetRow,centroids): label = centroids[0,-1] #初始化当前标记赋值为第一个中心点的标记(第一行最后一列) minDist = np.linalg.norm(dataSetRow - centroids[0,:-1]) #初始化计算当前行实例与第一个中心点实例的欧氏距离 for i in range(1,centroids.shape[0]): #遍历第二个到最后一个中心点 dist = np.linalg.norm(dataSetRow - centroids[i,:-1]) #计算当前行实例与每一个中心点实例的欧氏距离 if dist < minDist: minDist = dist label = centroids[i,-1] #若当前的欧氏距离比初始化的小,则取当前中心点的标记作为该实例标记 print("minDist:",minDist) return label##根据归类后数据集和k值,计算新的中心点def getCentroids(dataSet,k): #最后返回的新的中心点的值有k行,列数与dataSet相同 result = np.zeros((k,dataSet.shape[1])) for i in range(1,k+1): #将所有标记是当前同一类的实例的数据组成一个类 oneCluster = dataSet[dataSet[:,-1] == i,:-1] result[i-1,:-1] = np.mean(oneCluster,axis = 0) #对同一类的实例求均值找出新的中心点 result[i-1,-1] = i return resultx1 = np.array([1,1])x2 = np.array([2,1])x3 = np.array([4,3])x4 = np.array([5,4])testX = np.vstack((x1,x2,x3,x4)) #垂直方向合并numpy数组result = kmeans(testX,2,10)print("final result:",result)运行结果:
iterations: 0dataSet: [[ 1. 1. 0.] [ 2. 1. 0.] [ 4. 3. 0.] [ 5. 4. 0.]]centroids: [[ 5. 4. 1.] [ 2. 1. 2.]]minDist: 1.0minDist: 0.0minDist: 1.41421356237minDist: 0.0iterations: 1dataSet: [[ 1. 1. 2.] [ 2. 1. 2.] [ 4. 3. 1.] [ 5. 4. 1.]]centroids: [[ 4.5 3.5 1. ] [ 1.5 1. 2. ]]minDist: 0.5minDist: 0.5minDist: 0.707106781187minDist: 0.707106781187final result: [[ 1. 1. 2.] [ 2. 1. 2.] [ 4. 3. 1.] [ 5. 4. 1.]]
(2)初始化前两个实例作为中心点的情况
#!/usr/bin/env python# -*- coding:utf-8 -*-# Author:ZhengzhengLiuimport numpy as np#x:数据集是一个numpy数组(每行代表一个数据点,每列代表一个特征值),k:分类数,maxIt:迭代次数def kmeans(X,k,maxIt): numPoints, numDim = X.shape #返回数据集X的行数和列数 dataSet = np.zeros((numPoints,numDim+1)) #初始化新的数据集dataSet比X多一列,用来存放分标签 dataSet[:,:-1] = X #dataSet的所有行和除去最后一列的所有列的数值与X相同 #随机初始化k个中心点(利用randint函数从所有行实例中随机选出k个实例作为中心点) centroids = dataSet[np.random.randint(numPoints,size=k),:] centroids = dataSet[0:2,:] #初始化前两个实例作为中心点(也可以随机选取初始化中心点) #为中心点最后一列初始化分类标记1到k centroids[:,-1] = range(1,k+1) iterations = 0 #循环次数 oldCentroids = None #旧的中心点 while not shouldStop(oldCentroids,centroids,iterations,maxIt): print("iterations:\n",iterations) #打印当前循环迭代次数 print("dataSet:\n",dataSet) #打印当前数据集 print("centroids:\n",centroids) #打印当前的中心 oldCentroids = np.copy(centroids) #将当前中心点赋值到旧中心点中 iterations += 1 #迭代次数加1 #依照中心点为每个实例归类 updateLabels(dataSet,centroids) #根据归类后数据集和k值,计算新的中心点 centroids = getCentroids(dataSet,k) return dataSet#迭代停止函数def shouldStop(oldCentroids,centroids,iterations,maxIt): if iterations > maxIt: return True #迭代次数比最大迭代次数大,则停止迭代 return np.array_equal(oldCentroids,centroids) #比较新旧中心点的值是否相等,相等返回True,迭代终止#依照中心点为每个实例归类def updateLabels(dataSet,centroids): numPoints, numDim = dataSet.shape #获取当前数据集的行列数 for i in range(0,numPoints): #当前行实例与中心点的距离最近的标记作为该实例的标记 dataSet[i,-1] = getLabelFromClosesCentroid(dataSet[i,:-1],centroids)def getLabelFromClosesCentroid(dataSetRow,centroids): label = centroids[0,-1] #初始化当前标记赋值为第一个中心点的标记(第一行最后一列) minDist = np.linalg.norm(dataSetRow - centroids[0,:-1]) #初始化计算当前行实例与第一个中心点实例的欧氏距离 for i in range(1,centroids.shape[0]): #遍历第二个到最后一个中心点 dist = np.linalg.norm(dataSetRow - centroids[i,:-1]) #计算当前行实例与每一个中心点实例的欧氏距离 if dist < minDist: minDist = dist label = centroids[i,-1] #若当前的欧氏距离比初始化的小,则取当前中心点的标记作为该实例标记 print("minDist:",minDist) return label##根据归类后数据集和k值,计算新的中心点def getCentroids(dataSet,k): #最后返回的新的中心点的值有k行,列数与dataSet相同 result = np.zeros((k,dataSet.shape[1])) for i in range(1,k+1): #将所有标记是当前同一类的实例的数据组成一个类 oneCluster = dataSet[dataSet[:,-1] == i,:-1] result[i-1,:-1] = np.mean(oneCluster,axis = 0) #对同一类的实例求均值找出新的中心点 result[i-1,-1] = i return resultx1 = np.array([1,1])x2 = np.array([2,1])x3 = np.array([4,3])x4 = np.array([5,4])testX = np.vstack((x1,x2,x3,x4)) #垂直方向合并numpy数组result = kmeans(testX,2,10)print("final result:",result)运行结果:
iterations: 0dataSet: [[ 1. 1. 1.] [ 2. 1. 2.] [ 4. 3. 0.] [ 5. 4. 0.]]centroids: [[ 1. 1. 1.] [ 2. 1. 2.]]minDist: 0.0minDist: 0.0minDist: 2.82842712475minDist: 4.24264068712iterations: 1dataSet: [[ 1. 1. 1.] [ 2. 1. 2.] [ 4. 3. 2.] [ 5. 4. 2.]]centroids: [[ 1. 1. 1. ] [ 3.66666667 2.66666667 2. ]]minDist: 0.0minDist: 1.0minDist: 0.471404520791minDist: 1.88561808316iterations: 2dataSet: [[ 1. 1. 1.] [ 2. 1. 1.] [ 4. 3. 2.] [ 5. 4. 2.]]centroids: [[ 1.5 1. 1. ] [ 4.5 3.5 2. ]]minDist: 0.5minDist: 0.5minDist: 0.707106781187minDist: 0.707106781187final result: [[ 1. 1. 1.] [ 2. 1. 1.] [ 4. 3. 2.] [ 5. 4. 2.]]
对比两种情况的聚类,结果一致。
- 机器学习——聚类(clustering):K-means算法(非监督学习)
- 机器学习--K-means算法(聚类,无监督学习)
- 斯坦福大学公开课 :机器学习课程(Andrew Ng)——9、无监督学习:K-means Clustering Algorithm
- 非监督学习之k-means聚类算法——Andrew Ng机器学习笔记(九)
- 机器学习算法---无监督学习,k-means聚类
- [机器学习]k-means算法,非监督机器学习算法
- 机器学习——非监督学习——层次聚类(Hierarchical clustering)
- 机器学习与深度学习(六) 聚类(Clustering)____K-均值聚类算法(K-means Clustering) 层次聚类(Hierarchical Clustering)
- Standford机器学习 聚类算法(clustering)和非监督学习(unsupervised Learning)
- Standford机器学习 聚类算法(clustering)和非监督学习(unsupervised Learning)
- 机器学习算法 - k-means Clustering K均值聚类
- 机器学习笔记11——无监督学习之k-means聚类算法
- 非监督学习算法K均值(K-Means)探讨
- K-means聚类算法(无监督学习算法)
- 【机器学习】聚类分析(一)——k-means算法
- 机器学习(一)——K-Means算法分析
- 机器学习笔记:K-Means无监督聚类算法
- 机器学习算法(2)-K-means
- coci2014 contest#1 T3-PIRAMIDA—— 数学
- Robot Framework自动化测试基础实战课程 4
- Python3操作MySQL数据库
- Android图表库MPAndroidChart(二)双轴图
- Mac-硬件内存爆满囧么办,来这里看看~
- 机器学习——聚类(clustering):K-means算法(非监督学习)
- Android 性能优化
- SOQLでのリレーションの辿り方
- 初窥nodejs(七) ——cookie$session
- #CCF准备一年日常刷题#201312-3 最大的矩形
- 有关gis一些在线资源
- [bigdata-116] tomcat官网文档-翻译-不完整
- Angularjs增删改查,路由
- linux服务器搭建两个tomcat实战教程