zoukankan      html  css  js  c++  java
  • K-means聚类算法

       K-means聚类算法

    1、算法思想

    首先,我们可以随机选取K个对象作为初始的聚类中心,然后计算每个对象与每一个种子聚类中心的距离,然后分别把这些对象分配给距离对象最近的一个聚类中心,只要对象被分配以后,被分配的对象就和聚类中心组成一个新的聚类,分配后就不能改变了,然后在根据每个聚类的聚类中心和对象的距离进行重新计算,并且一直重复这样的计算,直到没有对象可以被重新分配给不同的聚类或聚类中心不再发生变化或误差平方和局部已经最小,这样循环计算就会停止。

    2、优缺点

    优点:a.算法容易实现

               b.当聚类个数小于真实值时,误差平方和会下降的很快;

    缺点:a.当聚类个数超过真实值时,误差平方和虽然会继续下降,但是下降的速度会缓减,而这个转折点就是最佳的聚类个数了。

               b.非均质的数据、不同类别内部方差不相同 

    3、伪代码

    输入:类簇的个数K,迭代终止值Z。

    输出:聚类结果

    For(t=1;t<K;t++){

         给出数据对象Xi;

         计算聚类中心和对象的距离dist(Xi,Centerk);

         将Xi划到距离Xi最近的类簇中心所在的类簇中

    For(直到Xi不能在分配){

    将所有的类簇中心更新

    }

    输出聚类结果;

    }

    4.代码实现

     

    import numpy as np

     

    import pandas as pd

     

    import random

     

    import sys

     

    import time

     

    class KMeansClusterer:

     

        def __init__(self,ndarray,cluster_num):

     

            self.ndarray = ndarray

     

            self.cluster_num = cluster_num

     

            self.points=self.__pick_start_point(ndarray,cluster_num)

     

             

     

        def cluster(self):

     

            result = []

     

            for i in range(self.cluster_num):

     

                result.append([])

     

            for item in self.ndarray:

     

                distance_min = sys.maxsize

     

                index=-1

     

                for i in range(len(self.points)):                

     

                    distance = self.__distance(item,self.points[i])

     

                    if distance < distance_min:

     

                        distance_min = distance

     

                        index = i

     

                result[index] = result[index] + [item.tolist()]

     

            new_center=[]

     

            for item in result:

     

                new_center.append(self.__center(item).tolist())

     

            # 中心点未改变,说明达到稳态,结束递归

     

            if (self.points==new_center).all():

     

                return result

     

             

     

            self.points=np.array(new_center)

     

            return self.cluster()

     

                 

     

        def __center(self,list):

     

            '''计算一组坐标的中心点

     

            '''

     

            # 计算每一列的平均值

     

            return np.array(list).mean(axis=0)

     

        def __distance(self,p1,p2):

     

            '''计算两点间距

     

            '''

     

            tmp=0

     

            for i in range(len(p1)):

     

                tmp += pow(p1[i]-p2[i],2)

     

            return pow(tmp,0.5)

     

        def __pick_start_point(self,ndarray,cluster_num):

     

            

     

            if cluster_num <0 or cluster_num > ndarray.shape[0]:

     

                raise Exception("簇数设置有误")

     

          

     

            # 随机点的下标

     

            indexes=random.sample(np.arange(0,ndarray.shape[0],step=1).tolist(),cluster_num)

     

            points=[]

     

            for index in indexes:

     

                points.append(ndarray[index].tolist())

     

            return np.array(points)

     

    代码参考资料cf44fxnaALrxBy0alj1s9pDTHymWapRwW4pnYyFhdnzSIAK-aAFBsCADRaJbBaRXne6CwU5lM4ucx-Y2YTUKejAT7qcyU_OsvFfLJldKJPmfADilL3a6K3QzB3u--M2y.htm

     

  • 相关阅读:
    二、跳转指定页面的JS代码
    一、常规的JS页面跳转代码
    您在前一家公司的离职原因是什么?
    如果你在这次面试中没有被录用,你怎么打算?
    如果你在这次面试中没有被录用,你怎么打算?
    针对你们单位业务工作中出现的问题,你提出了一些很好的建议,得到了同事们的赞同,但你的领导并不满意。在这种情况下,你怎么办?
    进程与线程的区别
    work13
    work12
    day09
  • 原文地址:https://www.cnblogs.com/wyf-1999-1--6/p/11602519.html
Copyright © 2011-2022 走看看