最近做聚类分析,记录一下聚类后,利用PCA将特征降维到二维、三维,进行聚类可视化的方法
数据处理和EDA部分就不放在这里了,有兴趣的可以点击下方链接看完整的项目,fork后可以看到完整代码,可下载也可以在线运行:
关于大五人格测试数据集的探索【可视化分析+k-means聚类分析】¶
df2 = df.iloc[:,0:50]
df3 = df2.copy()
df2.head()
我这里聚类数目为4类
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=4)
k_fit = kmeans.fit(df2)
predictions = k_fit.labels_
df2['Clusters'] = predictions
df2.head()
查看不同类别的数目
Clu_nums = df2['Clusters'].value_counts()
Clu_nums
0 160727
1 152405
3 145982
2 139999
Name: Clusters, dtype: int64
这里使用df3是因为df2做了一些计算分析,如果直接可视化,还用df2就行,不过因为df3是拷贝的df2的数据,所以没有影响
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
pca_fit = pca.fit_transform(df3)
df_pca = pd.DataFrame(data=pca_fit, columns=['PCA1', 'PCA2'])
df_pca['Clusters'] = predictions
df_pca.head()
plt.figure(figsize=(10,10))
sns.scatterplot(data=df_pca, x='PCA1', y='PCA2', hue='Clusters', palette='tab10', alpha=0.8)
plt.title('Personality Clusters after PCA');
pca2 = PCA(n_components=3)
pca_fit2 = pca2.fit_transform(df3)
df_pca2 = pd.DataFrame(data=pca_fit2, columns=['PCA1', 'PCA2', 'PCA3'])
df_pca2['Clusters'] = predictions
df_pca2.head()
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111, projection='3d')
x = df_pca2['PCA1']
y = df_pca2['PCA2']
z = df_pca2['PCA3']
ax.scatter(x, y, z,c = predictions, cmap="jet", marker="o")
plt.title("KMeans (N = 4)");
ax.set_xlabel('PCA1')
ax.set_ylabel('PCA2')
ax.set_zlabel('PCA3')
1.我的数据单位是相同的,而且数值范围统一,我就没做数据归一化,如果有需求别忘了
2.在这个项目里面,因为数据量太大,我没有找轮廓系数最有的聚类个数
,但是代码还是值得记录一下的
# 通过平均轮廓系数检验得到最佳KMeans聚类模型
score_list = list() # 用来存储每个K下模型的平局轮廓系数
silhouette_int = -1 # 初始化的平均轮廓系数阀值
for n_clusters in range(2, 8): # 遍历从2到5几个有限组
model_kmeans = KMeans(n_clusters=n_clusters) # 建立聚类模型对象
labels_tmp = model_kmeans.fit_predict(X) # 训练聚类模型
silhouette_tmp = silhouette_score(X, labels_tmp) # 得到每个K下的平均轮廓系数
if silhouette_tmp > silhouette_int: # 如果平均轮廓系数更高
best_k = n_clusters # 保存K将最好的K存储下来
silhouette_int = silhouette_tmp # 保存平均轮廓得分
best_kmeans = model_kmeans # 保存模型实例对象
cluster_labels_k = labels_tmp # 保存聚类标签
score_list.append([n_clusters, silhouette_tmp]) # 将每次K及其得分追加到列表
print('{:*^60}'.format('K值对应的轮廓系数:'))
print(np.array(score_list)) # 打印输出所有K下的详细得分
print('最优的K值是:{0} \n对应的轮廓系数是:{1}'.format(best_k, silhouette_int))