brown cluster

本文介绍了一种用于自然语言处理领域的单词聚类算法——BrownClustering,并探讨了其背后的原理及实现代码的学习过程。同时,文章还讨论了全局线性模型的相关概念。
import pandas as pd import numpy as np from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler from sklearn.metrics import silhouette_score import matplotlib.pyplot as plt import warnings warnings.filterwarnings('ignore') # 1. 读取Excel文件 file_name = "../数模1/工作簿4.xlsx" try: # 读取Excel文件 df = pd.read_excel(file_name, sheet_name='Sheet1') print(f"成功读取Excel文件: {file_name}") print(f"数据形状: {df.shape}") # 显示前几行数据 print("\n数据前5行:") print(df.head()) except FileNotFoundError: print(f"错误: 找不到文件 '{file_name}'") print("请确保Excel文件与Python脚本在同一目录下") exit() # 2. 数据预处理 if '孕妇BMI' not in df.columns: print("错误: 数据中未找到'孕妇BMI'列") print("可用列:", df.columns.tolist()) exit() # 处理缺失值 print(f"\nBMI列缺失值数量: {df['孕妇BMI'].isnull().sum()}") df_clean = df.dropna(subset=['孕妇BMI']).copy() # 3. 删除重复的BMI值 print(f"原始数据中BMI值数量: {len(df_clean['孕妇BMI'])}") print(f"唯一BMI值数量: {df_clean['孕妇BMI'].nunique()}") # 创建只包含唯一BMI值的数据集 unique_bmi_df = df_clean.drop_duplicates(subset=['孕妇BMI']).copy() print(f"删除重复BMI值后剩余样本数: {len(unique_bmi_df)}") # 4. 确定最佳K值(使用肘部法则和轮廓系数) bmi_data = unique_bmi_df['孕妇BMI'].values.reshape(-1, 1) sse = {} silhouette_scores = [] k_range = range(2, 11) # 测试2到10个聚类 print("\n正在计算最佳聚类数量...") for k in k_range: kmeans = KMeans(n_clusters=k, init='k-means++', random_state=42, n_init=10) kmeans.fit(bmi_data) sse[k] = kmeans.inertia_ # SSE(Sum of Squared Errors) # 计算轮廓系数(需要至少2个聚类) if k > 1: silhouette_avg = silhouette_score(bmi_data, kmeans.labels_) silhouette_scores.append(silhouette_avg) else: silhouette_scores.append(0) # 绘制肘部法则图和轮廓系数图 plt.figure(figsize=(12, 5)) plt.subplot(1, 2, 1) plt.plot(list(sse.keys()), list(sse.values()), 'bx-') plt.xlabel('聚类数量 (k)') plt.ylabel('SSE (误差平方和)') plt.title('肘部法则 - 最佳k值') plt.subplot(1, 2, 2) plt.plot(range(2, 11), silhouette_scores, 'bx-') plt.xlabel('聚类数量 (k)') plt.ylabel('轮廓系数') plt.title('轮廓系数 - 最佳k值') plt.tight_layout() plt.savefig('bmi_clustering_analysis.png') # 保存图像 plt.show() # 基于轮廓系数选择最佳K值 optimal_k = np.argmax(silhouette_scores) + 2 # +2是因为我们从k=2开始 print(f"\n基于轮廓系数的最佳聚类数量: {optimal_k}") # 5. 使用K-means++进行聚类 kmeans = KMeans(n_clusters=optimal_k, init='k-means++', random_state=42, n_init=10) kmeans.fit(bmi_data) # 将聚类结果添加到唯一BMI数据集 unique_bmi_df['BMI_Cluster'] = kmeans.labels_ # 6. 将聚类结果映射回原始数据 # 创建一个BMI到聚类的映射字典 bmi_cluster_map = dict(zip(unique_bmi_df['孕妇BMI'], unique_bmi_df['BMI_Cluster'])) # 将映射应用到原始数据 df_clean['BMI_Cluster'] = df_clean['孕妇BMI'].map(bmi_cluster_map) # 7. 分析聚类结果 cluster_summary = unique_bmi_df.groupby('BMI_Cluster')['孕妇BMI'].agg([ ('最小值', 'min'), ('最大值', 'max'), ('平均值', 'mean'), ('样本数', 'count') ]).round(2) print("\n聚类摘要 (基于唯一BMI值):") print(cluster_summary) # 8. 可视化聚类结果 plt.figure(figsize=(12, 6)) # 绘制BMI分布直方图,按聚类着色 colors = ['red', 'blue', 'green', 'purple', 'orange', 'brown', 'pink', 'gray', 'olive', 'cyan'] for i in range(optimal_k): cluster_data = unique_bmi_df[unique_bmi_df['BMI_Cluster'] == i]['孕妇BMI'] plt.hist(cluster_data, bins=30, alpha=0.6, color=colors[i % len(colors)], label=f'聚类 {i} (n={len(cluster_data)})') # 添加WHO BMI分类标准线 plt.axvline(x=18.5, color='black', linestyle='--', label='偏瘦 (WHO)') plt.axvline(x=25, color='black', linestyle='--', label='正常 (WHO)') plt.axvline(x=30, color='black', linestyle='--', label='超重 (WHO)') plt.axvline(x=35, color='black', linestyle='--', label='肥胖 I级 (WHO)') plt.axvline(x=40, color='black', linestyle='--', label='肥胖 II级 (WHO)') plt.xlabel('BMI') plt.ylabel('频数') plt.title('BMI分布 - 按聚类着色 (基于唯一BMI值)') plt.legend() plt.grid(True, alpha=0.3) plt.savefig('bmi_cluster_distribution.png') # 保存图像 plt.show() # 9. 保存结果到新Excel文件 output_file = "bmi_clustering_results.xlsx" with pd.ExcelWriter(output_file) as writer: df_clean.to_excel(writer, sheet_name='聚类结果', index=False) cluster_summary.to_excel(writer, sheet_name='聚类摘要') print(f"\n结果已保存到: {output_file}") # 10. 打印每个聚类的详细描述 print("\n=== BMI聚类分组结果 ===") for i in range(optimal_k): cluster_data = unique_bmi_df[unique_bmi_df['BMI_Cluster'] == i]['孕妇BMI'] min_bmi = cluster_data.min() max_bmi = cluster_data.max() mean_bmi = cluster_data.mean() count = len(cluster_data) # 根据WHO标准确定分类 if mean_bmi < 18.5: category = "偏瘦" elif mean_bmi < 25: category = "正常" elif mean_bmi < 30: category = "超重" elif mean_bmi < 35: category = "肥胖 I级" elif mean_bmi < 40: category = "肥胖 II级" else: category = "肥胖 III级" print(f"聚类 {i}: BMI范围 {min_bmi:.1f}-{max_bmi:.1f}, 平均 {mean_bmi:.1f} ({category}), 样本数: {count}") # 11. 显示原始数据中每个聚类的样本数量 print("\n=== 原始数据中各聚类样本数量 ===") original_cluster_counts = df_clean['BMI_Cluster'].value_counts().sort_index() for cluster, count in original_cluster_counts.items(): print(f"聚类 {cluster}: {count} 个样本") 这个聚类结果还可以再精确一些吗,代码有没有别的选择
最新发布
09-07
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值