在坐标和非空间特征上对地理空间数据进行聚类

2024-02-22

假设我将以下数据帧存储为称为坐标的变量,其中前几行如下所示:

   business_lat  business_lng  business_rating
0   19.111841     72.910729           5.
1   19.111342     72.908387           5.
2   19.111342     72.908387           4.
3   19.137815     72.914085           5.
4   19.119677     72.905081           2.
5   19.119677     72.905081           2.
        .             .               .
        .             .               .
        .             .               .

正如您所看到的,此数据是地理空间数据(具有纬度和经度),并且每行都有一个附加值business_ rating,它对应于该行中经纬度处的企业评级。我想对数据进行聚类,其中附近且具有相似评级的企业被分配到同一个集群中。本质上,我需要一个地理空间集群,并附加要求集群必须考虑评级列。

我在网上查看过,但找不到太多解决此问题的方法:只有严格的地理空间聚类(只有要聚类的特征是 latlng)或非空间聚类。

我在下面运行了一个简单的 DBSCAN,但是当我绘制聚类结果时,它似乎没有正确执行我想要的操作。

from sklearn.cluster import DBSCAN
import numpy as np
db = DBSCAN(eps=2/6371., min_samples=5, algorithm='ball_tree', metric='haversine').fit(np.radians(coordinates))

尝试调整 DBSCAN 的参数、对数据进行一些额外的处理或同时使用不同的方法是否会更好?


对两种不同类型的信息(位置和评级)进行聚类的棘手部分是确定它们应如何相互关联。当它只是一个域并且您正在比较相同的单位时,询问很简单。我的方法是研究如何关联域内的行,然后确定域之间的某些交互。这可以使用提到的 MinMaxScaler 之类的缩放选项来完成,但是,我认为这有点笨拙,我们可以利用我们的领域知识来更好地进行聚类。

处理地点

位置距离最好直接处理,因为这具有现实世界的意义,我们可以预先计算距离。相距米的含义直接与我们的意思有关

您可以使用上一个答案中提到的缩放选项,但这可能会扭曲位置数据。例如,如果您有一组又长又细的位置,则 MinMaxScaling 会更重视细轴上的变化而不是长轴上的变化。如果要使用缩放,请在计算的距离矩阵上进行,而不是在纬度本身上进行。

import numpy as np
from sklearn.metrics.pairwise import haversine_distances


points_in_radians = df[['business_lat','business_lng']].apply(np.radians).values
distances_in_km = haversine_distances(points_in_radians) * 6371

添加评级

我们可以通过提出几个将评级与距离相关的问题来思考这个问题。我们可能会问,同一地点的不同观察结果的评级必须有多大差异?米差与额定差之比是多少?有了比率的概念,我们可以计算所有观测值的评级差异的另一个距离矩阵,并使用它来缩放或添加到原始位置距离矩阵,或者我们可以增加评级中每个差距的距离。然后可以对该位置加评级差异矩阵进行聚类。

from sklearn.metrics.pairwise import euclidean_distances

added_km_per_rating_gap = 1
rating_distances = euclidean_distances(df[['business_rating']].values) * added_km_per_rating_gap 

然后我们可以简单地将它们加在一起并在结果矩阵上进行聚类。

from sklearn.cluster import DBSCAN

distance_matrix = rating_distances + distances_in_km

clustering = DBSCAN(metric='precomputed', eps=1, min_samples=2)
clustering.fit(distance_matrix)

我们所做的是按位置进行聚类,并针对评分差异添加惩罚。使该惩罚直接且可控,可以进行优化以找到最佳聚类。

Testing

我发现的问题是(至少在我的测试数据中)DBSCAN 倾向于从一个观察“行走”到另一个观察,形成集群,这些集群要么因为惩罚不够高而将评级混合在一起,要么分成单个评级组。 DBSCAN 可能不适合这种类型的聚类。如果我有更多时间,我会寻找一些开放数据来测试它并尝试其他聚类方法。

这是我用来测试的代码。我使用评级距离的平方来强调更大的差距。

import random
from sklearn.datasets import make_blobs


X, y = make_blobs(n_samples=300, centers=6, cluster_std=0.60, random_state=0)
ratings = np.array([random.randint(1,4) for _ in range(len(X)//2)] \
          +[random.randint(2,5) for _ in range(len(X)//2)]).reshape(-1, 1)

distances_in_km = euclidean_distances(X)
rating_distances = euclidean_distances(ratings)


def build_clusters(multiplier, eps):
    rating_addition = (rating_distances ** 2) * multiplier
    distance_matrix = rating_addition + distances_in_km
    clustering = DBSCAN(metric='precomputed', eps=eps, min_samples=10)
    clustering.fit(distance_matrix)
    return clustering.labels_
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在坐标和非空间特征上对地理空间数据进行聚类 的相关文章

随机推荐