数据科学【五】:聚类(一)
本文代码基于数据科学【四】:基本可视化(二) 。
Kmeans 聚类
示例:使用longitude
, latitude
, price
, number_of_reviews
四个特征对房产进行聚类,并将聚类在地图上可视化。不同聚类使用不同颜色显示。
from sklearn.cluster import KMeans
df_h = airbnb_df[['latitude', 'longitude', 'price','number_of_reviews']]
data_h = df_h.values
data_list = data_h.tolist()
kmeans_h = KMeans(n_clusters=5).fit(data_h)
labels_h = kmeans_h.labels_.tolist()
colors = ['red', 'blue', 'gray', 'green', 'purple']
map_nyc_h = folium.Map(nyc_base, zoom_start=8)
for i in range(len(labels_h)):
folium.CircleMarker([data_list[i][0], data_list[i][1]], color=colors[labels_h[i]]).add_to(map_nyc_h)
map_nyc_h.save("map_1h.html")
效果如图:
很诡异对吧,诡异就对了。因为相较于price和number_of_reviews,经纬度在不同数据之间的差距非常小,所以聚类基本上是按照经纬度均匀分布的,也就是在地图上混在一起。
聚类效果评价
聚类效果的评价指标可以使用sklearn的silhouette score评价。这个值越大,说明不同聚类之间分的越明显,效果越好。在KMeans聚类时有时我们不确定k为和值时效果最好,这时可以试验多个k值,取silhouette score最大的k值。
示例:对上文的四个特征进行聚类,看最佳k值
from sklearn import metrics
for cluster_num in range(2, 7):
kmeans_j = KMeans(cluster_num).fit(data_h)
labels_j = kmeans_j.labels_
print(metrics.silhouette_score(data_h, labels_j))
0.9777638276553681
0.8463525243386326
0.7289984978753536
0.5977807377876659
0.5978460763136394
很明显,最佳k值是2。
层次聚类可视化:树状图
我们可以使用树状图(dendrogram)来可视化层次聚类的过程。
示例:对于标签为shared_room的房产,使用树状图可视化基于经纬度以及价格的层次聚类:
注意:由于层次聚类可视化需要获得数据之间的“距离”,我们需要先计算距离矩阵,使用distance.pdist()
。
df_l = airbnb_df[airbnb_df.room_type=='Shared room'][['longitude', 'latitude','price']]
data_l = df_l.values
from scipy.cluster.hierarchy import linkage, dendrogram, distance
disMat_l =distance.pdist(data_l, 'euclidean')
plt.figure(figsize=(20, 8), dpi=80)
Z_l = linkage(disMat_l)
P_l = dendrogram(Z_l, 0)
plt.show()
示例:将数据正则化之后可视化:
df_n = df_l
df_n['price'] = (df_n['price'] - df_n['price'].mean())/df_n['price'].std()
data_n = df_n.values
disMat_n =distance.pdist(data_n, 'euclidean')
plt.figure(figsize=(20, 8), dpi=80)
Z_n = linkage(disMat_n)
P_n = dendrogram(Z_n, 0)
plt.show()