如何优化泰坦尼克号数据的KMeans聚类及可视化效果?
泰坦尼克号姓名字段KMeans聚类优化方案
问题背景
基于Kaggle泰坦尼克号数据集的姓名字段完成KMeans聚类流程后,可视化结果存在文本点分散度不足、异常值干扰的问题,需优化聚类显著性与可视化可读性,让分析更具实际意义。
运行代码
import pandas as pd titanic = pd.read_csv('titanic.csv') titanic.head() # 导入依赖模块 from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.cluster import KMeans from sklearn.metrics import adjusted_rand_score documents = titanic['Name'] vectorizer = TfidfVectorizer(stop_words='english') X = vectorizer.fit_transform(documents) # 初始化并训练KMeans kmeans = KMeans(n_clusters=20, random_state=42) kmeans.fit(X) clusters = kmeans.labels_ titanic['kmeans'] = clusters titanic.tail() # PCA降维与可视化 from sklearn.decomposition import PCA vectorizer = TfidfVectorizer(stop_words='english') X = vectorizer.fit_transform(documents) pca = PCA(n_components=2, random_state=42) pca_vecs = pca.fit_transform(X.toarray()) titanic['cluster'] = clusters titanic['x0'] = pca_vecs[:, 0] titanic['x1'] = pca_vecs[:, 1] import plotly.express as px fig = px.scatter(titanic, x='x0', y='x1', color='kmeans', text='Name') fig.show()
当前可视化结果

优化方案
一、文本特征优化
- 拆分姓名关键信息:从姓名中提取头衔(Mr/Mrs/Miss等)、姓氏字段,减少冗余信息干扰。示例代码:
# 提取头衔 titanic['Title'] = titanic['Name'].str.extract(' ([A-Za-z]+)\.', expand=False) # 提取姓氏 titanic['Surname'] = titanic['Name'].str.split(',', expand=True)[0] # 合并头衔+姓氏作为聚类输入 documents = titanic['Title'] + ' ' + titanic['Surname'] - 调整TF-IDF参数:
- 设置
min_df=2过滤仅出现1次的低频噪声词; - 自定义停用词列表,添加姓名中无意义的通用前缀/后缀;
- 启用
ngram_range=(1,2),捕捉头衔+姓氏这类组合特征,提升区分度。
- 设置
二、聚类模型优化
- 确定最优聚类数:放弃固定20个聚类,用轮廓系数或肘部法则选择合理k值:
选择轮廓系数最高的k值,避免聚类过多/过少导致的重叠。from sklearn.metrics import silhouette_score import matplotlib.pyplot as plt silhouette_scores = [] for k in range(2, 15): kmeans = KMeans(n_clusters=k, random_state=42) labels = kmeans.fit_predict(X) silhouette_scores.append(silhouette_score(X, labels)) plt.plot(range(2,15), silhouette_scores) plt.xlabel('聚类数量') plt.ylabel('轮廓系数') plt.show() - 替换聚类算法:改用DBSCAN处理异常值,它能自动识别噪声点,适合文本类数据的聚类场景。
三、可视化优化
- 更换降维方法:PCA对高维文本降维效果有限,改用t-SNE或UMAP保留局部聚类结构,提升分散度:
from sklearn.manifold import TSNE tsne = TSNE(n_components=2, random_state=42, perplexity=30) tsne_vecs = tsne.fit_transform(X.toarray()) titanic['tsne_x'] = tsne_vecs[:,0] titanic['tsne_y'] = tsne_vecs[:,1] fig = px.scatter(titanic, x='tsne_x', y='tsne_y', color='kmeans', hover_data=['Name']) fig.show() - 优化文本显示:
- 用hover提示框替代全部文本标注,避免重叠;
- 调整点的透明度(
opacity=0.7)和大小(size_max=10); - 对异常值用特殊形状/颜色单独标记。
四、强化分析意义
- 关联业务字段:将聚类结果与生存率、舱位、年龄等字段结合,统计各聚类的平均生存率、舱位分布,挖掘姓名特征与生存概率的关联;
- 聚类标签解释:提取每个聚类中TF-IDF权重最高的词汇(如某聚类高频出现"Mrs"、"Brown"),给聚类赋予明确标签(如"已婚布朗家族成员"),提升分析可读性。
内容的提问来源于stack exchange,提问作者ASH
相关产品推荐
相关产品推荐

