K-means聚类
作用
K-means 聚类是一种无监督学习算法,旨在将数据点分成若干个不同的群组(或簇),使得同一簇内的数据点彼此相似,而不同簇之间的数据点差异较大,算法的目标是最小化簇内的平方误差和(SSE),即每个簇内数据点与该簇中心的距离的平方和
t-SNE降维
作用
t-SNE(t-分布随机邻域嵌入)是一种降维算法,用于将高维数据映射到低维空间(通常是二维或三维)进行可视化,t-SNE 保留了数据点之间的局部结构,使得相似的数据点在降维后的空间中距离较近,适用于数据的可视化和理解
组合
K-means聚类用于将数据点分组到不同的簇中,找出每个簇的中心, t-SNE降维用于将这些高维数据点映射到二维空间,使得聚类结果可以通过二维图形进行可视化,通过结合这两种方法,我们可以首先对数据进行有效的聚类,然后将聚类结果通过 t-SNE 降维可视化,从而更好地理解和解释数据的结构和分布
代码实现
数据读取
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei' # 设置中文显示
plt.rcParams['axes.unicode_minus'] = False
import seaborn as sns
import warnings
# 忽略所有警告
warnings.filterwarnings('ignore')
df = pd.read_excel('商品.xlsx')
df
数据记录了超市各个站点在不同类别商品上的销售金额,这些数据具有多维特征(大于三维),难以直接展示和分析,通过降维技术,我们可以将高维数据映射到二维空间,从而有效地可视化聚类效果
聚类数K确定
from sklearn.cluster import KMeans
from sklearn import metrics
# 计算SSE(肘部图)
SSE = []
for k in range(1, 11):
km = KMeans(n_clusters=k, random_state=42)
km.fit(df)
SSE.append(km.inertia_)
X = range(1, 11)
plt.figure(figsize=(15, 5), dpi=300)
plt.subplot(1, 2, 1)
plt.xlabel('k')
plt.ylabel('SSE')
plt.title('肘部图')
plt.plot(X, SSE, 'o-')
plt.grid(True)
# 计算轮廓系数
scores = []
for k in range(2, 11):
labels = KMeans(n_clusters=k, random_state=42).fit(df).labels_
score = metrics.silhouette_score(df, labels)
scores.append(score)
X = range(2, 11)
# 创建第二个子图:轮廓系数图
plt.subplot(1, 2, 2)
plt.xlabel('k')
plt.ylabel('轮廓系数')
plt.title('轮廓系数图')
plt.plot(X, scores, 'o-')
plt.grid(True)
plt.tight_layout()
plt.show()
这里根据轮廓系数图和肘部图确定最佳K,肘部图上通常会出现一个弯曲点,这个点的形状类似于肘部。这个肘部所在的k值是最佳的簇数选择,因为在这个点之后,增加簇数对SSE的减少效果会逐渐减小,轮廓系数的值在-1到1之间,值越高表示聚类效果越好,选择轮廓系数最高的k值作为最佳簇数,综合二者确定聚类数K=5
聚类实现
# 使用K-means进行聚类,并指定聚类数为3
columns = df.columns
kmeans = KMeans(n_clusters=5, random_state=42)
df['Cluster'] = kmeans.fit_predict(df)
# 获取聚类中心
centers = kmeans.cluster_centers_
# 创建聚类中心的DataFrame,并设置索引为聚类中心类别
centers_df = pd.DataFrame(centers, columns=columns)
centers_df.index = ['Cluster_0', 'Cluster_1', 'Cluster_2', 'Cluster_3', 'Cluster_4']
data = pd.concat([df.iloc[:,0:6], centers_df], axis = 0).reset_index(drop=True)
使用K-means算法将数据聚类为5个簇,并将每个数据点的簇标签存储在df['Cluster']中,同时计算并记录了每个簇的中心点,最后将原始数据 df 的前六列与计算出的聚类中心 centers_df 进行拼接,生成一个新的 DataFrame data,其中包含原始数据和聚类中心,并重置索引,方便接下来的降维处理
降维实现
from sklearn.manifold import TSNE
# 使用t-SNE进行降维
print('数据降维前维度:',data.shape)
tsne = TSNE(n_components=2, random_state=0)
X_2d = tsne.fit_transform(data)
print('数据降维后维度:',X_2d.shape)
# 将降维后的数据保存为一个新的 DataFrame
df_tsne = pd.DataFrame(X_2d, columns=['Dimension 1', 'Dimension 2'])
df_tsne.head()
使用 t-SNE 将多维数据降维到二维,并将降维后的结果保存为一个新的 DataFrame,以便于进一步的可视化和分析
可视化
plt.figure(figsize=(14, 10))
df_last = df_tsne.iloc[-5:]
df_rest = df_tsne.iloc[:-5]
clusters = df['Cluster']
palette = sns.color_palette("viridis", len(df['Cluster'].unique()))
scatter = plt.scatter(df_rest['Dimension 1'], df_rest['Dimension 2'], c=clusters, cmap='viridis', marker='o', s=50)
markers = ['X', 'P', 'D', 'H', 's']
# 绘制聚类中心数据点,使用不同颜色和形状
for i, marker in enumerate(markers):
plt.scatter(df_last.iloc[i]['Dimension 1'],
df_last.iloc[i]['Dimension 2'],
c=[sns.color_palette("tab10")[i]],
marker=marker,
s=50,
linewidths=3,
label=f'Cluster_{i} Center')
# 添加普通数据点的图例
handles, _ = scatter.legend_elements(prop="colors")
legend1 = plt.legend(handles, [f'Cluster_{i}' for i in range(len(handles))], loc="upper right", title="Clusters")
plt.gca().add_artist(legend1)
legend2 = plt.legend(loc="lower right", title="Cluster Centers")
plt.gca().add_artist(legend2)
plt.title("t-SNE Clustering of Iris Dataset", fontsize=16)
plt.xlabel("Dimension 1", fontsize=14)
plt.ylabel("Dimension 2", fontsize=14)
plt.grid(True)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
sns.despine()
plt.show()
通过 t-SNE 降维后的二维散点图可视化 K-means 聚类结果,其中包括了普通数据点和聚类中心,以便于分析不同簇的分布情况及其中心位置
往期推荐
小白轻松上手:一键生成SHAP解释图的GUI应用,支持多种梯度提升模型选择
综合多种梯度提升模型:LightGBM、XGBoost、CatBoost与NGBoost的集成预测
梯度提升集成:CatBoost与NGBoost模型的K折交叉验证及组合预测
特征工程进阶:暴力特征字典的构建与应用 实现模型精度质的飞跃
无网络限制!同步官网所有功能!让编程小白也能轻松上手进行代码编写!!!
微信号|deep_ML
欢迎添加作者微信进入Python、ChatGPT群
进群请备注Python或AI进入相关群
无需科学上网、同步官网所有功能、使用无限制
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~
个人观点,仅供参考