Python k-均值聚类算法一维实例

大家好,一直以来在CSDN上学了很多编程方面的知识,很感谢这个平台,感谢大家的无私分享,早就想为中文IT社区贡献一点自己的力量,正巧昨天看了一篇二维聚类的博客,关键算法的地方使用了一个函数,但是后面没有见到这个函数,琢磨了一下,一步步自己写吧,先写个一维的,没什么技术难度,就是一点点技巧。
k-均值聚类,是根据均值间的距离来进行聚类的,在算法实现时,
1、需要首先确定需要分几类,
2、然后给定各类别的均值,
3、再计算两个均值间的平均值,
4、根据该值进行聚类划分。
下面的代码是划分一维数组的聚类算法,因为使用的是随机数,效果不是特别理想,不过各类间的距离放开到30以上就比较理想了。当然,找规律是在有规律的情况下找,如果都是随机数,肯定没什么明显的规律。
Python 3.6.2

import time
import numpy as np
import random

def func00():    #生成随机数列表

    #random.seed(1)
    kjz1=[random.randint(1,50) for j in range(0,7000)]
    kjz1.extend([random.randint(80,150) for j in range(0,8000)])
    kjz1.extend([random.randint(200,300) for j in range(0,5000)])
    kjz1.extend([random.randint(400,500) for j in range(0,8000)])
    return kjz1

def func01(kjz1):    #2分类

    bj=1;kjz1=np.sort(kjz1)
    while(True):
        if bj==1:
            kj=np.mean([kjz1[0],kjz1[len(kjz1)-1]]) #初始分组均值使用最小值和最大值的平均值
        else:
            k1=s1;k2=s2;
            kj=np.mean([k1,k2]);
        kjz2=[[],[]];
        for j in kjz1:
            if j<=kj:
                kjz2[0].append(j)
            else:
                kjz2[1].append(j)
        s1=np.mean(kjz2[0]);
        s2=np.mean(kjz2[1]);
        if bj==2:
            if s1==k1 and s2==k2:
                break
        bj=2;
    return kjz2

def func02(kjz1,k):    #k个均值分k份

    kjz1=np.sort(kjz1);#正序
    wb2=kjz1.copy();
    #初始均匀分组wb1
    xlb=[];a=round(len(wb2)/(k));b=len(wb2)%(k);
    for j in range(1,k+1):
        xlb.append(j*a)
        if j==k:
            xlb[j-1]=xlb[j-1]+b;
    j=0;wb1=[];
    for j in range(0,k):
        wb1.append([])
    i=0;j=0;
    while(i<=len(wb2)-1):
        wb1[j].append(wb2[i]);
        if i>=xlb[j]-1:
            j=j+1;
        i=i+1;
    kj1=means(wb1);#初始分组均值

    bj=1;
    while(True):
        wb2=kjz1.copy().tolist();
        if bj!=1:
            kj1=kj2.copy();

        wb3=[];
        for j in range(0,k-1):
            wb3.append([])
        for j in range(0,k-1):
            i=-1;
            while(True):
                if wb2[i]<=kj1[j]:
                    wb3[j].append(wb2.pop(i));
                else:
                    i=i+1;
                if i>=len(wb2):
                    break
        wb3.append(wb2)

        kj2=means(wb3);#过程均值
        if bj==2:
            if kj1==kj2:
                break
        bj=2;
    return wb3

def means(lb1):    #计算均值

    mean1=[];mean2=[];std1=[];
    for j in lb1:
        mean1.append(np.mean(j).tolist())
    for j in range(1,len(mean1)):
        mean2.append(np.mean([mean1[j-1],mean1[j]])) #分组均值使用各组的均值
    print(mean2)
    return mean2

if __name__=='__main__':

    start=time.time();

    kjz1=func00()    #生成随机数列表

    kjz2=func01(kjz1)    #2分类
    for j in kjz2:
        print(len(j))

    k=4;
    kjz3=func02(kjz1,k)    #k个均值分k份
    for j in kjz3:
        print(len(j))

    print('Time used:',int((time.time()-start)/60*10)/10,'分钟')
    原文作者:聚类算法
    原文地址: https://blog.csdn.net/qq_24311495/article/details/79302472
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞