当前位置:   article > 正文

机器学习实验——K-Means聚类_人工智能kmeans聚类的实验

人工智能kmeans聚类的实验

K-Means聚类

源码与数据:github

一、 实验要求

1、编程实现K-means,对所提供数据(data.txt)进行聚类,cluster数量为3
2、数据形式为[x1, x2],其中x1,x2为样本属性

二、 实验原理:

2.1 K-means原理

K-means是一种基于距离的聚类算法,主要用于将数据点分成k个不同的簇,使得每个簇内的数据点相似度较高,不同簇之间的相似度较低。K-means是一种迭代算法,需要不断地迭代调整簇的中心点,直至满足停止迭代的条件。

2.2 K-means简要算法流程如下:

① 从数据集中随机选择k个数据点作为初始中心点(centroid)。
② 针对每个数据点,计算它与k个中心点的距离,并将它分配到距离最近的中心点所代表的簇中。
③ 针对每个簇,重新计算它的中心点,即将它的所有数据点的平均值作为新的中心点。
④ 重复步骤2和步骤3,直到簇的分配不再发生变化,或者达到预先设定的迭代次数。
⑤ 算法结束,输出最终的簇分配结果和中心点坐标。

2.3 k值

在实际应用中,簇的数量k可以根据领域知识、经验或试错法来确定。

2.4 K-means优缺点

1、优点:
① 算法简单易实现。
② 对于大规模数据集,K-means算法可以通过并行化技术加速计算。
③ 聚类效果较好,且能够适用于各种不同类型的数据。
2、缺点:
① 需要手动设定簇的数量k,这可能需要领域知识或试错法来确定。
② 对于不同的随机初始中心点,可能会得到不同的聚类结果,这会导致算法的不稳定性。
③ 算法可能会收敛到一个局部最优解,而不是全局最优解。

三、 实验过程:

3.1 读取数据

数据保存在“data.txt”中,保存格式如图:

在这里插入图片描述

根据数据的保存格式读取数据。

data_list = []  
with open(path,"r") as f:  
    lines = f.readlines()  
    for line in lines:  
        line = line.strip()  
        tmp = line.strip('[]').split()  
        data_list.append([float(num) for num in tmp])  
data = np.array(data_list)  
print(data.shape)  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

“data_list”保存处理后的每行数据,读取完数据后,将其转化为“ndarray”并打印数据的形状。
利用“strip”函数去掉空格和中括号,通过列表生成式生成每行数据,并用“float”进行数字类型转换。
如图所示,数据集形状为90*2,即有90个样本,每个样本有两个属性。

在这里插入图片描述

3.2 分析k值

以散点图形式打印数据集,观察数据集的分布。
在这里插入图片描述

如图所示,数据集大致由两簇组成,因此暂时确定k值为2。

3.3 K-means算法辅助函数

1、计算欧氏距离
通过欧氏距离评估样本和中心点的距离

#计算欧氏距离  
def getDistance(x,y):  
    return np.sqrt(np.sum((x-y)**2))  

  • 1
  • 2
  • 3
  • 4

2、随机中心点
刚开始聚类时,需要根据k值确定随机中心点以展开聚类。随机中心点的优劣对聚类结果具有重要影响。

#初始化中心点  
def getCenter(dataset,k):  
    m,n = dataset.shape  
    centerDots = np.zeros((k,n))  
    for i in range(k):  
        row = np.random.randint(m)  
        centerDots[i,:] = dataset[row,:]  
    return centerDots  

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3.4 K-means算法实现

说明见2.2。
本实验中判断聚类结束的条件为:当前轮次没有点更换过簇。反之,若某个点的簇发生了变化,则继续聚类。
每轮聚类结束后,需要更新各个簇的中心点。本实验中取各类样本的均值作为各类的中心点。
聚类结束后,返回聚类中心和各个样本的类别。

#Kmeans算法
def Kmeans(dataset,k):
    m,n = dataset.shape
    clusters = np.mat(np.zeros((m,2)))#构造m*2存储分类属性
    centerDots = getCenter(dataset, k)#获取随机中心
    
    Continuing = True
    while(Continuing):
        Continuing = False
        for i in range(m):
            minDistance = 1e5
            minindex = -1
            
            for j in range(k):
                #计算当前记录离那个中心更近
                distance = getDistance(centerDots[j,:], dataset[i,:])
                if distance < minDistance:
                    minDistance = distance
                    minindex = j
            #更新i记录类别
            if clusters[i,0] != minindex:
                Continuing = True
                clusters[i,:] = minindex,minDistance
        #更新中心点
        for j in range(k):
            cur_cluster = dataset[np.nonzero(clusters[:,0].A == j)[0]]
            centerDots[j] = np.mean(cur_cluster,axis=0)
    
    print("聚类完成")
    return centerDots,clusters[:,0].ravel().tolist()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

3.5 K-means聚类结果评估

使用两种方式进行评估:
① 聚类结果可视化
② 对比分析:使用sklearn库的Kmeans算法对统一数据集进行聚类并可视化

#设置k值
k = 2
plt.figure(dpi=100)
#上述Kmeans实现聚类并可视化
plt.subplot(121)
centroids,labels = Kmeans(data,k)
plt.scatter(data[:,0], data[:,1], c=labels)
plt.title("Kmeans from self")
#绘制中心点
centerDots = centroids
for i in range(len(centerDots)):
    plt.annotate("center", xy=(centerDots[i,0],centerDots[i,1]),arrowprops=dict(facecolor="yellow"))
#使用sklearn库的Kmeans算法进行聚类并可视化
plt.subplot(122)
estimator = KMeans(n_clusters=k).fit(data)
plt.scatter(data[:,0], data[:,1], c=estimator.labels_)
centerDots = estimator.cluster_centers_
for i in range(len(estimator.cluster_centers_)):
    plt.annotate("center", xy=(centerDots[i,0],centerDots[i,1]),arrowprops=dict(facecolor="yellow"))
plt.title("Kmeans from sklearn")
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

2、结果
① 结果1
在这里插入图片描述
3、分析
对比结果1中展示的两个聚类结果,可以发现,上述代码实现的K-means算法聚类效果与sklearn库中的K-means算法效果基本一致,且二者的聚类结果都比较符合数据集实际分布情况。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/72903
推荐阅读
相关标签
  

闽ICP备14008679号