一些典型聚类的方法

142 阅读3分钟

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

如上所述,聚类算法可以根据其聚类模型进行分类。因为可能有超过100种已发布的聚类算法,所以这里我们只介绍几种表现最为突出的算法。

没有客观“正确”的聚类算法。对于一个特定的问题,最合适的聚类算法通常需要通过实验来选择,除非有数学上的理由支持选择一个聚类模型而不是另一个。

应该注意的是,针对一种模型设计的算法通常会在包含完全不同类型的模型的数据集上失败。 例如,k-means找不到非凸簇。

已经在各种各样的应用中开发了各种聚类方法。 人们可以把它们区分为以下方法类型:

(基于中心的)分区方法,

分层方法, (若有时间,会后续编写)

基于密度的方法和(若有时间,会后续编写)

合并方法。(若有时间,会后续编写)

前两种方法是经典的聚类方法,而其他方法是最近的方法。

分区方法:

分区方法的共同特征是必须首先确定簇k的数量(数量的确定完全依赖经验,所以这是这类方法的一个缺点)。 然后确定k个聚类中心并一直迭代移动它们,直到对k个聚类中心的观测值的分配不再改变,从而最小化给定的误差函数。一个优点是在簇中心移动期间对象(数据点)可以更改其簇成员资格(更改所属簇)。

1. K-Means-Algorithmus

k-Means的目的是将数据集划分为k个分区(簇),以致使数据与簇中心的偏差平方之和最小。也即最小化了数据点(对象)与其最近聚类中心的欧几里德距离平方之和。 簇中心的更新是通过平均簇中的所有数据点来完成的

由于难以确定最优解,因此通常使用像Lloyd或MacQueen这样的近似算法。由于问题解决取决于k,因此必须由用户设置此参数。

Lloyd-Algorithmus:

最常用的k-means算法是Lloyd算法,通常被称为“k-means算法”,尽管Lloyd本人没有使用该名称。 劳埃德的算法包括三个步骤:

算法实现:

from scipy import linalg

import numpy as np

from sklearn.datasets import make_blobs

def K_means(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()]

    #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

 

data1=np.array([[1,1],[1,2],[2,1],[5,5],[5,6],[6,5],[0.5,2],[0.5,1],[1.5,2],[1.5,1],[1.414,1.414],          [2.414,2.414],[0.5,1.414],[1.5,2.414],[1.5,1.414],[5,5.5],[6,5.5],[6,6],[6,7.5],[3,3.5],           [0.75,0.25],[0.75,1.2378],[0.75,0.674],[0.85,1.853],[0.993,2.132],[1.23,1.813],[1.52,1.73],[1.99,2.1],               [1.77,1.9],[2.33,2.90],[2.53,2.21],[2.36,2.11],[2.7,2.9],[2.46,2.71],[2.38,2.9031],              [3.23,3.88],[3.11,3.8310],[3.889,3.59012],[3.9022,4.331],[3.8902,3.7294],[3.221045,3.990233]])

data_2=K_means(data1,3)   

import matplotlib.pyplot as plt

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

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

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

data_class2=np.array(data_2[1][2])

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_class2[:,0],data_class2[:,1],color='g',marker='+')

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

axes_1.scatter(data_2[0][1,0],data_2[0][1,1],color='b',marker='|')

axes_1.scatter(data_2[0][2,0],data_2[0][2,1],color='g',marker='1')

plt.show()

u12ntitled