赞
踩
K-mean聚类算法在机器学习中属于无监督学习。所谓“无监督学习”即是指训练样本的标记信息是未知的,目标是通过对无标记训练样本的学习来揭示数据的内在性质及规律,为进一步的数据分析提供基础。在此类学习任务中研究最多、最广的是“聚类”。
聚类也就是将数据集中的点划分为几个一般情况下不相交的子集、每个子集称为一个“簇”。如下图,在未上色前是一个散点图,通过这些点的位置分布情况,我们可以将他们分为红、绿、蓝三类也就是三个簇。
kmeans算法又名k均值算法,K-means算法中的k表示的是聚类为k个簇,means代表取每一个聚类中数据值的均值作为该簇的中心,或者称为质心,即用每一个类的质心对该簇进行描述,那么也就是会有k个质心。在该算法中k值的选择一般是按照实际需求进行决定,或在实现算法时直接给定 k 值。在k-means算法执行结束后,在划分的k个族中同一聚类中的对象相似度较高;而不同聚类中的对象相似度较低。
优点:速度快,简单
缺点:最终结果跟初始点选择相关,容易陷入局部最优,需直到k值
总的来看K-means算法就是 以空间中k个点为中心进行聚类,对最靠近他们的对象归类。通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。
算法介绍
随机从数据集中取k个点作为中心点也就是聚类质心
计算各个点到所有簇的质心的距离,将每个点划分到距离质心最近的那个簇
对于每个簇,利用均值的方法更新该簇的质心
对于所有的簇的质心,如果利用1.3.2 与1.3.3的迭代法更新后,质心值保持不变,或者变化值小于初始时给定的阈值,则迭代结束,否则继续迭代。
数据集:
x | y |
---|---|
1 | 1 |
2 | 1 |
4 | 3 |
5 | 4 |
**要求:**将以上数据集分为两个簇
初始化(1,1),(2,1)作为簇1,簇2的质心
第0次迭代:
显然根据最短距离划分,我们将A(1,1)划分簇1,将到B(2,1) C(4,3)D(5,4)划分到簇2,然后根据均值计算法得到簇1质心为(1,1),簇2质心为(11/3,8/3)
更新质心后的结果为
第1次迭代:
显然根据最短距离划分,我们将A(1,1) B(2,1) 划分簇1,将到 C(4,3)D(5,4)划分到簇2,然后根据均值计算法得到簇1质心为(3/2,1),簇2质心为(9/2,7/2)
更新质心后的结果为
第2次迭代:
显然根据最短距离划分,我们将A(1,1) B(2,1) 划分簇1,将到 C(4,3)D(5,4)划分到簇2,显然与第1次迭代得到的簇的划分相同,那么质点的更新也与第0此得到的值一样。所以符合1.3.3中的算法停止条件,此时算法停止。
最后我们得到的数据集划分结果为
x | y | 簇号 |
---|---|---|
1 | 1 | 1 |
2 | 1 | 1 |
4 | 3 | 2 |
5 | 4 | 2 |
暂无
下面我们以上面举的例子中的数据来具体看看K-means算法的简单代码实现
import numpy as np def kmeans(X, k, maxIt): ''' :param X:数据集 :param k:分类数 :param maxIt:循环次数 :return: ''' #矩阵X的横向数与纵向数赋值 numPoints, numDim = X.shape #创建一个横向数与X相同,纵向数与numDim+1相同的0矩阵 dataSet = np.zeros((numPoints, numDim + 1)) print('dataSet',dataSet) #把X赋值给dataSet除最后一列的数据 dataSet[:, :-1] = X print(dataSet) # 初始化中心点,随机选取两个点作为中心点 centroids = dataSet[np.random.randint(numPoints, size=k), :] print('centroids',centroids) centroids = dataSet[0:2, :] print(centroids) centroids[:, -1] = range(1, k + 1) print(centroids) iterations = 0 oldCentroids = None while not shouldStop(oldCentroids, centroids, iterations, maxIt): print("iteration: \n", iterations) print("dataSet: \n", dataSet) print("centroids: \n", centroids) oldCentroids = np.copy(centroids) iterations += 1 updateLabels(dataSet, centroids) centroids = getCentroids(dataSet, k) return dataSet def shouldStop(oldCentroids, centroids, iterations, maxIt): if iterations > maxIt: return True return np.array_equal(oldCentroids, centroids) def updateLabels(dataSet, centroids): numPoints, numDim = dataSet.shape for i in range(0, numPoints): dataSet[i, -1] = getLabelFromClosestCentroid(dataSet[i, :-1], centroids) def getLabelFromClosestCentroid(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 def getCentroids(dataSet, k): 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 result x1 = 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)) print("testx",testX) result = kmeans(testX, 2, 10) print("final result:") print(result)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。