算法原理
K-means, K均值聚类算法
假设每个 cluster 存在一个中心点,该 cluster 内的所有数据项到这个中心点的欧式距离(勾股定理的扩展:各维度差的平方求和再开方)都小于到其他 cluster 中心点的距离。算法的任务就是找出这些 cluster 的中心点。K-means 算法先随机选取 K (唯一的算法参数) 个点作为中心点,然后通过计算欧式距离来给所有数据项归类。归类之后使用平均值算法(mean)重新计算每个类的中心点,继续计算距离归类,直到中心点不再变化,此时视为收敛完成。
GMM,高斯混合聚类算法
假设每个聚类的数据都是符合高斯分布(又叫常态分布或者正态分布)的,当前数据呈现的分布就是各个聚类的分布叠加在一起。使用 EM 算法求解,具体没搞太明白。大概就是两个参数先随机指定一个,然后算另外一个,最后跟结果比较。
算法特点
K-means
算法简单,容易理解。计算量不大,收敛快。可以很方便的进行分布式计算。默认所有属性对距离的影响是相同的,默认所有数据均匀分布在聚类中。如果数据是三维空间中的圆柱体,模型就失效了。
GMM
不容易理解,需要翻翻统计学的教材。假设各个特征的权重不同,假设各个聚类中的数据分布不均匀。理论上可以拟合任何连续函数。计算量较大。如果其中一个聚类的数据并不服从正态分布、偏态分布,聚类算法会出现偏差。
sk-learn 代码
k-means
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
#遍历可能的 cluster 个数,选择边界最清晰的
for i in [2, 3, 4, 5, 6, 7, 8]:
clusterer = KMeans(n_clusters=i, random_state=1024)
clusterer.fit(data)
#预测每一个点的簇
labels = clusterer.predict(data)
#边界系数,[-1, 1] 越大越清晰
silhouette_avg = silhouette_score(data, labels)
print("For clusters = ", i,
"The average silhouette_score is :", silhouette_avg)
if silhouette_avg > best_score:
best_clusterer = clusterer
best_score = silhouette_avg
best_cluster = i
#中心点
print best_clusterer.centers_
GMM
from sklearn.mixture import GaussianMixture
from sklearn.metrics import silhouette_score
#遍历可能的 cluster 个数,选择边界最清晰的
for i in [2, 3, 4, 5, 6, 7, 8]:
clusterer = GaussianMixture(n_components=i, random_state=1024)
clusterer.fit(data)
#预测每一个点的簇
labels = clusterer.predict(data)
#边界系数,[-1, 1] 越大越清晰
silhouette_avg = silhouette_score(data, labels)
print("For clusters = ", i,
"The average silhouette_score is :", silhouette_avg)
if silhouette_avg > best_score:
best_clusterer = clusterer
best_score = silhouette_avg
best_cluster = i
#中心点
print best_clusterer.means_