这段时间尝试练习了聚类(K-means),过程中有很多疑惑,想要的东西、参照的功能往往单篇博客不能够满足。故而整理,也将好的教程集锦,利己利人。
计划回顾梳理的系列有:
1.K-MEANS聚类算法的应用过程:数据读取-数据预处理-聚类指标的选取(含python代码)-聚类。
2.dataframe的操作整理:数值的读取等
K-means几乎是最常用的无监督学习方法,本质上是基于距离进行计算分类,距离越近,相似度越大,会划分成一类。
K的意思是聚成K类,需要我们选择设定。选取的方法见后面。
具体的内容不再赘述,可参照【机器学习】K-means(非常详细)
notes:
通常大家搜到的教程会以鸢尾花二维数据的例子,实际上K-MEANS可以应用于多维特征值的聚类。
需要对数据进行转化,可参见本文后续的案例代码。
这里分析的是游戏log数据(闯关数据),包含很多用户很多列
数据文件是Excel的xlsx格式
前期已经进行了所需的清洗、合并计算,这里重点说明K-MEANS
#记得导入相关的包
#我这里是节选,所以并不全哈
#这里是将所有的用户特征值导入
#其中username包含0开头的情况(e.g.,’0601‘),为保证不失真,加入了格式控制converters
all_users_features=pd.read_excel("analysis_add_posttest.xlsx",converters = {u'user_name':str})
这里要注意的是:标准化和归一化
标准化: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))
代码实现,手肘图
如何根据手肘图选择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()
简要来说,一般选择值越大的越好。
但是也要轮廓系数最高的不一定是最佳的选择,需要看数据的分布情况。具体可以参照: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()
输出分类值的信息,调用已有的算法进行计算。
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)
参见:十分钟掌握聚类算法的评估指标
轮廓系数(Silhouette Coefficient)
Calinski-Harabaz指数(Calinski-Harabaz Index)
戴维森堡丁指数(DBI, Davies-Bouldin Index)
兰德指数(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聚类(案例:用户分类)
十分钟掌握聚类算法的评估指标