机器学习Sklearn系列:(五)聚类算法

K-means

原理

首先随机选择k个初始点作为质心

1. 对每一个样本点,计算得到距离其最近的质心,将其类别标记为该质心对应的类别
2. 使用归类好的样本点,重新计算K个类别的质心
3. 重复上述过程,直到质心不发生变化

距离计算方法

在K-Means算法中,需要注意的是,对于距离的计算有很多中方法:

(1)闵可夫斯基距离( Minkowski )

\[d(x,y) = (\sum_{i=1}^n|x_i-y_i|^p)^{\frac{1}{p}} \]

注意这里p=2时则为常用的欧氏距离。

(2) 余弦相似度( Cosine Similarity )

\[d(x,y) = cos(\theta) = \frac{x^Ty}{|x| \cdot|y| } = \frac{\sum_{i=1}^n x_iy_i}{\sqrt{\sum_{i=1}^n x_i^2} \sqrt{\sum_{i=1}^n y_i^2 }} \]

(3) 皮尔逊相关系数 ( Pearson Coefficient )

\[p(x,y) = \frac{cov(x,y)}{\sigma_x \sigma_y} = \frac{\sum_{i=1}^n(x_i-\mu_x)(y_i-\mu_y)}{\sqrt{\sum_{i=1}^n(x_i-\mu_x)^2}\sqrt{\sum_{i=1}^n(y_i-\mu_y)^2}} \]

sklearn中的k-mean方法

class sklearn.cluster.KMeans (n_clusters=8, init=’k-means++’, 
n_init=10, max_iter=300, tol=0.0001,
precompute_distances=’auto’, verbose=0,
random_state=None, copy_x=True, n_jobs=None, 
algorithm=’auto’)

n_clusters: 设置聚类的数量

init:设置初心质心的方法,可输入"k-means++","random"或者一个n维数组。这是初始化质心的方法,默认"k-means++"。输入k-means++":一种为K均值聚类选择初始聚类中心的聪明的办法,以加速收敛。如果输入了n维数组,数组的形状应该是(n_clusters,n_features)并给出初始质心。

random_state:控制每次质心随机初始化的随机数种子

n_init:整数,默认10,使用不同的质心随机初始化的种子来运行k-means算法的次数。最终结果会是基于Inertia来计算的n_init次连续运行后的最佳输出。等价于运行10次,选择最好一次的质心种子

max_iter:整数,默认300,单次运行的k-means算法的最大迭代次数

tol:浮点数,默认1e-4,两次迭代间Inertia下降的量,如果两次迭代之间Inertia下降的值小于tol所设定的值,迭代就会停下

precompute_distances: 是否余弦把所有点之间的距离计算出来,这样的好处是在后面只需要检索,不需要计算了,但是比较耗费内存。

一个例子:

from sklearn cluster import KMeans

model = Kmeans(n_cluster=3, max_iter=10)

model.cluster_centers_   #获取聚类中心
model.labels  #获取样本所属类别
model.inertia # 查看总距离平方和,主要用来比较聚类效果 

层级聚类AgglomerativeClustering

层次聚类的思想是通过层次化的自上而下,或者下而上来将相似的类别归到一起,最终实现聚类目的。具体流程如下:

1. 首先将所有样本都看做成是单独的类别,m个样本表示m 个类别
2. 计算类别之间的距离,然后将距离最短的两个类进行合并。
3. 重复2操作,直到类别个数为设置的聚类数k停止。

在层次聚类中,有两个点需要注意,第一是选择哪个作为类别的代表,二是两个类别的代表点如何计算距离。这其中,距离的计算选择比较多,例如上述K-Means聚类中提到的算法,都是可以的,但是关于类比代表的选择是需要多关注的,这个会影响聚类的效果,在实际应用中可以灵活选择。

关于代表点的选择有以下几种方法, 不同的代表点选择方法,也就代表了不同的类别融合方法

  1. 最小距离
    选择两个类之间距离最近的两个点作为代表点

  2. 最大距离
    选择两个类之间距离最远的点作为代表点

  3. 中心距离
    计算类别中的平均值,作为代表点

  4. 均值距离
    计算两个类别所有点之间的距离,求平均,然后平均值最小的进行融合

  5. 最小方差
    直接将几个类别俩俩混到一起,计算方差,方差小的两个类融合到一起

sklearn中的层次聚类

from sklearn.cluster import AgglomerativeClustering
model = AgglomerativeClustering(n_clusters=3,affinity="euclidean",
linkage="complete")
print("每个样本的举例",model.labels_)

这里有两个参数需要注意:

affinity: 主要表示距离计算的方法

linkage: 表示两个类别之间的融合方法,有些也可以理解为两个类中代表点的选择方法,常用的方法如下:

# ward 最小方差
# complete 最大距离
# average 平均距离
# single 最小距离 

密度聚类 DBSCAN

密度聚类不同于上述的两种,密度聚类是不需要设置聚类的个数的,它可以自动找到聚类的个数,但是相应的,密度聚类需要其他参数的设置,这些设置会影响最终聚类的效果。

在理解密度聚类之前,需要理解几个概念:

  1. \(\epsilon\)邻域

  2. 核心对象(Core object)

  3. 密度直达( directly density-reachable)

  4. 密度可达( density-reahable)

假设样本空间一个点为 \(x\), 那么\(\epsilon\)邻域表示的是,以\(x\)为中心,\(\epsilon\)为半径的空间。如果这个空间内,样本的数量≥ minpts(预先设置的样本阈值)这个时候,\(x\)可以被称为这个空间的核心对象。同时,如果存在一个样本点\(x_i\),处于以\(x\)为核心对象的\(\epsilon\)邻域内,那么就称为密度直达。假设有n个核心对象\(x_1,x_2....x_n\), 如果有一条路径是的\(x_1\)通过多次 密度直达 到达\(x_n\), 那么就称为密度可达。

密度聚类算法原理

算法思路,注意这里这个方法不需要指定要最终要聚多少类别

  1. 首先要设置一个参数是邻域半径\(\epsilon\),其次是核心对象所需要的最小点个数minpts
  2. 确定核心对象,通过设置的邻域半径和最小点个数,可以找到所有满足要求的核心对象,并保存到一个列表\(\Omega\)中。
  3. 从列表\(\Omega\)随机选择一个核心对象\(x\),找到所有\(x\)密度可达的所有样本,组成一个类别,并且将已经归类的核心对象从\(\Omega\)中所找的的列表中删除。
  4. 重复步骤3 , 直到所有核心对象列表为空结束。

sklearn中的密度聚类


from sklearn.cluster import DBSCAN
model = DBScan(eps = 0.5, min_samples = 5, metric = "euclidean")
model.fit(X)
print(model.labels_) 

这里eps就是上述的参数\(\epsilon\), min_samples就是上述的参数minpts, metric参数用来设置距离计算方法。

应用-压缩信息

聚类算法一个很大的应用就是信息压缩,可以将数据进行聚类,然后,使用类别中的一个样本代替全体样本。

posted @ 2021-07-22 18:37  Neo0oeN  阅读(847)  评论(0编辑  收藏  举报