Python: sklearn.neighbors.KDДерево не работает должным образом - PullRequest
2 голосов
/ 08 марта 2020

Я пишу программу, которая должна выбирать точки, расположенные в окрестности другой точки. Размер окрестности определяется радиусом. Для этого я использую алгоритм sklearn.neighbors.KDTree . Однако, это не работает, как я ожидал.

Чтобы показать вам, с чем я имею дело, у меня есть два фрейма данных:

  • df_example_points, что набор точек, в которых я хочу искать,

    >>> import pandas as pd
    >>> from sklearn.neighbors import KDTree
    >>> df_example_points = pd.DataFrame(
    ...     {
    ...         'X': [-845.204, -845.262, -845.262, -845.262],
    ...         'Y': [-1986.243, -1986.077, -1986.077, -1986.079],
    ...         'Z': [246.655, 246.741, 246.742, 246.743],
    ...     }
    ... )
    >>> print(df_example_points)
             X         Y        Z
    0 -845.204 -1986.243  246.655
    1 -845.262 -1986.077  246.741
    2 -845.262 -1986.077  246.742
    3 -845.262 -1986.079  246.743
    
  • и df_reference_point, который состоит из одной точки, которую я хочу использовать для определения ее окрестности.

    >>> df_reference_point = pd.DataFrame({'X': [-845.002], 'Y': [-1986.32], 'Z': [246.508]})
    >>> print(df_reference_point)
             X        Y        Z
    0 -845.002 -1986.32  246.508
    

Когда я пытаюсь жёстко, что я ожидаю от KDTree, кажется, что каждый пункт из df_example_points должны быть извлечены KDTree в качестве отправной точки, которая лежит внутри опорной точки окрестности с.

>>> radius = 0.27
>>> x_ref, y_ref, z_ref = df_reference_point.iloc[0]
>>> x_min, x_max = x_ref - radius, x_ref + radius
>>> y_min, y_max = y_ref - radius, y_ref + radius
>>> z_min, z_max = z_ref - radius, z_ref + radius
>>> for i, (x, y, z) in df_example_points.iterrows():
...     if all([x_min <= x <= x_max, y_min <= y <= y_max, z_min <= z <= z_max]):
...         print(f'Point {i} SHOULD be extracted.')
...     else:
...         print(f'Point {i} SHOULD NOT be extracted.')
Point 0 SHOULD be extracted.
Point 1 SHOULD be extracted.
Point 2 SHOULD be extracted.
Point 3 SHOULD be extracted.

Однако, когда я пытаюсь использовать KDTree, извлекается только одна точка.

>>> tree = KDTree(df_example_points.values)
>>> extracted_points_indices = tree.query_radius(df_reference_point.values.reshape(1, -1), radius)[0]
>>> print(f'Number of extracted points: {len(extracted_points_indices)}')
Number of extracted points: 1

Я хочу использовать KDTree, потому что реализация намного быстрее. Однако я не могу использовать его, когда результат ненадежен. Пожалуйста, не могли бы вы помочь мне, что я делаю не так? Чего мне не хватает?

1 Ответ

1 голос
/ 08 марта 2020

Как прокомментировал @Gabriel, вы используете две разные метрики расстояния. Значение по умолчанию KDTree равно minkowski, в то время как вы используете chebyshev (вы можете проверить возможные показатели здесь: DistanceMetri c).

Изменение значения по умолчанию даст вам ожидаемый результат:

tree = KDTree(df_example_points.values, metric='chebyshev')
extracted_points_indices = tree.query_radius(df_reference_point.values.reshape(1, -1), radius)[0]

print(f'Number of extracted points: {len(extracted_points_indices)}')
Number of extracted points: 4
...