文章目录
1 概述
kmeans:可看作高斯混合聚类在混合成分方差相等,且每个样本仅指派给一个混合成分时的特例
常用聚类算法:
-
k-medoids:
-
k-modes
-
Fuzzy C-means(soft clustering)
-
kernel k-means
-
spectral clustering
-
LVQ、LVQ2、LVQ3(学习向量量化)
-
DBSCAN、OPTICS、DENCLUE、AGNES…(基于密度聚类)
-
集成聚类
-
异常检测
2 性能度量
2.1 外部指标
将聚类结果与某个参考模型进行比较
将样本两两配对考虑:
聚类C | 聚类C*(参考模型) | |
---|---|---|
a | same | same |
b | same | different |
c | different | same |
d | different | different |
常用的聚类性能度量外部指标:
- Jaccard系数(Jaccard Coefficient,JC)
J C = a a + b + c JC=\frac{a}{a+b+c} JC=a+b+ca
- FM指数
F M I = a a + b ∗ a a + c FMI=\sqrt{\frac{a}{a+b}*\frac{a}{a+c}} FMI=a+ba∗a+ca
- Rand指数(RI)
R I = 2 ( a + d ) m ( m − 1 ) RI=\frac{2(a+d)}{m(m-1)} RI=m(m−1)2(a+d)
以上三个外部指标均在[0,1]区间,且越大越好。
2.2 内部指标
聚类结果的簇划分为
{
C
1
,
C
2
,
.
.
.
,
C
k
}
\{C_1,C_2,...,C_k\}
{C1,C2,...,Ck}
定义:
a
v
g
(
C
)
=
2
∣
C
∣
(
∣
C
∣
−
1
)
∑
1
≤
i
<
j
≤
∣
C
∣
d
i
s
t
(
x
i
,
x
j
)
avg(C)=\frac{2}{|C|(|C|-1)}\sum_{1≤i<j≤|C|}dist(x_i,x_j)
avg(C)=∣C∣(∣C∣−1)21≤i<j≤∣C∣∑dist(xi,xj)
DBI越小越好,DI越大越好
除此之外,还有F值、互信息、平均廓宽等。
3 距离计算
3.1 有序属性的距离
3.1.1 闵可夫斯基距离
d i s t m k ( x i , x j ) = ( ∑ u = 1 n ∣ x i u − x j u ∣ p ) 1 p dist_{mk}(x_i,x_j)=(\sum_{u=1}^{n}|x_{iu}-x_{ju}|^p)^{\frac{1}{p}} distmk(xi,xj)=(u=1∑n∣xiu−xju∣p)p1
3.1.2 欧氏距离(L2范数)
d i s t e d ( x i , x j ) = ∣ ∣ x i − x j ∣ ∣ 2 = ( ∑ u = 1 n ∣ x i u − x j u ∣ 2 ) 1 2 dist_{ed}(x_i,x_j)=||x_i-x_j||_2=(\sum_{u=1}^{n}|x_{iu}-x_{ju}|^2)^{\frac{1}{2}} disted(xi,xj)=∣∣xi−xj∣∣2=(u=1∑n∣xiu−xju∣2)21
3.1.3 曼哈顿距离(L1范数)
d i s t m a n ( x i , x j ) = ∣ ∣ x i − x j ∣ ∣ 1 = ∑ u = 1 n ∣ x i u − x j u ∣ dist_{man}(x_i,x_j)=||x_i-x_j||_1=\sum_{u=1}^{n}|x_{iu}-x_{ju}| distman(xi,xj)=∣∣xi−xj∣∣1=u=1∑n∣xiu−xju∣
3.2 无序属性的距离
VDM距离:
V
D
M
p
(
a
,
b
)
=
∑
i
=
1
k
∣
m
u
,
a
,
i
m
u
,
a
−
m
u
,
b
,
i
m
u
,
b
∣
p
VDM_p(a,b)=\sum_{i=1}^{k}|\frac{m_{u,a,i}}{m_{u,a}}-\frac{m_{u,b,i}}{m_{u,b}}|^p
VDMp(a,b)=i=1∑k∣mu,amu,a,i−mu,bmu,b,i∣p
3.3 混合属性的距离
闵可夫斯基和VDM结合可以处理混合属性。
3.4 非度距离
现实中存在一些无法直接用相似度度量的距离,例如:
不少情况下,我们需要基于数据样本来确定合适的距离公式,可以通过“距离度量学习”来实现。
4 原型算法
4.1 kmeans算法
- 从D中随机选择k个样本作为初始均值向量
- 计算每个样本与均值向量的距离,并给每个样本做簇标记
- 计算并更新均值向量
- 重复操作2,直至均值向量基本不变或达到所需迭代次数
4.2 学习向量量化(LVQ)
4.3 高斯混合聚类
高斯混合聚类采用概率模型来表达聚类原型。
多元高斯分布的概率密度函数:
p
(
x
)
=
1
(
2
π
)
n
2
∣
∑
∣
1
2
e
−
1
2
(
x
−
μ
)
T
∑
−
1
(
x
−
μ
)
p(x)=\frac{1}{(2\pi)^{\frac{n}{2}}|\sum|^{\frac{1}{2}}}e^{-\frac{1}{2}(x-\mu)^T\sum^{-1}(x-\mu)}
p(x)=(2π)2n∣∑∣211e−21(x−μ)T∑−1(x−μ)
E:计算x_i由各个混合成分生成的后验概率
M:求新均值向量、新协方差矩阵、新混合系数,并更新μ和Σ。
继续迭代,满足条件时终止。
更新每个高斯混合成的均值mu(由加权平均估计):
μ
i
=
∑
j
=
1
m
γ
j
i
x
j
∑
j
=
1
m
γ
j
i
\mu_i=\frac{\sum_{j=1}^{m}\gamma_{ji}x_j}{\sum_{j=1}^{m}\gamma_{ji}}
μi=∑j=1mγji∑j=1mγjixj
更新gamma(由最大似然LL(D)对gamma的偏导数为0):
∑
i
=
∑
j
=
1
m
γ
j
i
(
x
j
−
μ
i
)
(
x
j
−
μ
i
)
T
∑
j
=
1
m
γ
j
i
\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)(xj−μi)T
更新每个高斯成分的混合系数alpha(由该成分的平均后验概率确定):
α
i
=
1
m
∑
j
=
1
m
γ
j
i
\alpha_i=\frac{1}{m}\sum_{j=1}^m\gamma_{ji}
αi=m1j=1∑mγji
整合代码
import numpy as np
import matplotlib.pyplot as plt
def multiGaussian(x,mu,sigma):
return 1/((2*np.pi)*pow(np.linalg.det(sigma),0.5))*np.exp(-0.5*(x-mu).dot(np.linalg.pinv(sigma)).dot((x-mu).T))
def computeGamma(X,mu,sigma,alpha,multiGaussian):
n_samples=X.shape[0]
n_clusters=len(alpha)
gamma=np.zeros((n_samples,n_clusters))
p=np.zeros(n_clusters)
g=np.zeros(n_clusters)
for i in range(n_samples):
for j in range(n_clusters):
p[j]=multiGaussian(X[i],mu[j],sigma[j])
g[j]=alpha[j]*p[j]
for k in range(n_clusters):
gamma[i,k]=g[k]/np.sum(g)
return gamma
class MyGMM():
def __init__(self,n_clusters,ITER=50):
self.n_clusters=n_clusters
self.ITER=ITER
self.mu=0
self.sigma=0
self.alpha=0
def fit(self,data):
n_samples=data.shape[0]
n_features=data.shape[1]
'''
mu=data[np.random.choice(range(n_samples),self.n_clusters)]
'''
alpha=np.ones(self.n_clusters)/self.n_clusters
mu=np.array([[.403,.237],[.714,.346],[.532,.472]])
sigma=np.full((self.n_clusters,n_features,n_features),np.diag(np.full(n_features,0.1)))
for i in range(self.ITER):
gamma=computeGamma(data,mu,sigma,alpha,multiGaussian)
alpha=np.sum(gamma,axis=0)/n_samples
for i in range(self.n_clusters):
mu[i]=np.sum(data*gamma[:,i].reshape((n_samples,1)),axis=0)/np.sum(gamma,axis=0)[i]
sigma[i]=0
for j in range(n_samples):
sigma[i]+=(data[j].reshape((1,n_features))-mu[i]).T.dot((data[j]-mu[i]).reshape((1,n_features)))*gamma[j,i]
sigma[i]=sigma[i]/np.sum(gamma,axis=0)[i]
self.mu=mu
self.sigma=sigma
self.alpha=alpha
def predict(self,data):
pred=computeGamma(data,self.mu,self.sigma,self.alpha,multiGaussian)
cluster_results=np.argmax(pred,axis=1)
return cluster_results
西瓜实验:
import pandas as pd
data = pd.read_csv(r'C:\Users\Asus\Desktop\jobs\machine learning\寒假机器学习笔记\datasets4.0.csv')
data=data.values
model1=MyGMM(3)
model1.fit(data)
result=model1.predict(data)
plt.scatter(data[:,0],data[:,1],c=result)
plt.scatter(model1.mu[:,0],model1.mu[:,1],marker='x',color='red')