Найти 10 ближайших точек в порядке убывания
Я пытаюсь найти расстояние между точкой и другими 40000 точек.
Каждая точка - это 300-мерный вектор.
Я могу найти точку закрытия. Как мне найти 10 ближайших точек в порядке убывания?
Функция для ближайшей точки:
from scipy.spatial import distance
def closest_node(node,df):
closest_index = distance.cdist([node],df.feature.tolist()).argmin()
return pd.Series([df.title.tolist([closest_index],df.id.tolist()[closest_index]])
Эта команда возвращает ближайший заголовок и идентификатор:
df3[["closest_title","closest_id"]]=df3.feature.apply(lambda row: closest_node(row,df2))
df2- pandas dataframe of 40,000 points (each 300 dimension)
Как мне вернуть заголовок и индекс для 10 ближайших пунктов
Спасибо
2 ответа
Просто нарежьте отсортированную матрицу расстояний для 10 верхних узлов. Что-то вроде этого:
from scipy.spatial import distance
# Find the query node
query_node = df.iloc[10] ## Not sure what you're looking for
# Find the distance between this node and everyone else
euclidean_distances = df.apply(lambda row: distance.euclidean(row, query_node), axis=1)
# Create a new dataframe with distances.
distance_frame = pandas.DataFrame(data={"dist": euclidean_distances, "idx": euclidean_distances.index})
distance_frame.sort("dist", inplace=True)
# nodes
smallest_dist_ixs = distance_frame.iloc[1:10]["idx"]
most_similar_nodes = df.iloc[int(smallest_dist_ixs)]
Мое предположение, основанное на слове "заголовок", которое вы здесь использовали, и выбор 300 размерных векторов заключается в том, что это векторы слов или фраз.
Gensim на самом деле имеет способ получить N лучших похожих слов, основываясь на этой идее, что достаточно быстро.
https://tedboy.github.io/nlps/generated/generated/gensim.models.Word2Vec.most_similar.html
>>> trained_model.most_similar(positive=['woman', 'king'], negative=['man'])
[('queen', 0.50882536), ...]
Для чего-то немного отличающегося, это также немного похоже на задачу коммивояжера (TSP), если вы хотите получить кратчайшие пути между всеми точками, а затем просто выделить первые 10 "городов".
Google имеет довольно простую и быструю реализацию Python с OR-Tools здесь: https://developers.google.com/optimization/routing/tsp.
Поскольку я не знаю, какой у вас полный код образца данных, вот мое предложение:
Вместо использования ".argmin()" просто отсортируйте список по расстоянию, а затем верните первые десять элементов отсортированного списка. Затем найдите их показатели, как будто вы уже делаете это.