python中实现k-means聚类算法

算法优缺点

优点:简单,容易理解与解释,结果相对较好
缺点:1.分类个数k需要事先指定,指定的k值不同,聚类结果相差较大
   2.初始的k个类簇中心对最终结果有影响,选择不同,结果可能不同
   3.只对球状类簇有较好的识别效果
   4.样本多时计算量大
   5.离散数据需要特殊处理

算法实现介绍

根据初始化聚类中心信息,计算每个样本到这些中心的距离,可以判断每个样本均归属于某个类簇,更新聚簇中心信息,重新计算每个样本到新的类簇中心的距离,重复进行,直到满足最终条件。

代码中使用函数

loadDataSet(fileName)

从文件中读取数据集

distEclud(vecA, vecB)

计算两个向量的距离

randCent(dataSet, k)

随机生成初始的质心

# 计算距离方法和初始化质心方法可更换
KMeans(dataSet, k, distMeas=distEclud, createCent=randCent)

K-Means算法,输入数据和k值

show(dataSet, k, centroids, clusterAssment)

展示方法

使用数据

只展示部分数据

-3.415397	3.582124
-1.632707	1.624773
4.391960	1.415999
-3.446516	-2.464088
2.545512	2.212993
3.052709	3.494825
-3.277546	3.415180
-2.246377	1.499515
-1.206281	-3.436237
-2.697535	-3.134228
-2.067644	-0.626221
-3.122394	2.373387
-0.398199	2.010003
2.659758	-1.125584
-2.244237	0.277479
1.402242	-0.888432
0.478610	3.298247
-2.542210	3.787628
0.915269	3.205037
3.766489	-0.617184

代码

import numpy as np


def loadDataSet(fileName):
    dataMat = []
    fr = open(fileName)
    for line in fr.readlines():
        curLine = line.strip().split('\t')
        fltLine = map(float, curLine)
        dataMat.append(list(fltLine))
    return dataMat


# 计算两个向量的距离,用的是欧几里得距离
def distEclud(vecA, vecB):
    return np.sqrt(np.sum(np.power(vecA - vecB, 2)))


# 随机生成初始的质心(ng的课说的初始方式是随机选K个点)
def randCent(dataSet, k):
    n = np.shape(dataSet)[1]
    centroids = np.mat(np.zeros((k, n)))
    for j in range(n):
        minJ = min(dataSet[:, j])
        rangeJ = float(max(np.array(dataSet)[:, j]) - minJ)
        centroids[:, j] = minJ + rangeJ * np.random.rand(k, 1)
    return centroids


def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
    m = np.shape(dataSet)[0]
    clusterAssment = np.mat(np.zeros((m, 2)))  # create mat to assign data points
    # to a centroid, also holds SE of each point
    centroids = createCent(dataSet, k)
    clusterChanged = True
    while clusterChanged:
        clusterChanged = False
        for i in range(m):  # for each data point assign it to the closest centroid
            minDist = np.inf
            minIndex = -1
            for j in range(k):
                distJI = distMeas(centroids[j, :], dataSet[i, :])
                if distJI < minDist:
                    minDist = distJI;
                    minIndex = j
            if clusterAssment[i, 0] != minIndex:
                clusterChanged = True
                clusterAssment[i, :] = minIndex, minDist ** 2
        print(centroids)
        for cent in range(k):  # recalculate centroids
            ptsInClust = dataSet[np.nonzero(clusterAssment[:, 0].A == cent)[0]]  # get all the point in this cluster
            centroids[cent, :] = np.mean(ptsInClust, axis=0)  # assign centroid to mean
    return centroids, clusterAssment


def show(dataSet, k, centroids, clusterAssment):
    from matplotlib import pyplot as plt
    numSamples, dim = dataSet.shape
    mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']
    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']
        for i in range(k):
            plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize=12)
    plt.show()


def main():
    dataMat = np.mat(loadDataSet('testSet.txt'))
    myCentroids, clustAssing = kMeans(dataMat, 4)
    print(myCentroids)
    show(dataMat, 4, myCentroids, clustAssing)


if __name__ == '__main__':
    main()

效果图

设置聚簇点为4个时
在这里插入图片描述
在这里插入图片描述
设置聚簇点为10个时
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

选择不同数量的类簇中心时聚簇效果会不一样,且在多次运行后展示结果也不一致,不过大体聚簇效果还算不错。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: K-means聚类算法是一种常见的无监督学习算法,用于将数据集分成k个不同的簇。Python可以使用scikit-learn库的KMeans类来实现K-means聚类算法。具体步骤如下: 1. 导入KMeans类和数据集 ```python from sklearn.cluster import KMeans from sklearn.datasets import make_blobs ``` 2. 生成数据集 ```python X, y = make_blobs(n_samples=100, centers=3, random_state=42) ``` 3. 创建KMeans对象并进行拟合 ```python kmeans = KMeans(n_clusters=3, random_state=42) kmeans.fit(X) ``` 4. 获取聚类结果 ```python labels = kmeans.labels_ ``` 5. 可视化聚类结果 ```python import matplotlib.pyplot as plt plt.scatter(X[:, ], X[:, 1], c=labels) plt.show() ``` 以上就是Python实现K-means聚类算法的基本步骤。 ### 回答2: K-means聚类算法是一种常见的无监督学习算法,它将n个样本分成k个簇,每个簇对应着一些数据点,使得同一簇内的数据点之间的相似度尽可能高,而不同簇的数据点之间的相似度尽可能低。Python是一种广泛使用的编程语言,也是进行K-means聚类的好选择。 以下是Python实现K-means聚类算法的步骤: 1. 导入数据集:将要聚类的数据集导入,可以是csv文件或者Excel文件,也可以是Python自带的sklearn.datasets等数据集模块的数据集。 2. 选择K值:决定将数据分成几个簇。可以通过手肘法或者轮廓系数法找到最优的K值,手肘法就是将数据集按照K值分割成K个簇并计算每个簇的误差平方和,一般来说误差平方和随簇数量的增加而减小,随着簇数量增加,在某个点后,曲线的下降趋势会减缓。轮廓系数法可以直观地描述每个数据点与其所处簇的相似程度和不同簇的相似程度,即同一簇内的相似度高,与其他簇的相似度低。 3. 初始化聚类心:从数据集随机选择K个点作为聚类心。 4. 簇分配:对于每个数据点,计算其与每个聚类心的距离,将其分配到距离最近的簇。 5. 聚类心更新:重新计算每个簇的聚类心,即将簇内所有数据点的坐标进行平均,得到新的聚类心。 6. 重复步骤4-5,直到聚类心不再改变或达到最大迭代次数。 7. 输出簇:输出每个簇包含的数据点。 Python实现K-means聚类算法的示例代码: ```python from sklearn.cluster import KMeans from sklearn.datasets import make_blobs # 生成数据集 X, y = make_blobs(n_samples=500, centers=3, random_state=42) # 初始化KMeans聚类模型 model = KMeans(n_clusters=3, random_state=42) # 训练模型 model.fit(X) # 输出每个簇的聚类心坐标 print("Cluster centers:", model.cluster_centers_) # 输出每个数据点所属的簇 print("Cluster labels:", model.labels_) ``` 以上就是Python实现K-means聚类算法的基本步骤和示例代码。在实际应用,我们可以根据数据集的特点和需求对算法进行改进和优化,使得聚类效果更加准确和高效。 ### 回答3: K-means聚类算法是机器学习常用的无监督学习方法之一,可以将一组数据集划分为K个簇(cluster),簇与簇之间的差异最小。Python提供了很多库,如sklearn、scipy.cluster.vq、numpy等可以实现K-means聚类算法,这里以sklearn库为例进行讲解。 首先,需要导入sklearn库的KMeans模块,代码如下: ``` from sklearn.cluster import KMeans ``` 接着,需要确定K值,即簇的数量。可以通过手肘法(Elbow Method)来选择最优K值。手肘法是通过绘制不同K值对应的聚类误差值(即SSE,Sum of Squared Errors)与K值的折线图,确定最优的K值。代码如下: ``` import matplotlib.pyplot as plt from scipy.spatial.distance import cdist import numpy as np # 生成数据集 X = np.random.uniform(low=-10, high=10, size=(100, 2)) # 计算不同K值对应的SSE K_range = range(1, 10) sse = [] for k in K_range: kmeans = KMeans(n_clusters=k, random_state=0).fit(X) sse.append(sum(np.min(cdist(X, kmeans.cluster_centers_, 'euclidean'), axis=1)) / X.shape[0]) # 绘制折线图 plt.plot(K_range, sse, 'bx-') plt.xlabel('Number of clusters') plt.ylabel('SSE') plt.title('Elbow Method For Optimal k') plt.show() ``` 在绘制的折线图,选择拐点处的K值作为最优的簇数。 选择完簇数后,就可以利用KMeans模块进行聚类了。代码如下: ``` # 将数据集聚类为3个簇 kmeans = KMeans(n_clusters=3, random_state=0).fit(X) # 绘制聚类结果图 plt.scatter(X[:, 0], X[:, 1], c=kmeans.labels_) plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], marker='x', color='black', s=100, linewidths=3) plt.title('K-means Clustering') plt.show() ``` 其,kmeans.labels_为数据点所被聚到的簇的标号,kmeans.cluster_centers_为聚类心。 以上就是利用Python实现K-means聚类算法的基本步骤,通过手肘法选择最优簇数,然后利用KMeans模块进行聚类,最后绘制聚类结果图。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值