文章目录
聚类
一、概念
-
无监督学习:
无监督学习(Unsupervised learning):训练样本的标记信息是未知的,目标是为了揭露训练样本的内在属性,结构和信息,为进一步的数据挖掘提供基础。 -
监督学习:
监督学习(supervised learning):训练样本带有信息标记,利用已有的训练样本信息学习数据的规律预测未知的新样本标签 -
聚类:
聚类是一种最常用的无监督学习方法,对点集进行考察并按照某种 距离测度 将他们聚成多个“簇”的过程。聚类的目标是使得同一簇内的点之间的距离较短,而不同簇中点之间的距离较大。
二、聚类的类别
1. 基于划分的聚类
-
基本思想:
划分法(partitioning methods),给定一个有 N 个元组或者纪录的数据集,划分法将构造 K 个分组,每一个分组就代表一个聚类,K < N。而且这 K 个分组满足下列条件:
(1) 每一个分组至少包含一个数据纪录;
(2)每一个数据纪录属于且仅属于一个分组(注意:这个要求在某些模糊聚类算法中可以放宽); -
特点:
计算量大,很适合发现中小规模的数据库中小规模的数据库中的球状簇。 -
主要算法:
k-means、k-medoids、k-modes、k-medians、kernel k-means等算法。 -
算法过程:
K-maens算法过程:- 随机选择K个中心值
- 根据样本数据各点与中心点的距离来进行归簇
- 通过各个簇的均值,更新为每个簇的中心值
- 重复2、3,直至聚类中心的位置不再变化
详情参考博客:https://blog.csdn.net/pentiumCM/article/details/103657283
2. 基于层次的聚类
-
基本思想:
基于层次的聚类算法(Hierarchical Clustering)有两种类型:凝聚的(Agglomerative)层次聚类和分裂的(Divisive)层次聚类。取决于层次的划分是“自底向上”还是“自顶向下”。
凝聚层次聚类是 “自底向上” 的层次聚类算法,最初将每个数据看成一个簇,从最底层开始,每一次通过合并最相似的聚类来形成上一层次中的聚类,当全部数据点都合并到一个聚类的时候停止或者达到某个终止条件而结束,大部分层次聚类都是采用这种方法处理。
分裂的(Divisive)层次聚类是 “自顶向下“” 的方法,从一个包含全部数据点的聚类开始,然后把根节点分裂为一些子聚类,每个子聚类再递归地继续往下分裂,直到出现只包含一个数据点的单节点聚类出现,即每个聚类中仅包含一个数据点。 -
特点:
-
算法流程:
以下流程以 “自下向上”为例:- 将每个数据看作一类,计算两两之间的最小距离;
- 将距离最小的两个类合并成一个新类;
- 重新计算新类与所有类之间的距离;
- 重复2、3,直到所有类最后合并成一类
-
示例:
如对以下 5 个点进行凝聚层次聚类。
x | y | |
---|---|---|
点0 | 1 | 2 |
点1 | 2 | 3 |
点2 | -3 | 3 |
点3 | -2 | -1 |
点4 | 5 | -1 |
在坐标轴上的位置:层次聚类结果的聚类树为:
我们可以看出层次聚类的过程为:
首先将5个点分别看成一簇,为簇0、簇1、簇2、簇3、簇4,
然后将 簇0 和 簇1 聚集作为新的簇为 簇5,继续聚集将 簇2 和 簇3 聚成新簇为簇6,然后聚集 簇5 和 簇6 为新簇为簇7,最后将簇4和簇7聚集为簇8,这时候所有的数据被聚集在一个簇中,算法结束。
- 算法实现:
采用了 python 的 scipy 模块
#!/usr/bin/env python
# encoding: utf-8
'''
@Author : pentiumCM
@Email : 842679178@qq.com
@Software: PyCharm
@File : sci_cluster.py
@Time : 2020/4/15 22:21
@desc : scipy实现层次聚类
'''
import numpy as np
from scipy.cluster.hierarchy import dendrogram, linkage, fcluster
from matplotlib import pyplot as plt
data = np.array([[1, 2], [2, 3], [-3, 3], [-2, -1], [5, -1]])
# 画点
plt.scatter(x=data[:, 0:1], y=data[:, 1:2], marker='.', color='red')
n = np.arange(data.shape[0])
for i, txt in enumerate(n):
plt.annotate(txt, (data[i:i + 1, 0:1], data[i:i + 1, 1:2]))
plt.show()
# 1. 层次聚类
# linkage方法用于计算两个聚类簇s和t之间的距离d(s,t)
# 层次聚类编码为一个linkage矩阵。
Z = linkage(data, 'average')
print("聚类过程:", Z)
# 从给定链接矩阵定义的层次聚类中形成平面聚类。
f = fcluster(Z, 4, 'distance')
fig = plt.figure(figsize=(5, 3))
# 将层级聚类结果以树状图表示出来
dn = dendrogram(Z)
plt.show()
算法运行结果:
聚类的主要信息在 Z = linkage(data, ‘average’)中。
Z共有四列组成,第 1 字段与第 2 字段分别为聚类簇的编号,在初始距离前每个初始值被从0~n-1进行标识,每生成一个新的聚类簇就在此基础上增加一对新的聚类簇进行标识,第 3 个字段表示前两个聚类簇之间的距离,第 4 个字段表示新生成聚类簇所包含的元素的个数。
聚类过程: [[0. 1. 1.41421356 2. ]
[2. 3. 4.12310563 2. ]
[5. 6. 4.75565014 4. ]
[4. 7. 6.48606798 5. ]]
层次聚类可以一次性聚类出所有的情况,当生成出聚类树的结果时,可以通过在聚类树上画水平线来选择聚成几类的结果。如用户需要聚成两类:只需要从上往下画出如上图的水平线来判断聚成两类的结果,可以看出两类的结果,一类为 4,另一类为0、1、2、3。
如果需要聚成3类,只需要将水平线往下平移即可知道聚成三类的结果。
3. 基于密度的聚类
4. 基于网格的聚类
5. 基于模型的聚类
6. 基于模糊的聚类
三、聚类的相似度度量
聚类需要根据 样本特征的相似度 或者 距离 来作为是否归属于某一类的依据,也就是相似的样本归为一类,不相似的样本不归为一类。
度量样本特征的相似度或者距离有多种方式:
1. 闵氏距离:
- 当 p = 1 时,得到绝对值距离,称为曼哈顿距离:
- 当 p = 2 时,称为欧式距离:
- 当 p = ∞ 时,称为切比雪夫距离:
闵氏距离是一组距离的定义,随着次数的增加,向量分量中的大值对距离的贡献会越大,极端下切比雪夫距离只考虑最大的那个分量。一般常用欧式距离。
缺点:(1)没有考虑分量的量纲的影响,相同的特征,变换一下量纲级别就会导致完全不一样的结果。(2)没有考虑各个分量之间的分布(期望,方差),马氏距离解决了这个问题。
2. 马氏距离:
两个服从同一分布并且其整体样本的协方差矩阵为 S 的 样本点 Xi 与 Xj 的差异程度: 当协方差矩阵为单位矩阵的时候,马氏距离就等于欧式距离,当协方差矩阵仅为对角矩阵的时候,即为标准化之后的欧式距离。
马氏距离的两个优点:一是排除了量纲的影响,相当于标准化了,二是排除了变量之间的相关性的影响,相当除掉掉了向量线性相关部分。
马氏距离的缺点:夸大了变化微小变量的作用。