8-聚类算法
文章链接:https://gitee.com/fakerlove/machine-learning
8.1 聚类任务
什么是聚类,聚类是做什么的
8.1.1 概念
机器学习里面的聚类是无监督 的学习问题,它的目标是为了感知样本间的相似度进行类别归纳 。它可以用于潜在类别的预测以及数据压缩上去。
潜在类别预测,比如说可以基于通过某些常听的音乐而将用户进行不同的分类。数据压缩则是指将样本进行归类后,就可以用比较少的的One-hot向量来代替原来的特别长的向量。
聚类,既可以作为一个单独的过程,也可以作为其他机器学习任务的预处理模块。
8.1.2 问题描述
给定一个包含
N
N
N个样本的样本集
X
=
{
x
1
,
x
2
,
.
.
.
,
x
N
}
X=\{x_1,x_2,...,x_N\}
X={x1?,x2?,...,xN?},要给对这N个样本给定一个划分方式,将这些样本划分为m类
C
1
,
C
2
,
C
3
,
.
.
.
,
C
m
C_1,C_2,C_3,...,C_m
C1?,C2?,C3?,...,Cm?,使得满足
C
i
≠
?
,
i
=
1
,
2
,
.
.
.
,
m
C_i\ne \phi,i=1,2,...,m
Ci??=?,i=1,2,...,m
U
i
=
1
,
2
,
.
.
,
m
C
i
=
X
U_{i=1,2,..,m}C_i=X
Ui=1,2,..,m?Ci?=X
C
i
?
C
j
=
?
,
i
≠
j
C_i\bigcap C_j=\phi,i\ne j
Ci??Cj?=?,i?=j
8.1.3 算法分类

聚类算法主要有:
- 序贯法
- 层次分析法
- 基于损失函数最优化的:K-means,概率聚类
- 基于密度的聚类
- 其他特殊聚类方法:基因聚类算法,分治限界聚类算法;子空间聚类算法;基于核的聚类方法。
问题的提出
虽然 聚类看起来是很棒的,可以进行“物以类分,人以类聚”,但是聚类确守很多方面的影响。 例如: 1.属性选择不同,导致不同的结果 2.相似度度量不同,导致不同的结果 3.聚类的方法不同,导致不同的结果
如何衡量无监督学习的指标
8.1.4 数学准备
样本集合中由n个样本,每个样本由m个属性的特征向量组成,样本集合可以用矩阵X表示:
X
=
[
x
i
j
]
m
×
n
=
[
x
11
x
12
?
x
1
n
x
21
x
22
?
x
2
n
?
?
?
?
x
m
1
x
m
2
?
x
m
n
]
X=[x_{ij}]_{m\times n}=\begin{bmatrix} x_{11}&x_{12}&\cdots&x_{1n} \\ x_{21}&x_{22}&\cdots&x_{2n} \\ \vdots &\vdots&\cdots&\vdots \\ x_{m1}&x_{m2}&\cdots&x_{mn} \end{bmatrix}
X=[xij?]m×n?=??????x11?x21??xm1??x12?x22??xm2???????x1n?x2n??xmn???????? 给定样本集合X,
x
i
,
x
j
∈
X
,
x
i
=
(
x
1
i
,
x
2
i
,
.
.
.
,
x
m
i
)
T
,
x
j
=
(
x
1
j
,
x
2
j
,
.
.
.
,
x
m
j
)
T
x_i,x_j\in X,x_i=(x_{1i},x_{2i},...,x_{mi})^T,x_j=(x_{1j},x_{2j},...,x_{mj})^T
xi?,xj?∈X,xi?=(x1i?,x2i?,...,xmi?)T,xj?=(x1j?,x2j?,...,xmj?)T
1) 类或簇
用
G
G
G表示类或簇,用
x
i
,
x
j
x_i,x_j
xi?,xj?表示类中的样本,
N
G
N_G
NG?表示
G
G
G中的样本个数,
d
i
j
d_{ij}
dij?表示样本
x
i
x_i
xi?与样本
x
j
x_j
xj?之间的距离
类或簇的定义
设给定的整数 ,若集合
G
G
G中的任意两个样本
x
i
,
x
j
x_i,x_j
xi?,xj?,有
d
i
j
≤
T
d_{ij}\le T
dij?≤T, 则称
G
G
G表示为一个类或簇
2) 类或簇的特征
-
类的均值
x
 ̄
G
=
1
N
G
∑
i
=
1
N
G
x
i
\overline{x}_G=\frac{1}{N_G}\sum_{i=1}^{N_G}x_i
xG?=NG?1?∑i=1NG??xi? -
类的直径
D
G
=
m
a
x
x
i
,
x
j
∈
G
d
i
j
D_G=max_{x_i,x_j\in G}d_{ij}
DG?=maxxi?,xj?∈G?dij? -
类的样本散步矩阵
A
G
=
∑
i
=
1
N
G
(
x
i
?
x
 ̄
G
)
(
x
i
?
x
 ̄
G
)
T
A_G=\sum_{i=1}^{N_G}(x_i-\overline{x}_G)(x_i-\overline{x}_G)^T
AG?=∑i=1NG??(xi??xG?)(xi??xG?)T -
样本协方差矩阵
S
G
=
1
m
?
1
A
G
S_G=\frac{1}{m-1}A_G
SG?=m?11?AG?
=
1
m
?
1
∑
i
=
1
N
G
(
x
i
?
x
 ̄
G
)
(
x
i
?
x
 ̄
G
)
T
=\frac{1}{m-1}\sum_{i=1}^{N_G}(x_i-\overline{x}_G)(x_i-\overline{x}_G)^T
=m?11?∑i=1NG??(xi??xG?)(xi??xG?)T
3) 类与类之间的距离
类
C
p
C_p
Cp?和类
C
q
C_q
Cq?之间的距离
D
(
p
,
q
)
D(p,q)
D(p,q),也称为连接
前四种方法定义的
C
p
C_p
Cp?和
C
q
C_q
Cq?之间的距离如下表所示。
相似度度量标准(距离大小) | |
---|
最短距离或单连接(Single-link) | $D_{pq}=min{d_{ij | 最长距离或完全连接(Complete-link) | $D_{pq}=max{d_{ij} | 中心距离 |
D
p
q
=
d
x
 ̄
p
x
 ̄
q
D_{pq}=d_{\overline{x}_p\overline{x}_q}
Dpq?=dxp?xq?? | 平均距离(UPGMA) |
D
p
q
=
1
C
p
C
q
∑
x
i
∈
C
p
∑
x
j
∈
C
q
d
i
j
D_{pq}=\frac{1}{C_pC_q}\sum_{x_i \in C_p}\sum_{x_j \in C_q}d_{ij}
Dpq?=Cp?Cq?1?∑xi?∈Cp??∑xj?∈Cq??dij? |
8.2 评价指标
评价聚类算法性能好坏的
聚类性能度量大致分两类,
一类是将聚类结果与某个"参考模型",进行比较,称为外部指标,
另一类是直接参考聚类结果而不利用任何参考模型,称为内部指标
8.2.1 外部指标
a
=
∣
S
S
∣
,
S
S
=
{
(
x
i
,
x
j
)
∣
λ
i
=
λ
j
,
λ
i
?
=
λ
j
?
,
i
<
j
}
b
=
∣
S
D
∣
,
S
D
=
{
(
x
i
,
x
j
)
∣
λ
i
=
λ
j
,
λ
i
?
≠
λ
j
?
,
i
<
j
}
c
=
∣
D
S
∣
,
D
S
=
{
(
x
i
,
x
j
)
∣
λ
i
≠
λ
j
,
λ
i
?
=
λ
j
?
,
i
<
j
}
b
=
∣
D
D
∣
,
D
D
=
{
(
x
i
,
x
j
)
∣
λ
i
≠
λ
j
,
λ
i
?
≠
λ
j
?
,
i
<
j
}
a=|SS|,SS=\{(x_i,x_j)|\lambda_i=\lambda_j,\lambda_i^*=\lambda_j^*,i<j\} \\ b=|SD|,SD=\{(x_i,x_j)|\lambda_i=\lambda_j,\lambda_i^*\ne\lambda_j^*,i<j\} \\ c=|DS|,DS=\{(x_i,x_j)|\lambda_i\ne \lambda_j,\lambda_i^*=\lambda_j^*,i<j\} \\ b=|DD|,DD=\{(x_i,x_j)|\lambda_i\ne\lambda_j,\lambda_i^*\ne\lambda_j^*,i<j\}
a=∣SS∣,SS={(xi?,xj?)∣λi?=λj?,λi??=λj??,i<j}b=∣SD∣,SD={(xi?,xj?)∣λi?=λj?,λi???=λj??,i<j}c=∣DS∣,DS={(xi?,xj?)∣λi??=λj?,λi??=λj??,i<j}b=∣DD∣,DD={(xi?,xj?)∣λi??=λj?,λi???=λj??,i<j}
和混淆矩阵 差不多。
其中a表示
C
C
C中隶属于相同簇 且在与
C
?
C^*
C?也属于相同簇 的样本对 ,
b
b
b表示
C
C
C中隶属于相同簇 但在与
C
?
C^*
C?中隶属于不同簇 的样本对
1) Jaccard系数
(Jaccard Coefficient,简称JC)
J
C
=
a
a
+
b
+
c
JC=\frac{a}{a+b+c}
JC=a+b+ca?
2) FM指数
Fowlkes adn Mallows Index,简称FMI
F
M
I
=
a
a
+
b
?
a
a
+
c
FMI=\sqrt{\frac{a}{a+b}\cdot \frac{a}{a+c}}
FMI=a+ba??a+ca?
?
3) Ran指数
可知
a
+
b
+
c
+
d
=
m
(
m
?
1
)
/
2
a+b+c+d=m(m-1)/2
a+b+c+d=m(m?1)/2
Rand Index,简称RI
m表示样本总数
R
=
a
+
d
a
+
b
+
c
+
d
=
2
(
a
+
d
)
m
(
m
?
1
)
R=\frac{a+d}{a+b+c+d}=\frac{2(a+d)}{m(m-1)}
R=a+b+c+da+d?=m(m?1)2(a+d)?
4) Mirkin指数
M
K
=
b
+
c
a
+
b
+
c
+
d
=
2
(
b
+
c
)
m
(
m
?
1
)
MK=\frac{b+c}{a+b+c+d}=\frac{2(b+c)}{m(m-1)}
MK=a+b+c+db+c?=m(m?1)2(b+c)?
上诉性能度量的结果均在[0,1]之间,值越大越好
例子
下面,一共有5 个样本,分成2 簇。
使用聚类计算的答案
类别 | 物体 |
---|
C
1
C_1
C1? |
x
1
,
x
2
,
x
3
x_1,x_2,x_3
x1?,x2?,x3? |
C
2
C_2
C2? |
x
4
,
x
5
x_4,x_5
x4?,x5? |
目标答案
类别 | 物体 |
---|
C
1
?
C_1^*
C1?? |
x
1
,
x
2
,
x
4
x_1,x_2,x_4
x1?,x2?,x4? |
C
2
?
C_2^*
C2?? |
x
3
,
x
5
x_3,x_5
x3?,x5? |
根据上面计算的和目标答案,做出
a表示
C
C
C中隶属于相同簇 且在与
C
?
C^*
C?也属于相同簇 的样本对 。只有
(
x
1
,
x
2
)
(x_1,x_2)
(x1?,x2?)符合这样子的条件。
在
C
C
C中
(
x
1
,
x
2
)
(x_1,x_2)
(x1?,x2?)属于
C
1
C_1
C1?簇,在
C
?
C^*
C?中
(
x
1
,
x
2
)
(x_1,x_2)
(x1?,x2?)属于
C
1
C_1
C1?簇。其他都不满足
| | |
---|
a=|SS| |
(
x
1
,
x
2
)
(x_1,x_2)
(x1?,x2?) | 1 | b=|SD| |
(
x
1
,
x
3
)
,
(
x
2
,
x
3
)
,
(
x
4
,
x
5
)
(x_1,x_3),(x_2,x_3),(x_4,x_5)
(x1?,x3?),(x2?,x3?),(x4?,x5?) | 3 | c=|DS| |
(
x
1
,
x
4
)
,
(
x
2
,
x
4
)
,
(
x
3
,
x
5
)
(x_1,x_4),(x_2,x_4),(x_3,x_5)
(x1?,x4?),(x2?,x4?),(x3?,x5?) | 3 | d=|DD| |
(
x
1
,
x
5
)
,
(
x
2
,
x
5
)
,
(
x
3
,
x
4
)
(x_1,x_5),(x_2,x_5),(x_3,x_4)
(x1?,x5?),(x2?,x5?),(x3?,x4?) | 3 |
计算的外部指标为
J
C
=
a
a
+
b
+
c
=
1
7
JC=\frac{a}{a+b+c}=\frac{1}{7}
JC=a+b+ca?=71?
F
M
I
=
a
a
+
b
?
a
a
+
c
=
1
4
FMI=\sqrt{\frac{a}{a+b}\cdot \frac{a}{a+c}}=\frac{1}{4}
FMI=a+ba??a+ca?
?=41?
R
=
2
(
a
+
d
)
m
(
m
?
1
)
=
2
5
R=\frac{2(a+d)}{m(m-1)}=\frac{2}{5}
R=m(m?1)2(a+d)?=52?
8.2.2 内部指标
考虑聚类结果的簇划分
C
=
{
C
1
,
C
2
,
?
?
,
C
k
}
C=\{C_1,C_2,\cdots,C_k\}
C={C1?,C2?,?,Ck?}定义
a
v
g
(
C
)
=
2
∣
C
∣
(
∣
C
∣
?
1
)
∑
1
≤
i
<
j
≤
∣
C
∣
d
i
s
t
(
x
i
,
x
j
)
d
i
a
m
(
C
)
=
max
?
1
≤
i
<
j
≤
∣
C
∣
d
i
s
t
(
x
i
,
x
j
)
d
m
i
n
(
C
i
,
C
j
)
=
min
?
x
i
∈
C
i
,
x
j
∈
C
j
d
i
s
t
(
x
i
,
x
j
)
d
c
e
n
(
C
i
,
C
j
)
=
d
i
s
t
(
μ
i
,
μ
j
)
avg(C)=\frac{2}{|C|(|C|-1)}\sum_{1\le i<j\le|C|}dist(x_i,x_j) \\ diam(C)=\max_{1\le i<j\le|C|}dist(x_i,x_j) \\ d_{min}(C_i,C_j)=\min_{x_i\in C_i,x_j\in C_j} dist(x_i,x_j) \\ d_{cen}(C_i,C_j)=dist(\mu_i,\mu_j)
avg(C)=∣C∣(∣C∣?1)2?1≤i<j≤∣C∣∑?dist(xi?,xj?)diam(C)=1≤i<j≤∣C∣max?dist(xi?,xj?)dmin?(Ci?,Cj?)=xi?∈Ci?,xj?∈Cj?min?dist(xi?,xj?)dcen?(Ci?,Cj?)=dist(μi?,μj?) 举个例子

avg?–簇内样本 的平均距离
a
v
g
(
C
1
)
=
2
3
×
(
3
?
1
)
×
(
∣
x
1
?
x
2
∣
+
∣
x
1
?
x
3
∣
+
∣
x
2
?
x
3
∣
)
a
v
g
(
C
2
)
=
2
2
×
(
2
?
1
)
×
(
∣
x
4
?
x
5
∣
)
a
v
g
(
C
3
)
=
2
2
×
(
2
?
1
)
×
(
∣
x
6
?
x
7
∣
)
avg(C_1)=\frac{2}{3\times (3-1)}\times(|x_1-x_2|+|x_1-x_3|+|x_2-x_3|) \\ avg(C_2)=\frac{2}{2\times (2-1)}\times(|x_4-x_5|) \\ avg(C_3)=\frac{2}{2\times (2-1)}\times(|x_6-x_7|)
avg(C1?)=3×(3?1)2?×(∣x1??x2?∣+∣x1??x3?∣+∣x2??x3?∣)avg(C2?)=2×(2?1)2?×(∣x4??x5?∣)avg(C3?)=2×(2?1)2?×(∣x6??x7?∣) diam?–簇内样本 的最大距离
d
i
a
m
(
C
1
)
=
∣
x
1
?
x
3
∣
d
i
a
m
(
C
2
)
=
∣
x
4
?
x
5
∣
d
i
a
m
(
C
3
)
=
∣
x
6
?
x
7
∣
diam(C_1)=|x_1-x_3| \\ diam(C_2)=|x_4-x_5| \\ diam(C_3)=|x_6-x_7|
diam(C1?)=∣x1??x3?∣diam(C2?)=∣x4??x5?∣diam(C3?)=∣x6??x7?∣ dmin(Ci,Cj)–簇间样本 的最小距离
d
m
i
n
(
C
1
,
C
2
)
=
∣
x
3
?
x
4
∣
d
m
i
n
(
C
2
,
C
3
)
=
∣
x
5
?
x
6
∣
d
m
i
n
(
C
1
,
C
3
)
=
∣
x
3
?
x
6
∣
dmin(C_1,C_2)=|x_3-x_4| \\ dmin(C_2,C_3)=|x_5-x_6| \\ dmin(C_1,C_3)=|x_3-x_6|
dmin(C1?,C2?)=∣x3??x4?∣dmin(C2?,C3?)=∣x5??x6?∣dmin(C1?,C3?)=∣x3??x6?∣ dcen(Ci,Cj)–簇中心间距离
μ
1
=
(
C
1
,
C
2
)
=
x
1
+
x
2
+
x
3
3
,
μ
2
=
x
4
+
x
5
2
,
μ
3
=
x
6
+
x
7
2
d
c
e
n
(
C
1
,
C
2
)
=
∣
μ
1
?
μ
2
∣
d
c
e
n
(
C
2
,
C
3
)
=
∣
μ
2
?
μ
2
∣
d
c
e
n
(
C
1
,
C
3
)
=
∣
μ
1
?
μ
3
∣
\mu_1=(C_1,C_2)=\frac{x_1+x_2+x_3}{3},\mu_2=\frac{x_4+x_5}{2},\mu_3=\frac{x_6+x_7}{2} \\ dcen(C_1,C_2)=|\mu_1-\mu_2| \\ dcen(C_2,C_3)=|\mu_2-\mu_2| \\ dcen(C_1,C_3)=|\mu_1-\mu_3|
μ1?=(C1?,C2?)=3x1?+x2?+x3??,μ2?=2x4?+x5??,μ3?=2x6?+x7??dcen(C1?,C2?)=∣μ1??μ2?∣dcen(C2?,C3?)=∣μ2??μ2?∣dcen(C1?,C3?)=∣μ1??μ3?∣
DB指数
D
B
I
=
1
k
∑
i
=
1
k
max
?
j
≠
i
(
a
v
g
(
C
i
)
+
a
v
g
(
C
j
)
d
c
e
n
(
μ
i
,
μ
j
)
)
DBI=\frac{1}{k}\sum_{i=1}^k\max_{j\ne i}(\frac{avg(C_i)+avg(C_j)}{d_{cen}(\mu_i,\mu_j)})
DBI=k1?i=1∑k?j?=imax?(dcen?(μi?,μj?)avg(Ci?)+avg(Cj?)?)
Dunn指数
D
I
=
min
?
1
≤
i
≤
k
{
min
?
j
≠
i
(
d
m
i
n
(
C
i
,
C
j
)
max
?
1
≤
l
≤
k
d
i
a
m
(
C
l
)
}
DI=\min_{1\le i\le k}\{\min_{j\ne i}(\frac{d_{min(C_i,C_j)}}{\max_{1\le l\le k}diam(C_l)}\}
DI=1≤i≤kmin?{j?=imin?(max1≤l≤k?diam(Cl?)dmin(Ci?,Cj?)??}
8.3 距离计算(相似度)
距离越大,相似度越小
样本集合中由
n
n
n个样本,每个样本由
m
m
m个属性的特征向量组成,样本集合可以用矩阵
X
X
X表示:
X
=
[
x
i
j
]
m
×
n
=
[
x
11
x
12
?
x
1
n
x
21
x
22
?
x
2
n
?
?
?
?
x
m
1
x
m
2
?
x
m
n
]
X=[x_{ij}]_{m\times n}=\begin{bmatrix} x_{11}&x_{12}&\cdots&x_{1n} \\ x_{21}&x_{22}&\cdots&x_{2n} \\ \vdots &\vdots&\cdots&\vdots \\ x_{m1}&x_{m2}&\cdots&x_{mn} \end{bmatrix}
X=[xij?]m×n?=??????x11?x21??xm1??x12?x22??xm2???????x1n?x2n??xmn???????? 给定样本集合X,
x
i
,
x
j
∈
X
,
x
i
=
(
x
1
i
,
x
2
i
,
.
.
.
,
x
m
i
)
T
,
x
j
=
(
x
1
j
,
x
2
j
,
.
.
.
,
x
m
j
)
T
x_i,x_j\in X,x_i=(x_{1i},x_{2i},...,x_{mi})^T,x_j=(x_{1j},x_{2j},...,x_{mj})^T
xi?,xj?∈X,xi?=(x1i?,x2i?,...,xmi?)T,xj?=(x1j?,x2j?,...,xmj?)T
1) 性质
- 非负性
d
i
j
≥
0
d_{ij}\ge 0
dij?≥0
- 同一性
d
i
j
=
0
d_{ij}=0
dij?=0,当且仅当
i
=
j
i=j
i=j
- 对称性
d
i
j
=
d
j
i
d_{ij}=d_{ji}
dij?=dji?
- 直递性
d
i
j
≤
d
i
k
+
d
k
j
d_{ij}\le d_{ik}+d_{kj}
dij?≤dik?+dkj?
2) 闵可夫斯基距离
d
i
j
=
(
∑
k
=
1
m
∣
x
k
i
?
x
k
j
∣
p
)
1
p
,
p
≥
1
d_{ij}=(\sum_{k=1}^m|x_{ki}-x_{kj}|^p)^{\frac{1}{p}},p\ge 1
dij?=(∑k=1m?∣xki??xkj?∣p)p1?,p≥1
欧氏距离
两点之间直线最短
当
p
=
2
p=2
p=2时称为欧氏距离(Euclidean distance)
d
i
j
=
(
∑
k
=
1
m
∣
x
k
i
?
x
k
j
∣
2
)
1
2
d_{ij}=(\sum_{k=1}^m|x_{ki}-x_{kj}|^2)^{\frac{1}{2}}
dij?=(∑k=1m?∣xki??xkj?∣2)21?
曼哈顿距离
当p=1时称为曼哈顿距离(Manhattan distance)
d
i
j
=
∑
k
=
1
m
∣
x
k
i
?
x
k
j
∣
d_{ij}=\sum_{k=1}^m|x_{ki}-x_{kj}|
dij?=∑k=1m?∣xki??xkj?∣
切比雪夫距离
当p=
∞
\infty
∞时称为切比雪夫距离(Chebyshev distance)
d
i
j
=
m
a
x
k
∣
x
k
i
?
x
k
j
∣
d_{ij}=max_k|x_{ki}-x_{kj}|
dij?=maxk?∣xki??xkj?∣
3) 马哈拉诺比斯距离
给定一个样本集
X
X
X,
X
=
[
x
i
j
]
m
×
n
X=[x_{ij}]_{m \times n}
X=[xij?]m×n?,其协方差矩阵为S,样本
x
i
x_i
xi?与样本
x
j
x_j
xj?之间的马哈拉诺比斯距离距离
d
i
j
d_{ij}
dij?定义为
d
i
j
=
[
(
x
i
?
x
j
)
T
S
?
1
(
x
i
?
x
j
)
]
1
2
x
i
=
(
x
1
i
,
x
2
i
,
.
.
.
,
x
m
i
)
T
,
x
j
=
(
x
1
j
,
x
2
j
,
.
.
.
,
x
m
j
)
T
d_{ij}=[(x_i-x_j)^TS^{-1}(x_i-x_j)]^{\frac{1}{2}} \\ x_i=(x_{1i},x_{2i},...,x_{mi})^T,x_j=(x_{1j},x_{2j},...,x_{mj})^T
dij?=[(xi??xj?)TS?1(xi??xj?)]21?xi?=(x1i?,x2i?,...,xmi?)T,xj?=(x1j?,x2j?,...,xmj?)T
4) 相关系数
样本
x
i
x_i
xi?与样本
x
j
x_j
xj?之间的相关系数定义为:
r
i
j
=
∑
k
=
1
m
(
x
k
i
?
x
 ̄
i
)
(
x
k
j
?
x
 ̄
j
)
[
∑
k
=
1
m
(
x
k
i
?
x
 ̄
i
)
2
∑
k
=
1
m
(
x
k
j
?
x
 ̄
j
)
2
]
1
2
x
 ̄
i
=
1
m
∑
k
=
1
m
x
k
i
,
x
 ̄
j
=
1
m
∑
k
=
1
m
x
k
j
r_{ij}=\frac{\sum_{k=1}^m(x_{ki}-\overline{x}_i)(x_{kj}-\overline{x}_j)}{[\sum_{k=1}^m(x_{ki}-\overline{x}_i)^2\sum_{k=1}^m(x_{kj}-\overline{x}_j)^2]^{\frac{1}{2}}} \\ \overline{x}_i=\frac{1}{m}\sum_{k=1}^mx_{ki},\overline{x}_j=\frac{1}{m}\sum_{k=1}^mx_{kj}
rij?=[∑k=1m?(xki??xi?)2∑k=1m?(xkj??xj?)2]21?∑k=1m?(xki??xi?)(xkj??xj?)?xi?=m1?k=1∑m?xki?,xj?=m1?k=1∑m?xkj?
5) 夹角余弦
s
i
j
=
∑
k
=
1
m
x
k
i
x
k
j
[
∑
k
=
1
m
x
k
i
2
∑
k
=
1
m
x
k
j
2
]
1
2
s_{ij}=\frac{\sum_{k=1}^mx_{ki}x_{kj}}{[\sum_{k=1}^mx_{ki}^2\sum_{k=1}^mx_{kj}^2]^\frac{1}{2}}
sij?=[∑k=1m?xki2?∑k=1m?xkj2?]21?∑k=1m?xki?xkj??
参考资料
https://zhuanlan.zhihu.com/p/100557559
8.4 原型聚类(划分式聚类)
8.4.1 K均值(k-means)
1) 概念
K-means是基于损失函数最小化的思想的,给定样本集
D
=
{
x
1
,
x
2
,
…
,
x
m
}
D=\{x_1,x_2,\dots,x_m\}
D={x1?,x2?,…,xm?},聚类划分后簇为
C
=
{
c
1
,
c
2
,
…
,
c
k
}
C=\{c_1,c_2,\dots,c_k\}
C={c1?,c2?,…,ck?},K-means的损失函数定义为:
E
=
∑
i
=
1
k
∑
x
∈
C
i
∣
∣
x
?
μ
i
∣
∣
2
μ
i
=
1
∣
C
i
∣
∑
x
∈
C
i
x
E=\sum_{i=1}^k\sum_{x\in C_i}||x-\mu_i||^2 \\ \mu_i=\frac{1}{|C_i|}\sum_{x\in C_i}x
E=i=1∑k?x∈Ci?∑?∣∣x?μi?∣∣2μi?=∣Ci?∣1?x∈Ci?∑?x
μ
i
\mu_i
μi? 是簇
C
i
C_i
Ci?的均值向量
既然要最小化这个东西,那么只要把各个样本归到离自己最近的那个类别就是啦。
说人话就是
样本之间的欧氏距离为
d
i
j
=
∑
k
=
1
m
(
x
k
i
?
x
k
j
)
2
=
∣
∣
x
i
?
x
j
∣
∣
2
d_{ij}=\sum_{k=1}^m(x_{ki}-x_{kj})^2=||x_i-x_j||^2
dij?=∑k=1m?(xki??xkj?)2=∣∣xi??xj?∣∣2
损失函数为样本与所属类中心之间距离的总和:
W
(
C
)
=
∑
l
=
1
k
∑
C
(
i
)
=
l
∣
∣
x
i
?
x
 ̄
l
∣
∣
2
W(C)=\sum_{l=1}^k\sum_{C(i)=l}||x_i-\overline{x}_l||^2
W(C)=∑l=1k?∑C(i)=l?∣∣xi??xl?∣∣2
x
 ̄
l
=
{
x
 ̄
1
l
,
x
 ̄
2
l
,
…
,
x
 ̄
m
l
}
\overline{x}_l=\{\overline{x}_{1l},\overline{x}_{2l},\dots,\overline{x}_{ml}\}
xl?={x1l?,x2l?,…,xml?}为第I类的均值或者中心,
W
(
C
)
W(C)
W(C)称为能量函数
k均值聚类就是求解最优化问题:
C
?
=
a
r
g
m
i
n
W
(
C
)
=
a
r
g
m
i
n
C
∑
l
=
1
k
∑
C
(
i
)
=
l
∣
∣
x
i
?
x
 ̄
l
∣
∣
2
C^*=argminW(C)=argmin_{C}\sum_{l=1}^k\sum_{C(i)=l}||x_i-\overline{x}_l||^2
C?=argminW(C)=argminC?∑l=1k?∑C(i)=l?∣∣xi??xl?∣∣2
2) 算法推导

输入:
n
n
n个样本的集合
X
X
X
输出:样本集合的聚类
C
?
C^*
C?
-
初始化,令
t
=
0
t=0
t=0,随机选择
k
k
k个样本点作为初始聚类中心
m
(
0
)
=
(
m
1
(
0
)
,
…
,
m
l
(
0
)
,
…
,
m
k
(
0
)
)
m^{(0)}=(m_1^{(0)},\dots,m_l^{(0)},\dots,m_k^{(0)})
m(0)=(m1(0)?,…,ml(0)?,…,mk(0)?) -
对样本进行聚类,对固定的类中心
m
(
t
)
=
(
m
1
(
t
)
,
…
,
m
l
(
t
)
,
…
,
m
k
(
t
)
)
m^{(t)}=(m_1^{(t)},\dots,m_l^{(t)},\dots,m_k^{(t)})
m(t)=(m1(t)?,…,ml(t)?,…,mk(t)?),其中
m
k
(
t
)
m_k^{(t)}
mk(t)?为类
C
l
C_l
Cl?的中心, 计算每个样本到类中心的距离,将每个样本指派到与其最近的中心的类中,构成聚类结果
C
(
t
)
C^(t)
C(t) -
计算新的类中心,对聚类结果
C
(
t
)
C^{(t)}
C(t),计算当前各个类中的样本的均值,作为新的类中心
m
(
t
+
1
)
=
(
m
1
(
t
+
1
)
,
…
,
m
l
(
t
+
1
)
,
…
,
m
k
(
t
+
1
)
)
m^{(t+1)}=(m_1^{(t+1)},\dots,m_l^{(t+1)},\dots,m_k^{(t+1)})
m(t+1)=(m1(t+1)?,…,ml(t+1)?,…,mk(t+1)?) -
如果迭代收敛或符合停止条件,输出
C
?
=
C
(
t
)
C^*=C^{(t)}
C?=C(t),后者令
t
=
t
+
1
t=t+1
t=t+1
算法复杂度
O
(
m
n
k
)
O(mnk)
O(mnk),其中m为样本维数,n为样本个数,k为类别个数
3) 例子
迭代过程

import re
import random
import scipy.io as sio
import numpy as np
import matplotlib.pyplot as plt
from time import *
from sklearn.datasets import make_blobs
def find_closet_centroids(X, centroids):
"""
对样本进行分类
"""
result = []
for x in X:
distance = np.sum((x - centroids) ** 2, axis=1)
result.append(np.argmin(np.sqrt(distance)))
return np.array(result)
def compute_centroids(X, idx):
"""
计算新的簇中心
"""
K = int(np.max(idx)) + 1
m = X.shape[0]
n = X.shape[-1]
centroids = np.zeros((K, n))
counts = np.zeros((K,n))
for i in range(m):
centroids[int(idx[i])] += X[i]
counts[int(idx[i])] += 1
centroids = centroids / counts
return centroids
def cost(X, idx, centrodis):
"""
计算损失函数
:param X:
:param idx:
:param centrodis:
:return:
"""
c = 0
for i in range(len(X)):
c += np.sum((X[i] - centrodis[int(idx[i])]) ** 2)
c /= len(X)
return c
def random_initialization(X, K):
"""
随机选择K组数据,作为簇中心
:param X: ndarray,所有点
:param K: int,聚类的类数
:return: ndarray,簇中心
"""
res = np.zeros((1, X.shape[-1]))
m = X.shape[0]
rl = []
while True:
index = random.randint(0, m)
if index not in rl:
rl.append(index)
if len(rl) >= K:
break
for index in rl:
res = np.concatenate((res, X[index].reshape(1, -1)), axis=0)
return res[1:]
def k_means(X, K):
"""
k-means聚类算法,
:param X: ndarray,所有的数据
:param K: int,分成聚类的类数
:return: tuple,(idx, centroids_all)
idx,ndarray 为每个数据所属类标签
centroids_all,[ndarray,...]计算过程中每轮的簇中心
"""
centroids = random_initialization(X, K)
centroids_all = [centroids]
idx = np.zeros((1,))
last_c = -1
now_c = -2
while now_c != last_c:
idx = find_closet_centroids(X, centroids)
last_c = now_c
now_c = cost(X, idx, centroids)
centroids = compute_centroids(X, idx)
centroids_all.append(centroids)
return idx, centroids_all
def visualizing(X, idx, centroids_all):
"""
可视化聚类结果和簇中心的移动过程
:param X: ndarray,所有的数据
:param idx: ndarray,每个数据所属类标签
:param centroids_all: [ndarray,...]计算过程中每轮的簇中心
:return: None
"""
plt.scatter(X[..., 0], X[..., 1], c=idx)
xx = []
yy = []
for c in centroids_all:
xx.append(c[..., 0])
yy.append(c[..., 1])
plt.plot(xx, yy, 'rx--')
plt.show()
if __name__ == '__main__':
begin_time = time()
print("========程序开始============")
X, y = make_blobs(centers=5, random_state=20, cluster_std=1)
idx, centroids_all = k_means(X, 5)
visualizing(X, idx, centroids_all)
end_time = time()
run_time = end_time - begin_time
print("========程序结束============")
print('该循环程序运行时间:', run_time)

4) 优缺点
优点:
原理比较简单,实现也是很容易,收敛速度快;聚类效果较优;算法的可解释度比较强;主要需要调参的参数仅仅是簇数k。
缺点:
1、聚类中心的个数K需要事先给定,这个K值的选定是非常难以估计的。很多时候,事先并不知道给定的数据集应该分成多少个类别才最合适;一般通过交叉验证确定;
2、不同的初始聚类中心可能导致完全不同的聚类结果。算法速度依赖于初始化的好坏,初始质点距离不能太近;
3、如果各隐含类别的数据不平衡,比如各隐含类别的数据量严重失衡,或者各隐含类别的方差不同,则聚类效果不佳;
4、该方法不适于发现非凸面形状的簇或大小差别很大的簇,对于不是凸的数据集比较难收敛;
5、对噪音和异常点比较的敏感。
6、需样本存在均值(限定数据种类)。
7、采用迭代方法,得到的结果只是局部最优。
8.4.2 LVQ
8.4.3 高斯混合聚类GMM
1) 介绍
高斯混合模型(GMM)可以看做是k-means模型的一个优化。它既是一种工业界常用的技术手段,也是一种生成式模型。
高斯混合模型试图找到多维高斯模型概率分布的混合表示,从而拟合出任意形状的数据分布。在最简单的场景中,GMM可以用与k-means相同的方式进行聚类。
只是将高斯分布、贝叶斯公式、极大似然法和聚类的思路混合在这一种方法中,容易被绕来绕去感到云里雾里的。
2) 数学准备
a) 高斯分布
首先是高斯分布的概念。高斯分布即正态分布。一般我们最常见最熟知的一元正态分布的标准形式和曲线是这样的:
f
(
x
)
=
1
2
π
σ
e
?
(
x
?
μ
)
2
2
σ
2
f(x)=\frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{(x-\mu)^2}{2\sigma^2}}
f(x)=2π
?σ1?e?2σ2(x?μ)2?

正态分布可以记为
N
(
μ
,
σ
2
)
N(\mu,\sigma^2)
N(μ,σ2),从上面的公式很明显可以看出一元正态分布只有两个参数
μ
\mu
μ和
σ
\sigma
σ,且这两个参数决定了正态曲线的“宽窄”、“高矮”。 曲线下面积为1。
b) 多元高斯分布
资料参考
https://www.cnblogs.com/bingjianing/p/9117330.html
https://www.zhihu.com/question/36339816
先假设n个变量
x
=
[
x
1
,
x
2
,
…
,
x
n
]
T
x=[x_1,x_2,\dots,x_n]^T
x=[x1?,x2?,…,xn?]T,且服从正态分布(维度不相关多元正态分布),
各个维度的均值
E
(
x
)
=
[
μ
1
,
μ
2
,
…
,
μ
n
]
T
E(x)=[\mu_1,\mu_2,\dots,\mu_n]^T
E(x)=[μ1?,μ2?,…,μn?]T,
方差
σ
(
x
)
=
[
σ
1
,
σ
2
,
…
,
σ
n
]
T
\sigma(x)=[\sigma_1,\sigma_2,\dots,\sigma_n]^T
σ(x)=[σ1?,σ2?,…,σn?]T
根据联合概率密度公式:
f
(
x
)
=
p
(
x
1
,
x
2
,
…
,
x
n
)
=
p
(
x
1
)
p
(
x
2
)
…
p
(
x
n
)
=
1
(
2
π
)
n
σ
1
σ
2
…
σ
n
e
?
(
x
1
?
μ
1
)
2
2
σ
1
2
?
(
x
2
?
μ
2
)
2
2
σ
2
2
?
?
(
x
n
?
μ
n
)
2
2
σ
n
2
f(x)=p(x_1,x_2,\dots,x_n)=p(x_1)p(x_2)\dots p(x_n) \\ =\frac{1}{(\sqrt{2\pi})^n\sigma_1\sigma_2\dots\sigma_n}e^{-\frac{(x_1-\mu_1)^2}{2\sigma_1^2}-\frac{(x_2-\mu_2)^2}{2\sigma_2^2}\dots-\frac{(x_n-\mu_n)^2}{2\sigma_n^2}}
f(x)=p(x1?,x2?,…,xn?)=p(x1?)p(x2?)…p(xn?)=(2π
?)nσ1?σ2?…σn?1?e?2σ12?(x1??μ1?)2??2σ22?(x2??μ2?)2???2σn2?(xn??μn?)2?
令
z
2
=
?
(
x
1
?
μ
1
)
2
2
σ
1
2
?
(
x
2
?
μ
2
)
2
2
σ
2
2
?
?
(
x
n
?
μ
n
)
2
2
σ
n
2
,
σ
z
=
σ
1
σ
2
…
σ
n
令z^2=-\frac{(x_1-\mu_1)^2}{2\sigma_1^2}-\frac{(x_2-\mu_2)^2}{2\sigma_2^2}\dots-\frac{(x_n-\mu_n)^2}{2\sigma_n^2},\sigma_z=\sigma_1\sigma_2\dots\sigma_n
令z2=?2σ12?(x1??μ1?)2??2σ22?(x2??μ2?)2???2σn2?(xn??μn?)2?,σz?=σ1?σ2?…σn?
这样多元正态分布又可以写成一元那种漂亮的形式了(注意一元与多元的差别):
f
(
z
)
=
1
(
2
π
)
n
σ
n
e
?
z
2
2
f(z)=\frac{1}{(\sqrt{2\pi})^n\sigma_n}e^{-\frac{z^2}{2}}
f(z)=(2π
?)nσn?1?e?2z2? 因为多元正态分布有着很强的几何思想,单纯从代数的角度看待z很难看出z的概率分布规律,这里需要转换成矩阵形式:
z
2
=
z
T
z
=
[
x
1
?
μ
1
,
x
2
?
μ
2
,
…
,
x
n
?
μ
n
]
[
1
σ
1
2
0
…
0
0
1
σ
2
2
…
0
?
…
…
?
0
0
…
1
σ
n
2
]
[
x
1
?
μ
1
,
x
2
?
μ
2
,
…
,
x
n
?
μ
n
]
T
z^2=z^Tz=[x_1-\mu_1,x_2-\mu_2,\dots,x_n-\mu_n] \begin{bmatrix} \frac{1}{\sigma_1^2}&0&\dots&0 \\ 0&\frac{1}{\sigma_2^2}&\dots&0 \\ \vdots&\dots&\dots&\vdots \\ 0&0&\dots&\frac{1}{\sigma_n^2} \end{bmatrix} [x_1-\mu_1,x_2-\mu_2,\dots,x_n-\mu_n]^T
z2=zTz=[x1??μ1?,x2??μ2?,…,xn??μn?]???????σ12?1?0?0?0σ22?1?…0?…………?00?σn2?1?????????[x1??μ1?,x2??μ2?,…,xn??μn?]T 等式比较长,让我们要做一下变量替换:
x
?
μ
x
=
[
x
1
?
μ
1
,
x
2
?
μ
2
,
…
,
x
n
?
μ
n
]
T
x-\mu_x=[x_1-\mu_1,x_2-\mu_2,\dots,x_n-\mu_n]^T
x?μx?=[x1??μ1?,x2??μ2?,…,xn??μn?]T
定义一个符号
∑
=
[
σ
1
2
0
…
0
0
σ
2
2
…
0
?
…
…
?
0
0
…
σ
n
2
]
\sum=\begin{bmatrix}\sigma_1^2&0&\dots&0\\ 0&\sigma_2^2&\dots&0\\ \vdots&\dots&\dots&\vdots\\ 0&0&\dots&\sigma_n^2\end{bmatrix}
∑=??????σ12?0?0?0σ22?…0?…………?00?σn2????????
∑
\sum
∑代表变量
X
X
X的协方差矩阵, i行j列的元素值表示
x
i
与
x
j
x_i与x_j
xi?与xj?的协方差
因为现在变量之间是相互独立的,所以只有对角线上
(
i
=
j
)
(i = j)
(i=j)存在元素,其他地方都等于0,且
x
i
x_i
xi?与它本身的协方差就等于方差
∑
\sum
∑是一个对角阵,根据对角矩阵的性质,它的逆矩阵:
(
∑
)
?
1
=
[
1
σ
1
2
0
…
0
0
1
σ
2
2
…
0
?
…
…
?
0
0
…
1
σ
n
2
]
(\sum)^{-1}=\begin{bmatrix} \frac{1}{\sigma_1^2}&0&\dots&0 \\ 0&\frac{1}{\sigma_2^2}&\dots&0 \\ \vdots&\dots&\dots&\vdots \\ 0&0&\dots&\frac{1}{\sigma_n^2} \end{bmatrix}
(∑)?1=???????σ12?1?0?0?0σ22?1?…0?…………?00?σn2?1????????? 对角矩阵的行列式 = 对角元素的乘积
σ
z
=
∣
∑
∣
1
2
=
σ
1
σ
2
…
σ
n
\sigma_z=|\sum|^{\frac{1}{2}}=\sigma_1\sigma_2\dots\sigma_n
σz?=∣∑∣21?=σ1?σ2?…σn?
替换变量之后,等式可以简化为:
z
T
z
=
(
x
?
μ
x
)
T
∑
1
2
(
x
?
μ
x
)
z^Tz=(x-\mu_x)^T\sum^{\frac{1}{2}}(x-\mu_x)
zTz=(x?μx?)T∑21?(x?μx?)
代入以z为自变量的标准高斯分布函数中:
一般的多元高斯具有形式:
f
(
z
)
=
1
(
2
π
)
n
σ
n
e
?
z
2
2
f
(
x
)
=
1
(
2
π
)
n
∣
∑
∣
1
2
e
?
(
x
?
μ
x
)
T
(
∑
)
?
1
(
x
?
μ
x
)
2
f(z)=\frac{1}{(\sqrt{2\pi})^n\sigma_n}e^{-\frac{z^2}{2}} \\ f(x)=\frac{1}{(\sqrt{2\pi})^n|\sum|^{\frac{1}{2}}}e^{-\frac{(x-\mu_x)^T(\sum)^{-1}(x-\mu_x)}{2}}
f(z)=(2π
?)nσn?1?e?2z2?f(x)=(2π
?)n∣∑∣21?1?e?2(x?μx?)T(∑)?1(x?μx?)?
注意前面的系数变化:从非标准正态分布->标准正态分布需要将概率密度函数的高度压缩
∣
∑
∣
1
2
|\sum|^{\frac{1}{2}}
∣∑∣21?倍, 从一维 -> n维的过程中,每增加一维,高度将压缩
2
π
\sqrt{2\pi}
2π
?倍
二元高斯曲线如下图。曲线下面积为1。它多了一个变量。例如x轴是身高,y轴是体重,有了身高体重的数据就可以在z轴找到该身高体重在人群中所占的比例(即概率)。同样地,中等身高且中等体重的人在人群中是最常见的,正如路上普普通通的路人。

c) 贝叶斯公式
P
(
A
i
∣
B
)
=
P
(
A
i
)
P
(
B
∣
A
i
)
∑
j
=
1
n
P
(
A
j
)
P
(
B
∣
A
j
)
P(A_i|B)=\frac{P(A_i)P(B|A_i)}{\sum_{j=1}^nP(A_j)P(B|A_j)}
P(Ai?∣B)=∑j=1n?P(Aj?)P(B∣Aj?)P(Ai?)P(B∣Ai?)?
d) 极大似然
2) 算法推导

n维样本的高斯分布为:
p
(
x
)
=
1
(
2
π
)
n
∣
∑
∣
1
2
e
?
(
x
?
μ
x
)
T
(
∑
)
?
1
(
x
?
μ
x
)
2
p(x)=\frac{1}{(\sqrt{2\pi})^n|\sum|^{\frac{1}{2}}}e^{-\frac{(x-\mu_x)^T(\sum)^{-1}(x-\mu_x)}{2}}
p(x)=(2π
?)n∣∑∣21?1?e?2(x?μx?)T(∑)?1(x?μx?)?
由贝叶斯定理,样本
x
j
x_j
xj?属于
i
i
i类的后验概率为:
KaTeX parse error: No such environment: align at position 8: \begin{?a?l?i?g?n?}? p_M(z_j=i|x_j)…
将上式简写为
γ
j
i
\gamma_{ji}
γji?
则样本
x
j
x_j
xj?分类公式为
λ
j
=
a
r
g
m
a
x
i
∈
{
1
,
2
,
…
,
k
}
γ
j
i
\lambda_j=argmax_{i\in \{1,2,\dots,k\}}\gamma_{ji}
λj?=argmaxi∈{1,2,…,k}?γji?
给每一个分类一个系数,采用对数似然,得
L
L
(
D
)
=
l
n
(
∏
j
=
1
m
P
M
(
x
j
)
)
∑
j
=
1
m
l
n
(
∑
i
=
1
k
α
i
?
P
(
x
j
∣
μ
i
,
∑
i
)
)
LL(D)=ln(\prod_{j=1}^mP_M(x_j)) \\ \sum_{j=1}^mln(\sum_{i=1}^k\alpha_i\cdot P(x_j|\mu_i,\sum_i))
LL(D)=ln(j=1∏m?PM?(xj?))j=1∑m?ln(i=1∑k?αi??P(xj?∣μi?,i∑?))
上式分别对
∑
,
μ
\sum,\mu
∑,μ求导。令导数为0,得
μ
i
=
∑
j
=
1
m
γ
j
i
x
j
∑
j
=
1
m
γ
j
i
∑
i
=
∑
j
=
1
m
γ
j
i
(
x
j
?
μ
i
)
(
x
j
?
μ
i
)
T
∑
j
=
1
m
γ
j
i
\mu_i=\frac{\sum_{j=1}^m\gamma_{ji}x_j}{\sum_{j=1}^m\gamma_{ji}} \\ \sum_i=\frac{\sum_{j=1}^m\gamma_{ji}(x_j-\mu_i)(x_j-\mu_i)^T}{\sum_{j=1}^m\gamma_{ji}}
μi?=∑j=1m?γji?∑j=1m?γji?xj??i∑?=∑j=1m?γji?∑j=1m?γji?(xj??μi?)(xj??μi?)T?
系数求和为1,引入此约束,对数似然的拉格朗日形式为
α
i
=
1
m
∑
j
=
1
m
γ
j
i
\alpha_i=\frac{1}{m}\sum_{j=1}^m\gamma_{ji}
αi?=m1?∑j=1m?γji?
3) 例子
代码
import matplotlib.pyplot as plt
import seaborn as sns; sns.set()
import numpy as np
from sklearn.datasets.samples_generator import make_blobs
X, y_true = make_blobs(n_samples=700, centers=4,
cluster_std=0.5, random_state=2019)
X = X[:, ::-1]
from sklearn.mixture import GaussianMixture as GMM
gmm = GMM(n_components=4).fit(X)
labels = gmm.predict(X)
plt.scatter(X[:, 0], X[:, 1], c=labels, s=50, cmap='viridis')

它使用EM算法进行迭代:1.选择位置和初始形状2.循环直至收敛:
E步骤:对于每个点,为每个点分别计算由该混合模型内的每个分量生成的概率。
M步骤:调整模型参数以最大化模型生成这些参数的可能性。
该算法保证该过程内的参数总会收敛到一个局部最优解。
例二
参考资料
https://www.cnblogs.com/lunge-blog/p/11792226.html
数据
序号,密度,含糖量
1,0.697,0.460
2,0.774,0.376
3,0.634,0.264
4,0.608,0.318
5,0.556,0.215
6,0.403,0.237
7,0.481,0.149
8,0.437,0.211
9,0.666,0.091
10,0.243,0.267
11,0.245,0.057
12,0.343,0.099
13,0.639,0.161
14,0.657,0.198
15,0.360,0.370
16,0.593,0.042
17,0.719,0.103
18,0.359,0.188
19,0.339,0.241
20,0.282,0.257
21,0.748,0.232
22,0.714,0.346
23,0.483,0.312
24,0.478,0.437
25,0.525,0.369
26,0.751,0.489
27,0.532,0.472
28,0.473,0.376
29,0.725,0.445
30,0.446,0.459
代码
file='xigua4.txt'
x=[]
with open(file) as f:
f.readline()
lines=f.read().split('\n')
for line in lines:
data=line.split(',')
x.append([float(data[-2]),float(data[-1])])
y=np.array(x)
import numpy as np
import random
def probability(x,u,cov):
cov_inv=np.linalg.inv(cov)
cov_det=np.linalg.det(cov)
return np.exp(-1/2*((x-u).T.dot(cov_inv.dot(x-u))))/np.sqrt(cov_det)
def gauss_mixed_clustering(x,k=3,epochs=50,reload_params=None):
features_num=len(x[0])
r=np.empty(shape=(len(x),k))
if reload_params!=None:
a,u,cov=reload_params
else:
a=np.random.uniform(size=k)
a/=np.sum(a)
u=np.array(random.sample(list(x),k))
cov=np.empty(shape=(k,features_num,features_num))
for i in range(k):
for j in range(features_num):
cov[i][j]=[0]*j+[0.5]+[0]*(features_num-j-1)
step=0
while step<epochs:
for j in range(len(x)):
for i in range(k):
r[j,i]=a[i]*probability(x[j],u[i],cov[i])
r[j]/=np.sum(r[j])
for i in range(k):
r_toal=np.sum(r[:,i])
u[i]=np.sum([x[j]*r[j,i] for j in range(len(x))],axis=0)/r_toal
cov[i]=np.sum([r[j,i]*((x[j]-u[i]).reshape((features_num,1)).dot((x[j]-u[i]).reshape((1,features_num)))) for j in range(len(x))],axis=0)/r_toal
a[i]=r_toal/len(x)
step+=1
C=[]
for i in range(k):
C.append([])
for j in range(len(x)):
c_j=np.argmax(r[j,:])
C[c_j].append(x[j])
return C,a,u,cov
验证
res,A,U,COV=gauss_mixed_clustering(y)
import matplotlib.pyplot as plt
%matplotlib inline
colors=['green','blue','red','black','yellow','orange']
for i in range(len(res)):
plt.scatter([d[0] for d in res[i]],[d[1] for d in res[i]],color=colors[i],label=str(i))
plt.scatter([d[0] for d in U],[d[1] for d in U],color=colors[-1],marker='^',label='center')
plt.xlabel('density')
plt.ylabel('suger')
plt.legend()
50论过后
res,A,U,COV=gauss_mixed_clustering(y,reload_params=[A,U,COV])
for i in range(len(res)):
plt.scatter([d[0] for d in res[i]],[d[1] for d in res[i]],color=colors[i],label=str(i))
plt.scatter([d[0] for d in U],[d[1] for d in U],color=colors[-1],marker='^',label='center')
plt.xlabel('density')
plt.ylabel('suger')
plt.legend()
参考资料
https://zhuanlan.zhihu.com/p/81255623
https://blog.csdn.net/lotusng/article/details/79990724
8.5 密度聚类
8.5.1 概念
k-means 算法对于凸性数据具有良好的效果,能够根据距离来讲数据分为球状类的簇,但对于非凸形状的数据点,就无能为力了,当k-means 算法在环形数据的聚类时,我们看看会发生什么情况。

从上图可以看到,kmeans 聚类产生了错误的结果,这个时候就需要用到基于密度的聚类方法了,
DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法,类似于均值转移聚类算法,但它有几个显著的优点。

DBSCAN算法的核心思想是:用一个点的ε邻域内的邻居点数衡量该点所在空间的密度,该算法可以找出形状不规则的cluster,而且聚类的时候事先不需要给定cluster的数量。
常用的密度聚类算法:DBSCAN、MDCA、OPTICS、DENCLUE等。
密度聚类的主要特点是:
- 发现任意形状的簇
- 对噪声数据不敏感
- 一次扫描
- 需要密度参数作为停止条件
- 计算量大、复杂度高
8.5.2 相关概念
定义一个数据集
D
=
{
x
1
,
x
2
,
…
,
x
m
}
D=\{x_1,x_2,\dots,x_m\}
D={x1?,x2?,…,xm?}
-
?
\epsilon
? 表示半径 -
?
\epsilon
?领域(
?
\epsilon
? neighborhood,也称为Eps),给定对象在半径
?
\epsilon
?内的区域
N
?
(
x
)
=
{
y
∈
X
:
d
i
s
t
(
x
,
y
)
≤
?
}
N_\epsilon(x)=\{y\in X:dist(x,y)\le \epsilon\}
N??(x)={y∈X:dist(x,y)≤?} -
密度
?
\epsilon
?领域中x的密度,是一个整数值,依赖于半径
?
\epsilon
?
p
(
x
)
=
∣
N
?
(
x
)
∣
p(x)=|N_\epsilon(x)|
p(x)=∣N??(x)∣ -
MinPts ε-邻域内样本个数最小值。也简记为M -
核心对象 若
x
i
x_i
xi?的
?
\epsilon
?领域至少包含MinPts个样本,即|
N
?
(
x
i
)
∣
≥
M
i
n
P
t
s
N_\epsilon(x_i)|\ge MinPts
N??(xi?)∣≥MinPts,则
x
i
x_i
xi?是一个核心对象 -
密度直达 若
x
j
x_j
xj?位于
x
i
x_i
xi?的
?
\epsilon
?领域中,且
x
i
x_i
xi?是核心对象,则称
x
j
x_j
xj?和
x
i
x_i
xi?是密度直达 -
密度可达(density-reachable) 如果存在一个对象链
p
1
,
p
2
,
.
.
p
m
p_1,p_2,..p_m
p1?,p2?,..pm?,其中
p
1
=
x
i
,
p
n
=
x
j
,
p_1=x_i,p_n=x_j,
p1?=xi?,pn?=xj?,且
p
i
+
1
p_{i+1}
pi+1?由
p
i
p_i
pi?密度直达,那么称
x
j
x_j
xj?是从
x
i
x_i
xi?密度可达的。 -
密度相连(density-connected) 在集合X中,如果存在一个对象o,使得对象x和y是从o关于ε和m密度可达的,那么对象x和y是关于ε和m密度相连的。
可以发现,密度可达是直接密度可达的传递闭包,并且这种关系是非对称的。密度相连是对称关系。DBSCAN目的是找到密度相连对象的最大集合。
从下图可以很容易看出理解上述定义,图中MinPts=5,红色的点都是核心对象,因为其?-邻域至少有5个样本。黑色的样本是非核心对象。所有核心对象密度直达的样本在以红色核心对象为中心的超球体内,如果不在超球体内,则不能密度直达。图中用绿色箭头连起来的核心对象组成了密度可达的样本序列。在这些密度可达的样本序列的?-邻域内所有的样本相互都是密度相连的。

8.5.3 DBSCAN算法推导
1、如果一个点x的ε邻域包含多余m个对象,则创建一个x作为核心对象的新簇; 2、寻找并合并核心对象直接密度可达的对象; 3、没有新点可以更新簇的时候,算法结束。

输入:样本集
D
=
{
x
1
,
x
2
,
…
,
x
m
}
D=\{x_1,x_2,\dots,x_m\}
D={x1?,x2?,…,xm?},领域参数
(
?
,
M
i
n
P
t
s
)
(\epsilon,MinPts)
(?,MinPts),样本距离度量方式
输出:簇划分
-
初始化核心对象集合
Ω
=
?
\Omega=\phi
Ω=?,初始化聚类簇k=0,初始化为访问样本集合
F
F
F.簇划分
C
=
?
C=\phi
C=? -
对于j=1,2,…,m,按照下面的步骤找出所有的核心对象
a) 通过距离度量的方式没找到样本
x
j
x_j
xj?的
?
\epsilon
?领域子样本集
N
?
(
x
j
)
N_\epsilon(x_j)
N??(xj?)
b) 如果子样本集样本个数满足
∣
N
?
(
x
j
)
∣
≥
M
i
n
P
t
s
|N_\epsilon(x_j)|\ge MinPts
∣N??(xj?)∣≥MinPts,将样本
x
j
x_j
xj?加入核心对象样本集合
Ω
=
Ω
?
{
x
j
}
\Omega=\Omega \bigcup\{x_j\}
Ω=Ω?{xj?}
-
如果核心对象集合
Ω
=
?
\Omega=\phi
Ω=?,则算法结束,否则转入步骤4 -
在核心对象集合Ω中,随机选择一个核心对象o,初始化当前簇核心对象队列
Ω
c
u
r
r
e
n
t
=
{
o
}
\Omega_{current}=\{o\}
Ωcurrent?={o},初始化类别序号k=k+1,初始化当前簇样本集合
C
k
=
{
o
}
C_k=\{o\}
Ck?={o},更新未访问核心对象为未访问集合
F
=
F
?
{
o
}
F=F-\{o\}
F=F?{o}。 -
如果当前簇核心对象队列
Ω
c
u
r
r
e
n
t
=
?
\Omega_{current}=\phi
Ωcurrent?=?,则当前聚类簇
C
k
C_k
Ck?生成完毕,更新簇划分
C
=
{
C
1
,
C
2
,
.
.
C
k
}
C=\{C_1,C_2,..C_k\}
C={C1?,C2?,..Ck?},更新核心对象集合
Ω
=
Ω
?
C
k
\Omega=\Omega-C_k
Ω=Ω?Ck?,转入步骤3,否则更新核心对象集合
Ω
=
Ω
?
C
k
\Omega=\Omega-C_k
Ω=Ω?Ck?。 -
在当前簇核心对象队列
Ω
c
u
r
r
e
n
t
\Omega_{current}
Ωcurrent?中取出一个核心对象
o
′
o^\prime
o′。通过领域距离阈值
?
领
域
\epsilon领域
?领域子样本集
N
?
(
o
′
)
N_\epsilon(o^\prime)
N??(o′),令
Δ
=
N
?
(
o
′
)
?
F
\Delta=N_\epsilon(o^\prime)\bigcap F
Δ=N??(o′)?F,更新当前簇集合
C
k
=
C
k
?
Δ
C_k=C_k\bigcup \Delta
Ck?=Ck??Δ,更新为访问样本集合
F
=
F
?
Δ
F=F-\Delta
F=F?Δ,更新
Ω
c
u
r
r
e
n
t
=
Ω
c
u
r
r
e
n
t
?
(
Δ
?
Ω
)
?
o
′
\Omega_{current}=\Omega_{current}\bigcup (\Delta\bigcap \Omega)-o^\prime
Ωcurrent?=Ωcurrent??(Δ?Ω)?o′,转入步骤5
输出结果,簇划分
C
=
{
C
1
,
C
2
,
.
.
.
,
C
k
}
C=\{C_1,C_2,...,C_k\}
C={C1?,C2?,...,Ck?}
算法特征描述: 1、每个簇至少包含一个核心对象。 2、非核心对象可以是簇的一部分,构成簇的边缘。 3、包含过少对象的簇被认为是噪声。
8.5.4 代码
import re
import random
from sklearn.cluster import DBSCAN
import scipy.io as sio
import numpy as np
import matplotlib.pyplot as plt
from time import *
from sklearn.datasets import make_blobs
from sklearn import datasets
def dbscan(data_set, eps, min_pts):
"""
data_set 数据集,[n,2]
eps 邻域大小范围
min_pts 一个邻域至少包含多少个样本
"""
examples_nus = np.shape(data_set)[0]
unvisited = [i for i in range(examples_nus)]
visited = []
cluster = [-1 for i in range(examples_nus)]
k = - 1
while len(unvisited) > 0:
p = random.choice(unvisited)
unvisited.remove(p)
visited.append(p)
nighbor = []
for i in range(examples_nus):
if i != p and np.sqrt(np.sum(np.power(data_set[i, :] - data_set[p, :], 2))) <= eps:
nighbor.append(i)
if len(nighbor) >= min_pts:
k = k + 1
cluster[p] = k
for pi in nighbor:
if pi in unvisited:
unvisited.remove(pi)
visited.append(pi)
nighbor_pi = []
for j in range(examples_nus):
if np.sqrt(np.sum(np.power(data_set[j] - data_set[pi], 2))) <= eps and j != pi:
nighbor_pi.append(j)
if len(nighbor_pi) >= min_pts:
for t in nighbor_pi:
if t not in nighbor:
nighbor.append(t)
if cluster[pi] == -1:
cluster[pi] = k
else:
cluster[p] = -1
return np.array(cluster)
if __name__ == '__main__':
X, Y1 = datasets.make_circles(n_samples=1000, factor=.4, noise=.07)
print(X)
eps = 0.1
min_pts = 2
cluster = dbscan(X, eps, min_pts)
print(cluster.shape)
print(np.unique(cluster))
plt.figure()
plt.scatter(X[:, 0], X[:, 1], c=cluster)
plt.show()
plt.figure()
y_pred = DBSCAN(eps=0.1).fit_predict(X)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()
结果如下

想要换个模型
X, Y1 = datasets.make_moons(n_samples=200, noise=None, shuffle=True, random_state=None)

可以自己玩
datasets.make_biclusters()
datasets.make_blobs()
datasets.make_checkerboard()
datasets.make_circles()
datasets.make_classification()
datasets.make_friedman1()
datasets.make_friedman2()
datasets.make_friedman3()
datasets.make_gaussian_quantiles()
datasets.make_hastie_10_2()
datasets.make_low_rank_matrix()
datasets.make_moons()
datasets.make_multilabel_classification()
datasets.make_regression()
datasets.make_s_curve()
datasets.make_sparse_coded_signal()
datasets.make_sparse_spd_matrix()
datasets.make_sparse_uncorrelated()
datasets.make_spd_matrix()
datasets.make_swiss_roll()
8.5.5 优缺点
**优点:**不需要确定要划分的聚类个数,聚类结果没有偏倚;抗噪声,在聚类的同时发现异常点,对数据集中的异常点不敏感;处理任意形状和大小的簇,相对的,K-Means之类的聚类算法一般只适用于凸数据集。
**缺点:**数据量大时内存消耗大,相比K-Means参数多一些;样本集的密度不均匀、聚类间距差相差很大时,聚类质量较差,这时用DBSCAN聚类一般不适合;
参考资料
https://www.jianshu.com/p/5e5bcf3ec9d6
(3条消息) python实现DBSCAN聚类_啃西瓜的小煤球的博客-CSDN博客_dbscan聚类python实现
8.6 层次聚类
8.6.1 概念
层次聚类(Hierarchical Clustering)是聚类算法的一种,通过计算不同类别数据点间的相似度来创建一棵有层次的嵌套聚类树。在聚类树中,不同类别的原始数据点是树的最低层,树的顶层是一个聚类的根节点。创建聚类树有自下而上合并和自上而下分裂两种方法,本篇文章介绍合并方法

源数据:

层次聚类:


1.凝聚层次聚类:AGNES算法(自底向上)
首先将每个对象作为一个簇,然后合并这些原子簇为越来越大的簇,直到某个终结条件被满足
2.分裂层次聚类:DIANA算法(自顶向下)
首先将所有对象置于一个簇中,然后逐渐细分为越来越小的簇,直到达到了某个终结条件。
8.6.2 数学准备
给定聚类簇
C
i
C_i
Ci?和
C
j
C_j
Cj?,两个簇的距离可以通过以下定义得到
最短距离:
d
m
i
n
(
C
i
,
C
j
)
=
m
i
n
p
∈
C
i
,
q
∈
C
j
∣
p
?
q
∣
d_{min}(C_i,C_j)=min_{p\in C_i,q\in C_j}|p-q|
dmin?(Ci?,Cj?)=minp∈Ci?,q∈Cj??∣p?q∣
最大距离
d
m
a
x
(
C
i
,
C
j
)
=
m
a
x
p
∈
i
,
q
∈
C
j
∣
p
?
q
∣
d_{max}(C_i,C_j)=max_{p\in _i,q\in C_j}|p-q|
dmax?(Ci?,Cj?)=maxp∈i?,q∈Cj??∣p?q∣
均值距离
d
m
e
a
n
(
C
i
,
C
j
)
=
∣
p
 ̄
?
q
 ̄
∣
,
其
中
p
 ̄
=
1
∣
C
i
∣
∑
p
∈
C
i
p
,
q
 ̄
=
∑
q
∈
C
j
q
d_{mean}(C_i,C_j)=|\overline{p}-\overline{q}|,其中\overline{p}=\frac{1}{|C_i|}\sum_{p\in C_i}p,\overline{q}=\sum_{q\in C_j}q
dmean?(Ci?,Cj?)=∣p??q?∣,其中p?=∣Ci?∣1?∑p∈Ci??p,q?=∑q∈Cj??q
平均距离
d
a
v
g
(
C
i
,
C
j
)
=
1
∣
C
i
∣
∣
C
j
∣
∑
p
∈
C
i
∑
q
∈
C
j
∣
p
?
q
∣
d_{avg}(C_i,C_j)=\frac{1}{|C_i||C_j|}\sum_{p\in C_i}\sum_{q\in C_j}|p-q|
davg?(Ci?,Cj?)=∣Ci?∣∣Cj?∣1?∑p∈Ci??∑q∈Cj??∣p?q∣

显然最小距离是由两个簇的最近样本决定、最大距离由两个簇的最远样本决定、均值距离由两个簇的中心位置决定、而平均距离则由两个簇的所有样本共同决定。当聚类距离由
d
m
i
n
,
d
m
a
x
,
d
a
v
g
d_{min},d_{max},d_{avg}
dmin?,dmax?,davg?计算时。AGNES算法被相应地称为“单链接”、“全链接”或“均链接”算法。
8.6.3 算法推导
AGNES(自底向上凝聚算法)算法的具体步骤如下所示: 输入:包含n个对象的数据库。 输出:满足终止条件的若干个簇。 (1) 将每个对象当成一个初始簇; (2) REPEAT(重复) (3) 计算任意两个簇的距离,并找到最近的两个簇; (4) 合并两个簇,生成新的簇的集合; (5) UNTIL 终止条件得到满足。

8.6.4 例子
使用AGNES算法对下面的数据集进行聚类,以最小距离计算簇间的距离。刚开始共有5个簇:
C
1
=
{
A
}
,
C
2
=
{
B
}
,
C
3
=
{
C
}
,
C
4
=
{
D
}
,
C
5
=
{
E
}
C_1=\{A\},C_2=\{B\},C_3=\{C\},C_4=\{D\},C_5=\{E\}
C1?={A},C2?={B},C3?={C},C4?={D},C5?={E}
样本点 | A | B | C | D | E |
---|
A | 0 | 0.4 | 2 | 2.5 | 3 | B | 0.4 | 0 | 1.6 | 2.1 | 1.9 | C | 2 | 1.6 | 0 | 0.6 | 0.8 | D | 2.5 | 2.1 | 0.6 | 0 | 1 | E | 3 | 1.9 | 0.8 | 1 | 0 |
step1.簇
C
1
C_1
C1?和簇
C
2
C_2
C2?的距离最近,将二者合并,得到新的簇结构:
C
1
=
{
A
,
B
}
,
C
2
=
{
C
}
,
C
3
=
{
D
}
C_1=\{A,B\},C_2=\{C\},C_3=\{D\}
C1?={A,B},C2?={C},C3?={D}和
C
4
=
{
E
}
C_4=\{E\}
C4?={E}
样本点 | AB | C | D | E |
---|
AB | 0 | 1.6 | 2.1 | 1.9 | C | 1.6 | 0 | 0.6 | 0.8 | D | 2.1 | 0.6 | 0 | 1 | E | 1.9 | 0.8 | 1 | 0 |
Step2. 接下来簇
C
2
C_2
C2?和簇
C
3
C_3
C3?的距离最近,将二者合并,得到新的簇结构:
C
1
=
{
A
,
B
}
,
C
2
=
{
C
,
D
}
C_1=\{A,B\},C_2=\{C,D\}
C1?={A,B},C2?={C,D}和
C
3
=
{
E
}
C_3=\{E\}
C3?={E}
样本点 | AB | CD | E |
---|
AB | 0 | 1.6 | 1.9 | CD | 1.6 | 0 | 0.8 | E | 1.9 | 0.8 | 0 |
Step3. 接下来簇
C
2
C_2
C2?和簇
C
3
C_3
C3?的距离最近,将二者合并,得到新的簇结构:
C
1
=
{
A
,
B
}
C_1=\{A,B\}
C1?={A,B}和
C
2
=
{
C
,
D
,
E
}
C_2=\{C,D,E\}
C2?={C,D,E}
Step4. 最后只剩下簇
C
1
C_1
C1?和簇
C
2
C_2
C2?,二者的最近距离为1.6,将二者合并,得到新的簇结构:
C
1
=
{
A
,
B
,
C
,
D
,
E
}
C_1=\{A,B,C,D,E\}
C1?={A,B,C,D,E}

层次聚类方法的终止条件:
- 设定一个最小距离阈值
d
 ̄
\overline{d}
d,如果最相近的两个簇的距离已经超过
d
 ̄
\overline{d}
d,则它们不需再合并,聚类终止。
- 限定簇的个数k,当得到的簇的个数已经达到
k
 ̄
\overline{k}
k,则聚类终止。
from sklearn import datasets
from sklearn.cluster import AgglomerativeClustering
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
import pandas as pd
iris = datasets.load_iris()
irisdata = iris.data
clustering = AgglomerativeClustering(linkage='ward', n_clusters=3)
res = clustering.fit(irisdata)
print "各个簇的样本数目:"
print pd.Series(clustering.labels_).value_counts()
print "聚类结果:"
print confusion_matrix(iris.target,clustering.labels_)
plt.figure()
d0 = irisdata[clustering.labels_==0]
plt.plot(d0[:,0],d0[:,1],'r.')
d1 = irisdata[clustering.labels_==1]
plt.plot(d1[:,0],d1[:,1],'go')
d2 = irisdata[clustering.labels_==2]
plt.plot(d2[:,0],d2[:,1],'b*')
plt.xlabel("Sepal.Length")
plt.ylabel("Sepal.Width")
plt.title("AGNES Clustering")
plt.show()
参考资料
https://blog.csdn.net/jmh1996/article/details/83959465
https://zhuanlan.zhihu.com/p/100557559
https://zhuanlan.zhihu.com/p/104355127
https://blog.csdn.net/AI_BigData_wh/article/details/78073444
https://www.cnblogs.com/pinard/p/6208966.html
|