MacQueen’s Algorithmus

110 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

借助于K-means算法概念,MacQueen引入了一个不同的算法。

  1. 选择前k个元素作为聚类中心。

  2. 将每个新元素添加到方差增加最小的簇,并更新簇中心。

尽管此算法原始、不确定并且不可预料,但也可以迭代此算法以获得较好的结果。

 

其它算法:

K-Median

在k中值算法中,曼哈顿距离用于分类步骤而不是欧几里德距离。 在更新步骤中,使用中值(中位数)而不是平均值。

该算法本质与Python实现过程与K-Means没有本质区别。这里不再做具体介绍,然而关于曼哈顿距离我们似乎从未介绍过,实际上并非如此,曼哈顿距离和我们前面所说的矢量的范数一有着紧密的关联。曼

假设点a坐标为:(0,0),b的坐标为(6,6),则这两个点的曼哈顿距离为12,那么两点间可能的轨迹如下图所示:、

图片.png

其中,红线,蓝线和黄线是曼哈顿轨迹,绿线为欧式轨迹。

 

K-Means++

k-Means ++算法不会随机选择簇中心点,而是根据以下规则:

  1. 随机选择一个数据作为第一个簇中心点。

  2. 计算每个数据到最近的簇中心点的距离D(x)。

  3. 随机选择一个对象作为最近的簇中心。

  4. 重复步骤2和3,直到确定k个簇中心点。

  5. 现在执行通常的k-means算法

K-Means++算法的Python实现:

import numpy as np

import pandas as pd

def lunpan_select(fr12,t):

    for k in range(fr12.shape[1]):

        if t<fr12.loc[1,0] and t>=0:

            return np.array(fr12.loc[0,0])

        elif t<fr12.loc[1,k+1] and t>=fr12.loc[1,k]:

            return np.array(fr12.loc[0,k+1])

 

def K_center_selection(k,data):

    cluster_centerp=[]

    pro_collect=[]

    dist_collection=[]

    index=np.random.randint(data.shape[0])

    cluster_centerp.append(data[index])

    for j in range(1,k):

        for point in data:

            dist_list=[np.dot(point-center,point-center)for center in cluster_centerp]

            dist_collection.append((min(dist_list),point))

        #print(dist_collection)

        for d_x in dist_collection:

             pro_collect.append((d_x[0]/sum([dist[0] for dist in dist_collection]),d_x[1]))

        new_pro_collect=pd.DataFrame([[dp[1] for dp in pro_collect],np.cumsum([wt[0] for wt in pro_collect]).tolist()]) \

        .sort_values(by=1,axis=1)

        randomnr=np.random.rand()

        cluster_centerp.append(lunpan_select(new_pro_collect,randomnr))

return np.array(cluster_centerp)

 

from scipy import linalg

import numpy as np

from sklearn.datasets import make_blobs

def K_meanspp(X,k):#X必须是浮点矩阵

    var_generator=locals()

    X=X.astype(np.float64)

    #sample_selection=np.random.randint(0,X.shape[0],k)

    #center_point=X[sample_selection.tolist()]

    center_point= K_center_selection(k,X)

    #print(center_point)

    center_point_temp=np.zeros_like(center_point).astype(np.float64)

    while ~((center_point_temp==center_point).all()):#设置外层循环终止条件

        for i in range(k):

            var_generator['c'+str(i)]=[]#创建动态变量并赋值[]

        for sample_point in X:#对所有点进行分类

            distance_vector=linalg.norm(center_point-sample_point,axis=1)

            min_distance=min(distance_vector)

            cluster_marker=np.where(distance_vector==min_distance)[0][0]

            var_generator['c'+str(cluster_marker)].append(sample_point)

        center_point_temp=center_point.copy()

        #print(center_point_temp)

        for cluster_nr in range(k):#分类完毕后,求各分类的中心点

            if len(var_generator['c'+str(cluster_nr)])!=0:

                center_point[cluster_nr]=(sum(var_generator['c'+str(cluster_nr)])

                /len(var_generator['c'+str(cluster_nr)]))

            else:

                continue

        #print(center_point)

    classification_data={m:var_generator['c'+str(m)] for m in range(k)}

return center_point,classification_data  

    

ar1=np.array([[3,4,3,4,0,1,0,1],[4,4,3,3,2,2,1,1]])

K_center_selection(2,ar1.T)

array([[3, 3],

       [4, 4]])

data_3=K_means(ar1.T,2)

import matplotlib.pyplot as plt

pic,axes_1=plt.subplots(1,1,figsize=(8,6),dpi=140)

data_class0=np.array(data_3[1][0])

data_class1=np.array(data_3[1][1])

axes_1.scatter(data_class0[:,0],data_class0[:,1],color='r',marker='.')

axes_1.scatter(data_class1[:,0],data_class1[:,1],color='b',marker='*')

axes_1.scatter(data_3[0][0,0],data_3[0][0,1],color='r',marker='D')

axes_1.scatter(data_3[0][1,0],data_3[0][1,1],color='b',marker='3')

plt.show()