手把手的K-means聚类算法教程(含简介及教育数据应用实例 Python实现)

手把手的K-means聚类算法教程(含简介及教育数据应用实例 Python实现)

  • 1. K-MEANS的基本原理
  • 2. 数据预处理
    • 2.1 数据读取:from Excel
    • 2.2 数据预处理:标准化Z分数
  • 3. 聚类过程
    • 3.1 K值的选取
      • 手肘法
      • 轮廓系数法
    • 3.2 聚类代码
  • 4. 聚类的评价
    • 4.1内部评估
    • 4.2外部评估
  • 参考资料

这段时间尝试练习了聚类(K-means),过程中有很多疑惑,想要的东西、参照的功能往往单篇博客不能够满足。故而整理,也将好的教程集锦,利己利人。
计划回顾梳理的系列有:
1.K-MEANS聚类算法的应用过程:数据读取-数据预处理-聚类指标的选取(含python代码)-聚类。
2.dataframe的操作整理:数值的读取等

1. K-MEANS的基本原理

K-means几乎是最常用的无监督学习方法,本质上是基于距离进行计算分类,距离越近,相似度越大,会划分成一类。
K的意思是聚成K类,需要我们选择设定。选取的方法见后面。
具体的内容不再赘述,可参照【机器学习】K-means(非常详细)

notes:
通常大家搜到的教程会以鸢尾花二维数据的例子,实际上K-MEANS可以应用于多维特征值的聚类。
需要对数据进行转化,可参见本文后续的案例代码。

2. 数据预处理

这里分析的是游戏log数据(闯关数据),包含很多用户很多列
数据文件是Excel的xlsx格式
前期已经进行了所需的清洗、合并计算,这里重点说明K-MEANS

2.1 数据读取:from Excel

#记得导入相关的包
#我这里是节选,所以并不全哈

#这里是将所有的用户特征值导入
#其中username包含0开头的情况(e.g.,’0601‘),为保证不失真,加入了格式控制converters
all_users_features=pd.read_excel("analysis_add_posttest.xlsx",converters = {u'user_name':str})


2.2 数据预处理:标准化Z分数

这里要注意的是:标准化和归一化
标准化:Z-score=(value-mean)/std
归一化:MAX-MIN,new value=(value-min)/(max-min), new-value总会在[0,1]之间。
一般而言,机器学习用标准化较多。也有特定场景需要使用归一化,可以参照尾部链接。

实现方法

我的实现方法有点冗余,每个用户每列计算的。
精髓在于:z_values=[] 存储一个用户的所有列数据。
因为dataframe 不是特别擅长处理单个单元格的存取,所以最好一行或者一列的操作。

当然,如果你的数据全是float等数值,无字符串也可以直接用dataframe的快捷算法:
标准化: df_norm = (df - df.mean()) / (df.std())
归一化:df_norm = (df - df.min()) / (df.max() - df.min())
记得导入包:
import numpy as np
import pandas as pd


#数据标准化处理
colz=['user_name','z_max_levels','z_avg_star','z_avg_time','z_avg_trys','z_avg_num_ani_tips','z_avg_num_3d_tips','z_FlowExperience','z_PostFolding','z_PostRotation','z_gender','z_age','z_PostRetention','z_PostTransfer','z_PostMotivation']
z_all_users=pd.DataFrame(columns=colz)
#取独一无二的用户值,形成List
user_names=list(set(all_users_features['user_name'].unique()))  

#对每一个用户的数据进行标准化
for user in user_names:
    z_values=[]
    #对每一列的数据进行标准化
    for every_col in all_users_features.columns.values[1:]:
        mean = all_users_features[every_col].values.mean()
        std = all_users_features[every_col].values.std()
        z = (all_users_features[all_users_features['user_name']==user][every_col] - mean) / std
        z_all_users.loc[z_all_users['user_name']==user,'z_'+every_col]=z  
        z_values.append(float(z))
#生成Z-score的dataframe
    z_all_users=z_all_users.append({'user_name':user,'z_max_levels':z_values[0],'z_avg_star':z_values[1],'z_avg_time':z_values[2],'z_avg_trys':z_values[3],'z_avg_num_ani_tips':z_values[4],'z_avg_num_3d_tips':z_values[5],'z_FlowExperience':z_values[6],'z_PostFolding':z_values[7],'z_PostRotation':z_values[8],'z_gender':z_values[9],'z_age':z_values[10],'z_PostRetention':z_values[11],'z_PostTransfer':z_values[12],'z_PostMotivation':z_values[13]},ignore_index=True)

z_all_users

#选取聚类的特征值列,将其Z分数转换为float
#还是那句话,记得导入相关的包 import numpy as np
X = np.array(z_all_users.iloc[:,1:],type(float))

3. 聚类过程

3.1 K值的选取

手肘法

代码实现,手肘图
如何根据手肘图选择K值:模拟肘部形状,肘部位置就是最佳的K值。
手肘法的原理:参见kmeans最优k值的确定方法-手肘法和轮廓系数法

from sklearn.cluster import  KMeans
sumDs=[]
for i in range(1,15):
    kmeans=KMeans(n_clusters=i)
    kmeans.fit(X)
    sumDs.append(kmeans.inertia_)
    print(kmeans.inertia_)
plt.plot(range(1,15),sumDs)
plt.title('the Elbow method')
plt.xlabel('number of cluster k')
plt.ylabel('SSE')
plt.show()

手把手的K-means聚类算法教程(含简介及教育数据应用实例 Python实现)_第1张图片

轮廓系数法

简要来说,一般选择值越大的越好。
但是也要轮廓系数最高的不一定是最佳的选择,需要看数据的分布情况。具体可以参照:Python实现K-Means聚类(案例:用户分类),这里我没仔细研究。以下代码是我摘录出我用到的部分,原博客更详细。


from sklearn import metrics
from sklearn.metrics import silhouette_score
from sklearn.metrics import silhouette_samples

#分别创建分群2-15的KMeans模型
clusters = range(2,15)
sc_scores = []
for k in clusters:  
    kmeans_model = KMeans(n_clusters=k).fit(X)
    sc_score = metrics.silhouette_score(X, kmeans_model.labels_)
    sc_scores.append(sc_score)
    print(sc_scores)
#作出K—平均轮廓系数曲线
plt.figure()
plt.plot(clusters, sc_scores, 'bx-')
plt.rcParams['figure.figsize'] = [12,8]
plt.xlabel('k',fontsize=18)
plt.ylabel('Silhouette Coefficient Score',fontsize=18)  #样本平均轮廓系数
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.show()

手把手的K-means聚类算法教程(含简介及教育数据应用实例 Python实现)_第2张图片

3.2 聚类代码

输出分类值的信息,调用已有的算法进行计算。
cluster =KMeans(n_clusters=4).fit(X)
X是前述处理转换好的数据集

#选择要聚的类别数,进行计算,我这里选择的4类进行聚类,并输出其轮廓系数。
cluster =KMeans(n_clusters=4).fit(X)
labels = cluster.labels_
pgjg1=metrics.silhouette_score(X, labels, metric='euclidean')   #轮廓系数
print('聚类结果的轮廓系数=',pgjg1)

4. 聚类的评价

参见:十分钟掌握聚类算法的评估指标

4.1内部评估

轮廓系数(Silhouette Coefficient)
Calinski-Harabaz指数(Calinski-Harabaz Index)
戴维森堡丁指数(DBI, Davies-Bouldin Index)

4.2外部评估

兰德指数(RI, Rand index)
调整兰德系数(Adjusted Rand index)
标准化互信息(NMI, Normalized Mutual Information)
调整互信息(AMI, Adjusted mutual information)
同质性度量和完整性度量的调和平均(V-measure)
Fowlkes-Mallows Scores(FMI)

参考资料

机器学习面试之归一化与标准化
【机器学习】K-means(非常详细)
kmeans最优k值的确定方法-手肘法和轮廓系数法
python 实现k-means聚类算法 银行客户分组画像实战(超详细,附源码)
Python实现K-Means聚类(案例:用户分类)
十分钟掌握聚类算法的评估指标

你可能感兴趣的:(机器学习,Python,python,机器学习,无监督学习,聚类,k-means)