数据挖掘实验:k_means、k_medoids聚类算法的实现(Python)

目录

前言

一、k-means算法

二、k-medoids算法

三、实验结果展示

总结


前言

本文是基于划分的聚类算法研究与实现,实现了k均值及k中心点聚类算法,并在数据集上完成测试。用户输入k的值,可对数据集中的数据进行聚类。

一、k-means算法

k-means算法使用簇的均值点作为簇的形心。

首先在数据集中随机选择k个点作为k个簇的初始均值,对于数据集中的每个点,根据欧式距离将其分配至距离最近的簇。然后k均值算法开始迭代,对于每个簇,使用该簇内的点计算均值作为新的簇中心,再重新分配所有的点。迭代继续,直到分配稳定,所有的簇中心不在发生变化。

具体实现代码如下:

import random
import math
import numpy

def dataSet():#处理数据集
    dataset=[]
    fr=open("聚类实验数据/data.txt")
    for line in fr.readlines():
        currLineListFloat = []
        line = line.split(" ")
        line=line[0:-1]
        for i in line:  # 逐行将字符串数据转化为浮点数
            currLineListFloat.append(float(i))
        dataset.append(currLineListFloat)#数组矩阵
    return dataset

def distance(x,y):#计算距离
    error=[]
    a=0
    for i in range(0,len(x)):
        error.append(abs(x[i]-y[i]))
    for i in range(0,len(error)):
        a=a+math.pow(error[i],2)
    return math.sqrt(a)
        
    
data=dataSet()#320*690
k=int(input("please enter k:"))
k_spot=[]

for i in range(0,k):
    j=random.randint(0,320)
    k_spot.append(data[j])#k个随机点
time=0
while True:
    time=time+1
    new_k_spot=[]
    kk=[]#存放数据属于哪一簇
    for i in range(0,320):#分类
        dist=[]
        for j in range(0,k):
            dist.append(distance(data[i],k_spot[j]))
        kk.append(dist.index(min(dist)))
    #print(kk)
    print("第",time,"次迭代循环:")
    for i in range(0,k):
        print(kk.count(i),end='  ')
    print("")
    for i in range(0,k):#对k个簇分别求均值点
        newspot=[]#存放第i簇分类后所有的点坐标
        a=[]#存放新的均值点
        for j in range(0,320):
            if kk[j]==i:
                newspot.append(data[j])#第i簇所有点的坐标
        #print(len(newspot))
        for t in range(0,690):
            b=0
            for m in range(0,len(newspot)):
                b=b+newspot[m][t]
            c=format(b/len(newspot), '.4f')#在t维度上的均值
            a.append(float(c))
                
        new_k_spot.append(a)
    #print(new_k_spot)

    if k_spot==new_k_spot:
        break
    else:
        k_spot=new_k_spot[:]
                   

二、k-medoids算法

k-medoids算法围绕中心点划分,使用簇的中心点作为簇的形心。

大致过程与k-means相同,就是在计算新的簇的形心时将均值方法改变为计算中心点方法。计算中心点使用该点到簇内其他所有点的距离之和作为根据,选择距离之和最小的点作为新的中心点(形心)。

具体实现代码如下:

import random
import math
import numpy

def dataSet():#处理数据集
    dataset=[]
    fr=open("聚类实验数据/data.txt")
    for line in fr.readlines():
        currLineListFloat = []
        line = line.split(" ")
        line=line[0:-1]
        for i in line:  # 逐行将字符串数据转化为浮点数
            currLineListFloat.append(float(i))
        dataset.append(currLineListFloat)#数组矩阵
    return dataset

def distance(x,y):#计算距离
    error=[]
    a=0
    for i in range(0,len(x)):
        error.append(abs(x[i]-y[i]))
    for i in range(0,len(error)):
        a=a+math.pow(error[i],2)
    return math.sqrt(a)
    
        
    
data=dataSet()#320*690
k=int(input("please enter k:"))
k_spot=[]

for i in range(0,k):
    j=random.randint(0,320)
    k_spot.append(data[j])#k个随机点
time=0
while True:
    time=time+1
    new_k_spot=[]
    kk=[]#存放数据属于哪一簇
    for i in range(0,320):#分类
        dist=[]
        for j in range(0,k):
            dist.append(distance(data[i],k_spot[j]))
        kk.append(dist.index(min(dist)))
    #print(kk)
    print("第",time,"次迭代循环:")
    for i in range(0,k):
        print(kk.count(i),end='  ')
    print("")
    for i in range(0,k):
        #找出中心点
        newspot=[]
        for j in range(0,320):
            if kk[j]==i:
                newspot.append(data[j])#第i簇所有点的坐标
        #print(len(newspot))
        dist=[]
        for t in newspot:
            a=0
            for m in newspot:
                a=a+(distance(t,m))
            dist.append(a)#a是t到其他所有点的距离
        new_k_spot.append(newspot[dist.index(min(dist))])
      

    if k_spot==new_k_spot:
        break
    else:
        k_spot=new_k_spot[:]
      

三、实验结果展示

如图,上面的是k-means算法的结果,下面的是k-medoids算法的结果。算法的输出是每次迭代的结果,即每个簇中的点个数。

两种算法在k都等于10的情况下,迭代次数差异很大,运行时时间差异也较大。


总结

K-means算法的优势是算法复杂度小,对凸状的簇分类效果较好,对于大数据集有较好的伸缩性,但是对噪声(极值点)敏感,而且因其求均值的特点,对数据集的要求很高,要求所有的点处于一个欧式空间里,有很多噪声就会造成极大的误差;k-medoids的中心点取值只能是数据空间里的点,所以对数据集要求较小,受极值点影响也较小,削弱了异常值对结果的影响,但只能适用于小数据集,运行速度较慢。

  • 5
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值