day07-means算法(上)

本文主要介绍了Means算法的基础概念,包括其工作原理、步骤及适用场景。首先,我们探讨了Means算法如何通过计算数据点与聚类中心之间的距离来划分类别。接着,详细解释了初始化聚类中心的方法和迭代过程,强调了在每次迭代中如何更新聚类中心。文章还讨论了Means算法的优点和局限性,如对初始中心敏感、处理非凸形状簇的困难等。此外,文中通过实例展示了Means算法在实际数据集上的应用。
day07-k_means算法自实现

01-数据转化
import pandas as pd
import numpy as np

# 将非数值型类别型数据转化为数值型
# 哑变量转化---将数据转化为哑变量矩阵
# 加载数据
data = pd.read_excel('./meal_order_detail.xlsx')
# print('data:\n',data)
# print('data的列索引:\n',data.columns)
# print('data :\n', data.loc[:, "dishes_name"])
print('data :\n', data.loc[:, "amounts"])
print('data 中amounts列的最大值:', data.loc[:, "amounts"].max())
print('data 中amounts列的最小值:', data.loc[:, "amounts"].min())
print('*' * 100)
#
# # 将detail 中的 dishes_name 进行哑变量转化
# res = pd.get_dummies(
#     data=data.loc[:, 'dishes_name'],  # 数据
#     prefix='菜品',  # 前缀
#     prefix_sep=':'  # 连接符
# )
# print('哑变量之后的结果:\n', res)

# 将连续型数据离散成类别数据 ---数据离散化
# 将连续的数据进行划分区间
# 将 detail 中 amounts单价列进行离散化
# 1、默认进行分组
# 2、自定义等宽分组
# # (1)确定分组个数
# group_num = 5
# # (2)确定极差
# # 确定最大值
# max_amounts = data.loc[:, "amounts"].max()
# # 确定最小值
# min_amounts = data.loc[:, "amounts"].min()
# # 确定极差
# ptp = max_amounts - min_amounts
# # (3)确定步长
# step = int(np.ceil(ptp / group_num))
# # (4)确定bins
# bins = np.arange(min_amounts, max_amounts + step, step)
# print('自定义等宽分组:', bins)

# 3、自定义等频分组 --利用分位数进行分组
# (1)确定分组个数
group_num = 5
# (2)确定bins
bins = data.loc[:, 'amounts'].quantile(q=np.arange(0, 1 + 1 / group_num, 1 / group_num))
# [0,0.2,0.4,0.6,0.8,1.0]
print('bins:', bins)
data.loc[:, 'amounts'] = pd.cut(
    x=data.loc[
# 代码概述 你希望使用 **PyCharm** 对 **397天客流量数据** 应用 **K-means 聚类算法**。以下是一套**标准、完整、可直接运行的 Python 代码**,包含数据加载、预处理、聚类分析与可视化全过程。 --- # 代码解析 ```python # -*- coding: utf-8 -*- """ 在 PyCharm 中对 397 天客流量数据应用 K-means 算法的标准脚本 步骤:1. 加载数据 → 2. 数据清洗 → 3. 标准化 → 4. K-means 聚类 → 5. 可视化结果 """ import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler from sklearn.metrics import silhouette_score import os # === 1. 配置路径(推荐将 CSV 文件放在项目根目录下)=== file_name = "shujuxinxi.csv" # 假设你的文件名为 shujuxinxi.csv,含一列 'traffic' current_dir = os.path.dirname(__file__) if "__file__" in locals() else os.getcwd() file_path = os.path.join(current_dir, file_name) print(f"🔍 正在查找数据文件:{file_path}") # === 2. 安全读取数据并验证格式 === try: if not os.path.exists(file_path): raise FileNotFoundError(f"文件未找到!请确认 '{file_name}' 是否位于:\n{current_dir}") df = pd.read_csv(file_path) # 检查是否至少有一列用于分析 if df.shape[1] == 0: raise ValueError("CSV 文件为空,无任何数据") # 假设你要聚类的列为 'traffic';若不同,请替换为实际列名如 '客流' 或 'volume' column_name = "traffic" if column_name not in df.columns: print(f"⚠️ 未找到列 '{column_name}',现有列:{list(df.columns)}") column_name = df.columns[0] # 自动取第一列为默认 print(f"👉 将使用第一列 '{column_name}' 进行聚类") X = df[[column_name]].astype(float) # 确保是数值型 print(f"✅ 成功加载 {len(X)} 天数据,列名:'{column_name}'") except Exception as e: print("❌ 错误发生:", str(e)) print("\n💡 解决方案:") print("1. 把 shujuxinxi.csv 放到 PyCharm 项目的根目录") print("2. 文件应为 UTF-8 编码,首行为列名(如 traffic)") print("3. 第二行起为数字,例如:") print(" traffic\n 120\n 135\n ...") exit() # === 3. 数据标准化(K-means 对量纲敏感)=== scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # === 4. 确定最优聚类数 k(肘部法则 + 轮廓系数)=== k_range = range(2, 8) inertias = [] silhouettes = [] for k in k_range: kmeans = KMeans(n_clusters=k, random_state=42, n_init=10) kmeans.fit(X_scaled) inertias.append(kmeans.inertia_) silhouettes.append(silhouette_score(X_scaled, kmeans.labels_)) # 绘制肘部图和轮廓系数图 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5)) ax1.plot(k_range, inertias, marker='o', color='blue') ax1.set_title("Elbow Method") ax1.set_xlabel("Number of Clusters (k)") ax1.set_ylabel("Inertia") ax1.grid(True, alpha=0.3) ax2.plot(k_range, silhouettes, marker='s', color='green') ax2.set_title("Silhouette Score") ax2.set_xlabel("Number of Clusters (k)") ax2.set_ylabel("Silhouette Score") ax2.grid(True, alpha=0.3) plt.tight_layout() plt.show() # 推荐最优 k(取轮廓系数最大值对应的 k) optimal_k = k_range[np.argmax(silhouettes)] print(f"\n🎯 推荐最优聚类数:k = {optimal_k}(基于最高轮廓系数)") # === 5. 使用最优 k 进行最终聚类 === final_kmeans = KMeans(n_clusters=optimal_k, random_state=42, n_init=10) labels = final_kmeans.fit_predict(X_scaled) centers_original = scaler.inverse_transform(final_kmeans.cluster_centers_) # 转回原始尺度 df['cluster'] = labels print(f"\n📊 聚类结果(前10条):") print(df.head(10)) # 输出每类统计信息 print(f"\n📋 各类别中心值(原始尺度):") for i in range(optimal_k): count = sum(labels == i) center = centers_original[i][0] print(f" 类别 {i}: 中心 = {center:.2f}, 数量 = {count} 天") # === 6. 可视化聚类结果 === plt.figure(figsize=(12, 6)) colors = plt.cm.get_cmap('tab10', optimal_k) for i in range(optimal_k): cluster_data = X[labels == i] plt.scatter(cluster_data.index, cluster_data.values.flatten(), label=f'Cluster {i}', color=colors(i), alpha=0.7, s=60) # 绘制聚类中心线(按时间平均分布) time_center = np.mean(np.arange(len(X))) for i in range(optimal_k): plt.hlines(centers_original[i], 0, len(X), colors=colors(i), linestyles='--', alpha=0.7) plt.title(f"397 Days Customer Traffic Clustering (K={optimal_k})") plt.xlabel("Day Index") plt.ylabel("Traffic Volume") plt.legend() plt.grid(True, axis='y', alpha=0.3) plt.tight_layout() plt.show() ``` --- # 知识点(列出该代码中遇到的知识点) 1. **K-means 算法原理与适用性** 基于距离划分簇,适用于连续型数据聚类,需提前确定 $k$ 值。 2. **数据标准化必要性** 使用 $StandardScaler$ 消除量纲影响,避免某特征主导聚类结果。 3. **最优聚类数选择方法** 结合“肘部法则”与“轮廓系数”评估,提升聚类质量与解释性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值