Как выбрать числовые образцы на основе их расстояния относительно уже выбранных образцов (Python)

У меня есть некоторые случайные тестовые данные в 2D-массиве формы (500,2) как таковые:

xy = np.random.randint(low=0.1, high=1000, size=[500, 2])

Из этого массива я сначала выбираю 10 случайных выборок, чтобы выбрать 11-ю выборку, я хотел бы выбрать выборку, которая находится дальше всего от исходных 10 выбранных выборок вместе, я использую для этого евклидово расстояние. Мне нужно продолжать делать это, пока не будет выбрана определенная сумма. Вот моя попытка сделать это.

# Function to get the distance between samples
def get_dist(a, b):

    return np.sqrt(np.sum(np.square(a - b)))


# Set up variables and empty lists for the selected sample and starting samples
n_xy_to_select = 120
selected_xy = []
starting = []


# This selects 10 random samples and appends them to selected_xy
for i in range(10):
    idx = np.random.randint(len(xy))
    starting_10 = xy[idx, :]
    selected_xy.append(starting_10)
    starting.append(starting_10)
    xy = np.delete(xy, idx, axis = 0)
starting = np.asarray(starting)


# This performs the selection based on the distances
for i in range(n_xy_to_select - 1):
# Set up an empty array dists
    dists = np.zeros(len(xy))
    for selected_xy_ in selected_xy:
        # Get the distance between each already selected sample, and every other unselected sample
        dists_ = np.array([get_dist(selected_xy_, xy_) for xy_ in xy])
        # Apply some kind of penalty function - this is the key
        dists_[dists_ < 90] -= 25000
        # Sum dists_ onto dists
        dists += dists_
    # Select the largest one
    dist_max_idx = np.argmax(dists)
    selected_xy.append(xy[dist_max_idx])
    xy = np.delete(xy, dist_max_idx, axis = 0)

Ключом к этому является эта строка — штрафная функция

dists_[dists_ < 90] -= 25000

Эта штрафная функция существует для того, чтобы код не мог просто выбрать кольцо выборок на краю пространства, искусственно сокращая близко расположенные значения. Однако в конечном итоге это нарушается, и выделение начинает группироваться, как показано на изображении. Вы можете ясно видеть, что код может сделать гораздо лучший выбор, прежде чем потребуется какая-либо кластеризация. Я чувствую, что для этого лучше всего подойдет своего рода затухающая экспоненциальная функция, но я не знаю, как ее реализовать. Как выбрать числовые образцы на основе их расстояния относительно уже выбранных образцов (Python) Итак, мой вопрос; как мне изменить текущую функцию штрафа, чтобы получить то, что я ищу?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
27
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Из вашего вопроса я понимаю, что вы ищете периодические граничные условия (PBC). Это означает, что точка, которая находится на левом краю вашего пространства, находится рядом с правой конечной стороной. Таким образом, максимальное расстояние, которое вы можете пройти по одной оси, определяется половиной прямоугольника (то есть между краем и центром).

Чтобы учесть PBC, вам нужно вычислить расстояние по каждой оси и вычесть из него половину поля: Например, если у вас есть точка с x1 = 100 и вторая с x2 = 900, используя PBC, они находятся на расстоянии 200 единиц друг от друга: |x1 - x2| - 500. В общем случае, учитывая 2 координаты и поле половинного размера, вы получите:

В вашем случае это упрощается до:

delta_x[delta_x > 500] = delta_x[delta_x > 500] - 500

В завершение я переписал ваш код, используя новую функцию distance (обратите внимание, что я удалил некоторые ненужные циклы for):

import numpy as np

def distance(p, arr, 500):
    delta_x = np.abs(p[0] - arr[:,0])
    delta_y = np.abs(p[1] - arr[:,1])
    delta_x[delta_x > 500] = delta_x[delta_x > 500] - 500
    delta_y[delta_y > 500] = delta_y[delta_y > 500] - 500
    return np.sqrt(delta_x**2 + delta_y**2)

xy = np.random.randint(low=0.1, high=1000, size=[500, 2])
idx = np.random.randint(500, size=10)
selected_xy = list(xy[idx])
_initial_selected = xy[idx]
xy = np.delete(xy, idx, axis = 0)
n_xy_to_select = 120


for i in range(n_xy_to_select - 1):
    # Set up an empty array dists
    dists = np.zeros(len(xy))
    for selected_xy_ in selected_xy:
        # Compute the distance taking into account the PBC
        dists_ = distance(selected_xy_, xy)
        dists += dists_
    # Select the largest one
    dist_max_idx = np.argmax(dists)
    selected_xy.append(xy[dist_max_idx])
    xy = np.delete(xy, dist_max_idx, axis = 0)

И действительно, он создает кластеры, и это нормально, так как вы будете стремиться создавать кластеры точек, которые находятся на максимальном расстоянии друг от друга. Более того, из-за граничных условий мы установили, что максимальное расстояние между двумя точками по одной оси равно 500. Таким образом, максимальное расстояние между двумя кластерами также равно 500! И, как вы можете видеть на изображении, это так.

Более того, выбор большего количества чисел начнет рисовать линию для соединения различных кластеров, начиная с центрального, как вы можете видеть здесь:

Спасибо за ваш ответ, но это не то, что я ищу. Возможно, я плохо сформулировал в своем первоначальном посте, но то, что я ищу, - это «Выборка самой дальней точки». Смотрите мой ответ, я только что обнаружил это сегодня!

Dragmoogle 18.03.2022 16:30
Ответ принят как подходящий

То, что я искал, называется «Выборка самой дальней точки». У меня есть еще несколько исследований решения, и код Python, используемый для его выполнения, находится здесь: https://minibatchai.com/ai/2021/08/07/FPS.html

Другие вопросы по теме