基于Sklearn的WiFi信号强度数据亲和传播聚类实现问询
用Scikit-learn实现WiFi信号强度网格点的亲和传播聚类
当然可以用scikit-learn实现这个需求!你的场景完全契合亲和传播聚类的核心逻辑——基于样本间的相似度(这里就是不同网格点的WiFi信号强度相似性)自动发现聚类中心,不需要提前指定聚类数量,非常适合你的网格点信号聚类场景。
下面是适配你数据集的完整代码示例和关键说明:
1. 数据准备
你的数据集核心是:每个网格点作为一个样本,每个样本的特征是各个WiFi接入点的信号强度值(比如有5个WiFi,特征就是[RSSI_AP1, RSSI_AP2, RSSI_AP3, RSSI_AP4, RSSI_AP5])。
首先需要把数据整理成scikit-learn要求的二维数组格式:(n_samples, n_features),其中:
n_samples:网格点的总数量n_features:WiFi接入点的数量
假设你的数据存储在CSV文件中,格式如下(第一列是网格点坐标,后面列是各个WiFi的信号强度):
x,y,RSSI1,RSSI2,RSSI3 0.5,0.6,-52,-60,-75 1.2,0.8,-55,-58,-72 ...
可以用pandas加载并提取特征:
import pandas as pd from sklearn.cluster import AffinityPropagation from sklearn import metrics # 加载数据集 df = pd.read_csv("wifi_grid_data.csv") # 提取信号强度作为特征(跳过x、y坐标列) X = df[["RSSI1", "RSSI2", "RSSI3"]].values
2. 适配亲和传播聚类
直接修改sklearn的示例代码,适配你的特征数据即可。这里需要重点关注preference参数——它决定了聚类中心的数量:值越小,聚类数量越少;值越大,聚类数量越多。你可以根据数据的相似度分布调整,比如设为样本间相似度的中位数:
# 初始化并训练亲和传播模型 # 可选:计算样本间相似度的中位数来设置preference,更适配你的数据 from sklearn.metrics.pairwise import euclidean_distances similarity = -euclidean_distances(X) # 亲和传播用负距离作为相似度 preference = similarity.flatten().median() af = AffinityPropagation(preference=preference, random_state=0).fit(X) # 获取聚类结果 cluster_centers_indices = af.cluster_centers_indices_ labels = af.labels_ n_clusters_ = len(cluster_centers_indices) print(f"自动发现的聚类数量: {n_clusters_}")
3. 结果分析与可视化
你可以把聚类结果和网格点坐标结合,可视化不同聚类的分布:
import matplotlib.pyplot as plt # 绘制每个聚类的网格点 plt.figure(figsize=(10, 8)) colors = plt.cm.get_cmap('viridis', n_clusters_) for k, col in zip(range(n_clusters_), colors): class_members = labels == k cluster_center = X[cluster_centers_indices[k]] # 绘制聚类内的网格点 plt.scatter(df.loc[class_members, "x"], df.loc[class_members, "y"], c=[col], marker='o', s=50, label=f"Cluster {k+1}") # 绘制聚类中心(用更大的点标记) plt.scatter(df.loc[cluster_centers_indices[k], "x"], df.loc[cluster_centers_indices[k], "y"], c=[col], marker='s', s=200, edgecolors='k') plt.title(f"WiFi信号强度网格点的亲和传播聚类 (共{n_clusters_}个聚类)") plt.xlabel("X坐标") plt.ylabel("Y坐标") plt.legend() plt.show()
4. 关键注意事项
- 缺失值处理:如果某些网格点的WiFi信号强度有缺失(比如无信号),需要先处理:可以用同WiFi的平均信号强度填充,或者删除缺失严重的样本。
- 相似度度量:默认用欧氏距离的负值作为相似度,你也可以根据需求换成其他相似度(比如余弦相似度),只需要自定义相似度矩阵传入
affinity='precomputed'参数即可。 - 聚类数量调整:如果自动生成的聚类数量不符合预期,直接调整
preference参数即可——比如想减少聚类数,就减小preference的值;想增加就增大。
内容的提问来源于stack exchange,提问作者santobedi




