本次整理了聚类工程里面常见算法,以及给出合适的工程结构方便调用,编写常用的聚类指标当作聚类结果函数,并Github链接在文末,供大家交流学习。
“物以类聚,人以群分”
下面介绍几种聚类算法
主要实现了肘部法确定聚类簇数,以及调用python的库函数进行聚类,可以参考我前面的博文
这篇更新一个带有权重的Kmeans算法,我们有时候需要给特征规定不同的权重,这个可以根据特征重要性来判断,具体更新在欧氏距离的计算上:
def euclidean_distance(one_sample, X):
'''
:param one_sample: 一个样本点输入
:param X: 所有的聚类中心
:return: 样本点距离每一个聚类中心的距离
'''
one_sample = one_sample.reshape(1, -1)
X = X.reshape(X.shape[0], -1)
distances = []
w = [1, 0.2, 0.2]
n = X.shape[0] # n 表示样本的个数
for i in range(n):
subs = one_sample - X[i]
dimension2 = np.power(subs, 2)
w_dimension2 = np.multiply(w, dimension2)
w_distance2 = np.sum(w_dimension2, axis=1)[0]
distances.append(w_distance2)
return distances
这一部分在前面已经详细阐述过了,可以参考我前面的博文
AP聚类也叫亲和力(Affinity Propagation)聚类是2007年在Science杂志上提出的一种新的聚类算法。推荐论文阅读Affinity Learning for Mixed Data Clustering
论文提出了基于混合对数据进行聚类的学习框架,具体研究内容包括:1)如何处理具有混合类型属性的数据、2)如何学习数据点之间的相互作用、以及3)如何利用学习的融合进行聚类。
AP算法的优点是:
1)不需要制定最终聚类个数;
2)将已有数据点作为最终的聚类中心,而不是新生成聚类中心;
3)模型对数据的初始值不敏感,多次执行AP聚类算法,得到的结果是完全一样的,即不需要进行随机选取初值步骤(还是对比K-Means的随机初始值);
4)对初始相似度矩阵数据的对称性没有要求;
5)与k中心聚类方法相比,其结果的平方差误差较小,相比于K-means算法,鲁棒性强、准确度较高,但算法复杂度高、运算消耗时间多。
具体思想是以S矩阵的对角线上的数值s (k, k)作为k点能否成为聚类中心的评判标准,这意味着该值越大,这个点成为聚类中心的可能性也就越大,这个值又称作参考度p ( preference) 。聚类的数量受到参考度p的影响,如果认为每个数据点都有可能作为聚类中心,那么p就应取相同的值。如果取输入的相似度的均值作为p的值,得到聚类数量是中等的。如果取最小值,得到类数较少的聚类。
主要代码部分如下:
def AP_clustering(data):
'''
:param data:
:param labels_true:
:return:
'''
center_num=[]
for i in range(-20,-50,-5):
ap = AffinityPropagation(preference=i).fit(data)
cluster_centers_indices = ap.cluster_centers_indices_ # 预测出的中心点的索引,如[123,23,34]
labels = ap.labels_ # 预测出的每个数据的类别标签,labels是一个NumPy数组
n_clusters_ = len(cluster_centers_indices) # 预测聚类中心的个数
center_num.append(n_clusters_)
print('预测的聚类中心个数:%d' % n_clusters_)
谱聚类是从图论中演化出来的算法,后来在聚类中得到了广泛的应用。它的主要思想是把所有的数据看做空间中的点,这些点之间可以用边连接起来。距离较远的两个点之间的边权重值较低,而距离较近的两个点之间的边权重值较高,通过对所有数据点组成的图进行切图,让切图后不同的子图间边权重和尽可能的低,而子图内的边权重和尽可能的高,从而达到聚类的目的。
要完全理解这个算法的话,需要对图论中的无向图、线性代数和矩阵分析都有一定的了解,因此在这不做过多解释,想要学习的小伙伴可以参考链接或者自己进行学习
谱聚类在python中的实现较容易,主要代码是用于参数寻优,具体聚类操作只需调用一个函数即可,代码如下:
def chose_para(X):
# 默认使用的是高斯核,需要对n_cluster和gamma进行调参,选择合适的参数
scores = []
s = dict()
for index, gamma in enumerate((0.01, 0.1, 1, 10)):
for index, k in enumerate((2, 3, 4)):
y_pred = SpectralClustering(n_clusters=k,gamma=gamma).fit_predict(X.data)
print("Calinski-Harabasz Score with gamma=", gamma, "n_cluster=", k, "score=",
calinski_harabasz_score(X.data, y_pred))
tmp = dict()
tmp['gamma'] = gamma
tmp['n_cluster'] = k
tmp['score'] = calinski_harabasz_score(X.data, y_pred)
s[calinski_harabasz_score(X.data, y_pred)] = tmp
scores.append(calinski_harabasz_score(X.data, y_pred))
max_score = s.get(np.max(scores))
print("max score:\n",max_score)
gamma = list(max_score.values())[0]
n_clusters = list(max_score.values())[1]
y_pred = SpectralClustering(n_clusters=n_clusters,gamma=gamma).fit_predict(X)
plt.title('SpectralClustering of blobs')
plt.scatter(X[:, 0], X[:, 1], marker='.',c=y_pred)
plt.show()
return y_pred
附上Github的代码链接供小伙伴交流学习,欢迎大家批评指正