一、聚类学习算法实现
- 随机设置K个特征空间内的点作为初始的聚类中心
- 对于其他每个点计算到K个中心点的距离(欧氏距离),未知的点选择最近的一个中心点作为标记类别
- 聚类完成之后,计算每个类别的中心点(平均值)
- 如果计算得出的新中心点与原中心点一样(质心不再移动),那么结束,否则重新进行第2步过程
二、案例
1.引入库
代码如下(示例):
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
from sklearn.metrics import calinski_harabaz_score
2.程序代码
#创建数据集
# cluster_std 分布,值越大越分散
# n_features 几个特征
# centers 中心点
X,y = make_blobs(n_samples=100,n_features=2,centers=[[-1,-1],[0,0],[1,1],[2,2]],cluster_std=[0.4,0.1,0.1,0.1],random_state=1)
plt.scatter(X[:,0],X[:,1],c=y)
plt.show()
# 训练
# n_clusters 聚成几类
estimator = KMeans(n_clusters=4,random_state=2)
pre = estimator.fit_predict(X)
print(pre)
print(y)
plt.scatter(X[:,0],X[:,1],c=pre)
plt.show()
# 评估
scaore = calinski_harabaz_score(X,pre)
print(scaore)
print(y==pre)
三、模型评估
误差平方和
- 计算当前类别中所有标记点到中心点的距离
- 将所有类别的距离计算求和
S S E = ∑ i = 1 k ∑ p ∈ C i ∣ p − m i ∣ 2 SSE=\sum_{i=1}^k\sum_{p∈C_i}|p-m_i|^2 SSE=i=1∑kp∈Ci∑∣p−mi∣2
SSE随着聚类迭代,其值越来越小,直到最后趋于稳定
如果执行的初始值选择不好,SSE只会达到一个不怎么好的局部最优解
肘部法-K值确定
下降率突然变缓时即认为是最佳的k值
轮廓系数法
S
C
=
b
−
a
m
a
x
(
a
,
b
)
SC = \frac{b-a}{max(a,b)}
SC=max(a,b)b−a
SC系数的取值范围在[-1,1]之间
CH系数
迹
类别内部协方差越小越好,类别之间协方差越大越好
m样本数 k是类别数
用尽量少的类别聚类更多的样本,同时获得最好的聚类效果
s
(
k
)
=
t
r
(
B
k
)
t
r
(
W
k
)
m
−
k
k
−
1
s(k)=\frac{tr(B_k)}{tr(W_k)}\frac{m-k}{k-1}
s(k)=tr(Wk)tr(Bk)k−1m−k
四、算法优化
Canopy
绘制同心圆进行k值选择筛选,需要确定同心圆的半径t1和t2
K-means++
距离平方进行求解,保证下一个质心到当前质心距离最远。
- 从数据集中随机选择一个点作为第一个聚类中心
- 计算每个样本与当前已有聚类中心之间的最短距离D(x),即与最近的一个聚类中心的距离(以概率选择距离最大的样本作为新的聚类中心)。这个值越大,表示被选取作为聚类中心的概率较大;并计算每个样本被选为下一个聚类中心的概率(如下所示),最后用轮盘法选出下一个聚类中心。
P = D ( x ) 2 ∑ x ∈ X D ( x ) 2 P=\frac{D(x)^2}{\sum_{x∈X}{D(x)^2}} P=∑x∈XD(x)2D(x)2
二分k-meas
通过误差平方和设置阈值进行划分
k_medoids
与k-means选取中心点的方式不同,对噪声有很好的鲁棒性。计算每个点之间的距离和,选取最小的作为质心。
kernel-kmeas
将低维度空间升级到高维度空间进行聚类
ISODATA
可以更改k值大小,可以对质心进行合并等
Mini-batch
从大数据集中只取部门数据进行聚类,从而减少计算的复杂度
总结
k-meas聚类
优点:
简单容易理解
缺点:
随机指定k值,容易陷入局部最优解