])
# 画分类中心点
mark = [\'*r\',\'*b\',\'*g\',\'*y\']
for i,center in enumerate(centers):
plt.plot(center[0],center[1],mark,markersize=20)
plt.show()
K-Means算法优化
根据经验:使用多次的随机初始化,计算每一次建模得到代价函数的值,选取代价 函数最小结果作为聚类结果
肘部法则优化k
from sklearn import metrics
silhouette_all=[]
for k in range(2,10):
model = KMeans(n_clusters=k)
model.fit(data)
labels = model.labels_
silhouette_score = metrics.silhouette_score(data, labels, metric=\'euclidean\')
silhouette_all.append(silhouette_score)
plt.plot(range(2,10),silhouette_all)
plt.xlabel(\'k\')
plt.ylabel(\'silhouette_score\')
plt.show()
轮廓系数:Mini Batch K-Means算法
Mini Batch K-Means算法是K-Means算法的变种,采用小批量的数据子集减小计 算时间。这里所谓批是指每次训练算法时所随机抽取的数据子集,采用这些随 机产生的子集进行训练算法,大大减小了计算时间,结果一般只略差于标准算法。
算法的迭代步骤有两步:
从数据集中随机抽取一些数据形成小批量,把他们分配给最近的质心
更新质心
与K均值算法相比,数据的更新是在每一个小样本集上。Mini Batch K-Means比 K-Means有更快的收敛速度,略微降低聚类的效果。
DBSCAN
DBSCAN(Density-Based Spatial Clustering of Applications with Noise):它将簇定义为密度相连的点组成的最大集合,能够把具有足够高密度的区域划 分为簇,并可在噪声的空间数据库中发现任意形状的聚类
DBSCAN中的几个定义:
Ε邻域:给定对象半径为Ε内的区域称为该对象的Ε邻域
核心对象:如果给定对象Ε邻域内的样本点数大于等于Min-points,则称 该对象为核心对象
直接密度可达:对于样本集合D,如果样本点q在p的Ε邻域内,并且p为核 心对象,那么p到q直接密度可达
密度可达:对于样本集合D,给定一串样本点p1,p2….pn,p=p1,q=pn,假如 pi-1到pi直接密度可达,那么对象p到q密度可达
密度相连:存在样本集合D中的一点o,如果对象o到对象p和对象q都是密度 可达的,那么p和q密度相联
DBSCAN密度聚类思想:由密度可达关系导出的最大密度相连的样本集合,即为 我们最终聚类的一个类别,或者说一个簇
算法步骤:
指定合适的E和Min-points;
计算所有的样本点,如果p的E邻域里有超过Min-points个点,则创建一个 以p为核心点的新簇;
反复寻找这些核心点直接密度可达(之后能是密度可达)的点,将其加入 到相应簇,对于核心点发生“密度相连”状况的簇,给予合并;
当没有新的点可以被添加到任何簇时,算法结束。
DBSCAN的主要优点有:
不需要输入聚类个数,可以对任意形状的稠密数据集进行聚类,相对的, K-Means之类的聚类算法一般只适用于凸数据集
可以在聚类的同时发现异常点,对数据集中的异常点不敏感
聚类结果没有偏倚,相对的,K-Means之类的聚类算法初始值对聚类结果有 很大影响
DBSCAN的主要缺点有:
如果样本集的密度不均匀、聚类间距差相差很大时,聚类质量较差
如果样本集较大时,聚类收敛时间较长
调参相对于传统的K-Means之类的聚类算法稍复杂,需要对距离阈值E,邻域样本数阈值Min-points联合调参
数据集是稠密的,并且数据集不是凸的,DBSCAN会比K-Means聚类效果好很多
代码实现
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
%matplotlib inline
x1, y1 = datasets.make_circles(n_samples=2000, factor=.4, noise=.05)#x1为坐标,y1为标签,这里不需要标签
x2, y2 = datasets.make_blobs(n_samples=1000, centers=[[1.2,1.2]], cluster_std=[[.1]])
x = np.concatenate((x1, x2))
plt.scatter(x[:, 0], x[:, 1], marker=\'o\')
plt.show()
from sklearn.cluster import DBSCAN
y_pred = DBSCAN(eps = 0.2,min_samples=50).fit_predict(x)
plt.scatter(x[:, 0], x[:, 1], c=y_pred)
plt.show()