1

我有一个交付应用程序,我想按位置接近度(线性距离)和限制(例如最大订单和最大总产品(每个订单都有一定数量的产品))对订单进行分组(每个订单都有一个纬度和经度坐标) .

对于邻近分组,我使用 DBSCAN

coordinates = [[lat,lng],[lat,lng]],[lat,lng]],[lat,lng]],[lat,lng]]]
distance_matrix = squareform(pdist(coordinates, (lambda u,v: haversine(u,v))))

#eps=0.1 => 100m radius, 50m linear
db = DBSCAN(eps=0.1, min_samples=2, metric='precomputed')
results = db.fit(distance_matrix)

如何在此功能中添加约束?

有没有办法通过使用 DBSCAN 或 HDBSCAN 以外的东西来做到这一点?

4

2 回答 2

1

这是个有趣的问题。我想它可以通过很多不同的方式来完成。这是您考虑的一种解决方案。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
import seaborn as sns; sns.set()
import csv


df = pd.read_csv('C:\\your_path\\properties_2017.csv')
# df.head(10)
df = df.head(10000)

df.shape


df.dropna(axis=0,how='any',subset=['latitude','longitude'],inplace=True)

# Variable with the Longitude and Latitude
X=df.loc[:,['parcelid','latitude','longitude']]
X.head(10)

K_clusters = range(1,10)
kmeans = [KMeans(n_clusters=i) 

for i in K_clusters]
Y_axis = df[['latitude']]
X_axis = df[['longitude']]
score = [kmeans[i].fit(Y_axis).score(Y_axis)

for i in range(len(kmeans))] # Visualize
plt.plot(K_clusters, score)
plt.xlabel('Number of Clusters')
plt.ylabel('Score')
plt.title('Elbow Curve')
plt.show()

在此处输入图像描述

kmeans = KMeans(n_clusters = 10, init ='k-means++')
kmeans.fit(X[X.columns[1:3]]) # Compute k-means clustering.X['cluster_label'] = kmeans.fit_predict(X[X.columns[1:3]])centers = kmeans.cluster_centers_ # Coordinates of cluster centers.labels = kmeans.predict(X[X.columns[1:3]]) # Labels of each pointX.head(10)

X['cluster_label'] = kmeans.fit_predict(X[X.columns[1:3]])
centers = kmeans.cluster_centers_ # Coordinates of cluster centers.
labels = kmeans.predict(X[X.columns[1:3]]) # Labels of each pointX.head(10)

X.head(5)

X = X[['parcelid','cluster_label']]
X.head(5)


clustered_data = df.merge(X, left_on='parcelid', right_on='parcelid')
clustered_data.head(5)

centers = kmeans.cluster_centers_
print(centers)


X=df.loc[:,['parcelid','latitude','longitude']]
X.plot.scatter(x = 'latitude', y = 'longitude', c=labels, s=50, cmap='viridis')
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.5)

在此处输入图像描述
数据 = X 标签 = kmeans.labels_

plt.subplots_adjust(bottom = 0.1)
plt.scatter(data.iloc[:, 1], data.iloc[:, 2], c=kmeans.labels_, cmap='rainbow') 

for label, x, y in zip(labels, data.iloc[:, 1], data.iloc[:, 2]):
    plt.annotate(
        label,
        xy=(x, y), xytext=(-20, 20),
        textcoords='offset points', ha='right', va='bottom',
        bbox=dict(boxstyle='round,pad=0.5', fc='red', alpha=0.5),
        arrowprops=dict(arrowstyle = '->', connectionstyle='arc3,rad=0'))

plt.show()

# labels pointing to each data point (this is a big jumbled together; you should probably select fewer data points to analyze).

在此处输入图像描述

参考:

https://levelup.gitconnected.com/clustering-gps-co-ordinates-forming-regions-4f50caa7e4a1

数据源:

https://www.kaggle.com/c/zillow-prize-1/data

于 2020-04-08T02:15:07.980 回答
0

不幸的是,我认为您想要的模型应该从头开始开发。

您的问题可以建模为以下优化模型。

目标函数:最小化簇数,K约束(1)每个簇的大小等于或小于S(参数)(2)每个簇的阶数等于或小于O(参数)(3)对于样本 x 及其簇 Ck,dist(x, Ck) 是 dist(x, C1), dist(x, C2), ..., dist(x, CK) 中的最小值。

解决这个问题需要很多努力...

于 2020-04-07T05:24:35.893 回答