前言
一、参数解析
#最终结果会是基于Inertia(簇内平方和)来计算的n_init次连续运行后的最佳输出
k = KMeans(n_clusters=4,#类的个数
init='k-means++',#可输入"k-means++","random"或者一个n维数组。这是初始化质心的方法,默认"k-means++"
n_init=10,#使用不同的质心随机初始化的种子来运行k-means算法的次数
max_iter=300,#单次运行的k-means算法的最大迭代次数
tol=0.0001,#tol:浮点数,默认1e-4,两次迭代间Inertia下降的量,如果两次迭代之间
#Inertia下降的值小于tol所设定的值,迭代就会停下
precompute_distances='deprecated',
verbose=0,
random_state=None,#控制每次质心随机初始化的随机数种子
copy_x=True,
n_jobs='deprecated',
algorithm='auto',).fit(X)
聚类算法的模型评估指标:
a、当真实标签已知的时候
1.调整兰德系数metrics.adjusted_rand_score(y_true, y_pred)取值在(-1,1)之间,负值象征着簇内的点差异巨大,甚至相互独立,正类的兰德系数比较优秀,越接近1越好。
2.互信息,取值范围在(0,1)之中越接近1,聚类效果越好在随机均匀聚类下产生0分。
metrics.adjusted_mutual_info_score (y_pred, y_true)
3.V-measure:基于条件上分析的一系列直观度量,取值范围在(0,1)之中
越接近1,聚类效果越好。metrics.homogeneity_score(y_true, y_pred)
b、当真实标签未知的时候:
轮廓系数,我们通常会绘制轮廓系数分布图和聚类后的数据分布图来选择我们的最佳n_clusters。
基于轮廓系数来选择n_clusters
'''
轮廓系数范围是(-1,1),其中值越接近1表示样本与自己所在的簇中的样本很相似,并且与其他簇中的样
本不相似,当样本点与簇外的样本更相似的时候,轮廓系数就为负。当轮廓系数为0时,则代表两个簇中的样本相
似度一致,两个簇本应该是一个簇。可以总结为轮廓系数越接近于1越好,负数则表示聚类效果非常差。
'''
from sklearn.metrics import silhouette_score#一个数据集中,所有样本的轮廓系数的均值
from sklearn.metrics import silhouette_samples##数据集中每个样本自己的轮廓系数
还可以使用:Calinski-Harabaz Index
二、使用步骤
1.导入数据
代码如下:
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
import pandas as pd
# 聚类算法用于降维,KMeans的矢量量化应用
data = pd.read_csv(r'F:\教师培训\ppd7\df_Master_clean.csv',encoding='gb18030')
x = data[data.target.notnull()].drop(columns=['Idx', 'target', 'sample_status', 'ListingInfo'])
y = data[data.target.notnull()]['target']
x_train,x_test, y_train, y_test = train_test_split(x,y,random_state=2,test_size=0.2)
2.操作步骤
代码如下(示例):
def plot_cluster(x, n):
for n_cluster in n:
n_clusters = n_cluster
# 画图
fig, ax = plt.subplots(1)
fig.set_size_inches(9, 7)#设置画布尺寸大小
# 横坐标是轮廓系数的取值范围是[-1,1],没必要从-1开始,只显示有值的地方即可
ax.set_xlim([-0.3, 1])
ax.set_ylim([0, 35000])#设置y轴范围,不同的簇有空隙,同一簇聚在一起
#聚类
clusterer = KMeans(n_clusters=n_clusters, random_state=10).fit(x)
cluster_labels = clusterer.labels_
silhouette_avg = silhouette_score(x, cluster_labels)#所有样本轮廓系数的均值
print("For n_clusters =", n_clusters,",The average silhouette_score is :", silhouette_avg)
sample_silhouette_values = silhouette_samples(x, cluster_labels)#单个样本自己的轮廓系数
# 设置y的初始取值
y_lower = 1000
# 对每一个类进行循环
for i in range(n_clusters):
ith_cluster_silhouette_values = sample_silhouette_values[cluster_labels == i]#每一类的轮廓系数
ith_cluster_silhouette_values.sort()#对每一类的轮廓系数进行排序
size_cluster_i = ith_cluster_silhouette_values.shape[0]#这一类有多少个元素
y_upper = y_lower + size_cluster_i#初始值的位置加上这个类中样本数量,一个大柱子,对应多个小柱子,柱子的长度是轮廓系数
color = cm.nipy_spectral(float(i)/n_clusters)#生成不同颜色nipy_spectral(输入任意小数代表一个颜色),确保每次绘制有不同的颜色
#fill_between让一个范围内的柱状图都统一颜色的函数
#fill_betweenx的范围在纵轴上
#fill_betweeny的范围在横轴上
#fill_betweenx的参数应该输入(纵坐标的下限,纵坐标的上限,x轴的取值,柱状图的颜色)
ax.fill_betweenx(np.arange(y_lower, y_upper)
,ith_cluster_silhouette_values
,facecolor=color
,alpha=0.7#透明度
)
#为每个簇的轮廓系数写上簇的编号,并且让簇编号显示在柱状图的中间位置
#text的参数为(要显示编号的横坐标,要显示编号的纵坐标,要显示编号的内容)
ax.text(-0.25, y_lower+0.5*size_cluster_i, str(i))
#为下一个簇计算y的初始值
y_lower = y_upper+1000
ax.set_title(("Silhouette analysis for KMeans clustering on sample data with n_clusters = %d" % n_clusters),
fontsize=14, fontweight='bold')
ax.set_xlabel("The silhouette coefficient values")
ax.set_ylabel("Cluster label")
# 在ax上画出整个聚类的轮廓系数的平均值
ax.axvline(x=silhouette_avg, color="red", linestyle="--")
ax.set_yticks([])
plot_cluster(x,[2,3])
总结
提示:此数据属于分类数据集,我拿过来用在聚类上,效果不是一般的差哈哈,代码部分源自菜菜机器学习。