聚类算法:是一种典型的无监督学习算法,主要用于将相似的样本自动归到一个类别中。
聚类算法与分类算法最大的区别是:聚类算法是无监督的学习算法,而分类算法属于监督的学习算法,分类是知道结果的。
在聚类算法中根据样本之间的相似性,将样本划分到不同的类别中,对于不同的相似度计算方法,会得到不同的聚类结果,常用的相似度计算方法有欧式距离法。
K-means中心思想:事先确定常数K,常数K意味着最终的聚类类别数,首先随机选定初始点为质心,并通过计算每一个样本与质心之间的相似度(这里为欧式距离),将样本点归到最相似的类中,接着,重新计算每个类的质心(即为类中心),重复这样的过程,直到质心不再改变,最终就确定了每个样本所属的类别以及每个类的质心。由于每次都要计算所有的样本与每一个质心之间的相似度,故在大规模的数据集上,K-Means算法的收敛速度比较慢。
在实际的应用中,主要两种方法进行K值的确定:
a、经验法:在实际的工作中,可以结合业务的场景和需求,来决定分几类以确定K值。
b、肘部法则:在使用聚类算法时,如果没有指定聚类的数量,即K值,则可以通过肘部法则来进行对K值得确定。
肘部法则是通过成本函数来刻画的,其是通过将不同K值的成本函数刻画出来,随着K值的增大,平均畸变程度会不断减小且每个类包含的样本数会减少,于是样本离其重心会更近。但是,随着值继续增大,平均畸变程度的改善效果会不断减低。
因此找出在K值增大的过程中,畸变程度下降幅度最大的位置所对应的K较为合理。
注:成本函数:各个类的畸变程度之和与其内部成员位置距离的平方和,最优解是以成本函数最小化为目标。
公式如下:
c、规则法:(此种方法存在一定的缺点:可能导致聚类的数目较大)
a、样本离最近聚类中心的总和(inertias)
inertias:其是K均值模型对象的属性,表示样本距离最近的聚类中心的总和,它是作为在没有真实分类标签下的非监督式评估指标,该值越小越好,值越小证明样本在类间的分布越集中,即类内的距离越小。
b、轮廓系数
轮廓系数:它用来计算所有样本的平均轮廓系数,使用平均群内距离和每个样本的平均最近簇距离来计算,它是一种非监督式评估指标。其最高值为1,最差值为-1,0附近的值表示重叠的聚类,负值通常表示样本已被分配到错误的集群。
c、兰德指数
调整后的兰德指数:兰德指数通过考虑在预测和真实聚类中在相同或不同的聚类中分配的所有样本对和计数对来计算两个聚类之间的相似性度量。调整后的兰德指数通过对兰德指数的调整得到独立于样本量和类别的接近于0的值,其取值范围为[-1,1],负数代表结果不好,越接近于1越好意味着聚类结果与真实情况吻合。
d、同质化得分
同质化得分(Homogeneity),如果所有的聚类都只包含属于单个类的成员的数据点,则聚类结果将满足同质性。其取值范围[0,1]值越大意味着聚类结果与真实情况越吻合。
优点:
说明:N为样本点个数,K为中心点个数,I为迭代次数
缺点:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from scipy.spatial.distance import cdist
from sklearn import metrics #导入sklearn效果评估模块
#导入相关数据
raw_data=np.loadtxt('cluster.txt')
X=raw_data[:,:-1] #分割要聚类的数据
y_true=raw_data[:,-1]
#确定要聚类的数目:肘部法则
X=raw_data[:,:-1] #分割要聚类的数据
y_true=raw_data[:,-1]
plt.figure()
plt.axis([0, 2.5, 0, 2.5])
plt.grid(True)
plt.plot(X[:,0],X[:,1],'k.')
K = range(1, 10)
meandistortions = []
for k in K:
kmeans = KMeans(n_clusters=k)
kmeans.fit(X)
meandistortions.append(sum(np.min(cdist(X, kmeans.cluster_centers_, 'euclidean'), axis=1)) / X.shape[0])
plt.plot(K, meandistortions, 'bx-')
plt.xlabel('k')
plt.ylabel('meandistortions')
plt.title('best K of the model');
#训练聚类模型
n_clusters=3 #设置聚类数量
model_kmeans=KMeans(n_clusters=n_clusters,random_state=0) #建立聚类模型对象
model_kmeans.fit(X) #训练聚类模型
y_pre=model_kmeans.predict(X) #预测聚类模型
#模型效果评估
n_samples,n_features=X.shape #总样本量,总特征数
inertias=model_kmeans.inertia_ #样本距离最近的聚类中心的总和
adjusted_rand_s=metrics.adjusted_rand_score(y_true,y_pre) #调整后的兰德指数
homogeneity_s=metrics.homogeneity_score(y_true,y_pre) #同质化得分
silhouette_s=metrics.silhouette_score(X,y_pre,metric='euclidean') #平均轮廓系数
#模型效果可视化
centers=model_kmeans.cluster_centers_ #各类别中心
colors=['#4EACC5','#FF9C34','#4E9A06'] #设置不同类别的颜色
plt.figure() #建立画布
for i in range(n_clusters): #循环读取类别
index_sets=np.where(y_pre==i) #找到相同类的索引集合、
cluster=X[index_sets] #将相同类的数据划分为一个聚类子集
plt.scatter(cluster[:,0],cluster[:,1],c=colors[i],marker='.') #展示聚类子集内的样本点
plt.plot(centers[i][0],centers[i][1],'o',markerfacecolor=colors[i]
,markeredgecolor='k',markersize=6) #展示各聚类子集的中心
plt.show() #展示图像
肘部法确定K值:
从图中可以看出K值应该取3。
#模型效果评估:
ine ARI homo silh
300 0.96 0.94 0.63
----------------------------------------------------------------------
ine inertias
ARI adjuster_rand_s
homo homogeneity_s
silh silhouette_s
----------------------------------------------------------------------
模型效果的可视化:
从上表和图中可以看出,兰德指数得分0.96、平均轮廓系数得分0.94,轮廓系数0.63,说明聚类效果较好。