У меня есть реализация K-средних, которая возвращает кластеры. Указанный кластер предназначен для тесселяции города. Что меня интересует, так это получить границу каждого кластера, ячеек Вороного. Мой код выглядит следующим образом:
class K_Means:
def __init__(self, k=2, tol=0.001, max_iter=300):
self.k = k
self.tol = tol
self.max_iter = max_iter
def fit(self,data):
self.centroids = {}
for i in range(self.k):
self.centroids[i] = data[i]
for i in range(self.max_iter):
self.classifications = {}
for i in range(self.k):
self.classifications[i] = []
for featureset in data:
distances = [np.linalg.norm(featureset-self.centroids[centroid]) for centroid in self.centroids]
classification = distances.index(min(distances))
self.classifications[classification].append(featureset)
prev_centroids = dict(self.centroids)
for classification in self.classifications:
self.centroids[classification] = np.average(self.classifications[classification],axis=0)
optimized = True
for c in self.centroids:
original_centroid = prev_centroids[c]
current_centroid = self.centroids[c]
if np.sum((current_centroid-original_centroid)/original_centroid*100.0) > self.tol:
print(np.sum((current_centroid-original_centroid)/original_centroid*100.0))
optimized = False
if optimized:
break
def predict(self,data):
distances = [np.linalg.norm(data-self.centroids[centroid]) for centroid in self.centroids]
classification = distances.index(min(distances))
return classification
X = df[['order_latitude', 'order_longitude']].to_numpy()
# plt.scatter(*zip(*X))
model = K_Means()
model.fit(X)
И мой фрейм данных вроде этого:
order_latitude order_longitude
0 38.3477022 -0.4927108
1 38.3624854 -0.4809995
2 38.3416865 -0.5005017
3 38.347822 -0.4882809
4 38.3511359 -0.4866966
5 38.3603331 -0.4869405
6 38.3433719 -0.4964212
7 38.3507314 -0.5098433
8 38.3576242 -0.4829199
9 38.3624383 -0.4878071
10 38.3511359 -0.4866966
Я правильно создаю кластер, но не могу создать границы. Я не могу использовать библиотеку для k-средних, поскольку, хотя мой пример показывает обычную норму, в реальном мне нужно использовать расстояния, не реализованные ни в одной из известных мне библиотек (время в пути между узлами). Я пробовал использовать scipy Voronoi, но данные по географии скудны, это не однозначно. Другие связанные вопросы, такие как Рисование граничных линий на основе центров кластеров kmeans , имеют многообещающий ответ, но опять же, я не могу уместить свой собственный metri c, и он группируется нежелательным образом.