多属性城市数据聚类算法选型及Python快速实现咨询
城市属性数据集的最优聚类方案与Python实现
一、最优聚类算法选择
针对你的场景(10000个城市、10类混合属性,需求是属性相似性聚类),K-means是最优选择,原因如下:
- 效率适配:K-means时间复杂度为O(nkt)(n为样本数,k为簇数,t为迭代次数),处理10000级别的样本速度远快于层次聚类(O(n²),10000样本会极慢)。
- 需求匹配:你的核心需求是基于属性数值的相似性分组,K-means通过最小化簇内平方和的方式,正好贴合“属性整体相似的城市归为一簇”的目标。
- 混合属性兼容:只要提前做好数据标准化,就能同时处理0-1型比例属性和数值型计数属性。
排除其他算法的理由:
- 层次聚类:仅适合小样本数据集,10000个样本的计算成本极高,不适用。
- 空间聚类:仅针对包含空间坐标(经纬度)的数据集,你的数据无空间信息,完全不匹配。
- DBSCAN:适合密度聚类(识别异常点、任意形状簇),但你的需求是常规的相似性分组,K-means更直接高效。
二、Python快速实现步骤
1. 数据预处理(关键步骤)
由于你的属性存在两种数值范围(0-1的比例值、几十/几百的计数值),必须先做标准化处理,避免大数值属性主导距离计算。
2. 完整代码实现
import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score import matplotlib.pyplot as plt # 加载数据(用你提供的示例数据) columns = ['city_id', 'attribute1', 'attribute2', 'attribute3', 'attribute4', 'attribute5', 'attribute6', 'attribute7', 'attribute8', 'attribute9'] data = [[0, 20, 45, 0.15, 0.04, 12, 1, 2, 10, 0.02], [1, 12, 35, 0.12, 0.03, 10, 0, 4, 5, 0.04], [2, 14, 28, 0.09, 0.01, 8, 1, 5, 4, 0.05], [3, 5, 17, 0.08, 0.02, 6, 1, 10, 3, 0.01], [4, 35, 36, 0.04, 0.02, 5, 1, 3, 15, 0.035], [5, 2, 12, 0.13, 0.04, 7, 0, 4, 13, 0.044], [6, 23, 52, 0.19, 0.04, 14, 0, 5, 9, 0.057], [7, 42, 29, 0.04, 0.05, 9, 1, 2, 7, 0.024], [8, 9, 34, 0.21, 0.07, 10, 1, 6, 15, 0.017], [9, 4, 41, 0.22, 0.03, 2, 0, 8, 11, 0.065]] df = pd.DataFrame(data, columns=columns) # 分离特征与标识(city_id不参与聚类) X = df.drop('city_id', axis=1) # 标准化特征 scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # 用肘部法则确定最优簇数k inertias = [] k_range = range(2, 10) for k in k_range: kmeans = KMeans(n_clusters=k, random_state=42) kmeans.fit(X_scaled) inertias.append(kmeans.inertia_) plt.plot(k_range, inertias, 'bo-') plt.xlabel('簇数k') plt.ylabel('簇内平方和') plt.title('肘部法则确定最优k') plt.show() # 训练K-means模型(假设根据肘部法则选k=3) kmeans = KMeans(n_clusters=3, random_state=42) df['cluster_label'] = kmeans.fit_predict(X_scaled) # 评估聚类效果(轮廓系数,取值[-1,1],越接近1聚类效果越好) sil_score = silhouette_score(X_scaled, df['cluster_label']) print(f"聚类轮廓系数: {sil_score:.3f}") # 查看每个簇的属性统计,验证簇内相似性 cluster_stats = df.groupby('cluster_label').mean() print("\n各簇属性均值统计:") print(cluster_stats)
3. 关键说明
- 标准化:这里用
StandardScaler将所有特征转换为均值0、标准差1的分布,确保不同范围的属性权重一致;如果偏好0-1范围,也可以替换为MinMaxScaler。 - 簇数选择:肘部法则中,曲线的“拐点”对应的k就是最优值(比如图中k=3时曲线开始平缓,就选3);轮廓系数是辅助判断聚类质量的指标。
- 结果验证:通过
groupby查看每个簇的属性均值,可以直观验证簇内城市的属性是否具有相似性。
内容的提问来源于stack exchange,提问作者ctrl_z
相关产品推荐
相关产品推荐

