如何找到一个点的最近邻居和未删除最近邻居的另一个点?

时间:2019-07-02 04:45:03

标签: python pandas numpy

我的任务是找到某些点的最近邻居,并删除不是最近邻居的其他点。这个任务就像抽样问题一样。

到目前为止的代码:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from scipy import spatial

data = pd.read_csv('data.csv')
majority = data.loc[data['class']==0]
minority = data.loc[data['class']==1]

majority_points=majority.drop('class', axis=1)
minority_points=minority.drop('class', axis=1)

all_data = pd.concat([majority,minority])

data_points = all_data.drop('class', axis=1)
# print(data_points)

majority_points=np.array(majority_points)
print (majority_points)
minority_points =np.array(minority_points)
print (minority_points)
    #result
    [[1 1]
 [1 2]
 [1 3]
 [1 4]
 [1 5]
 [2 1]
 [2 2]
 [2 4]
 [2 5]
 [3 1]
 [3 2]
 [3 5]
 [4 1]
 [4 4]
 [4 5]
 [5 1]
 [5 2]
 [5 3]
 [5 4]
 [5 5]] (20, 2)
[[2 3]
 [3 3]
 [3 4]
 [4 2]
 [4 3]]

`

#to find nearest neighbor
from scipy.spatial import distance
Y = distance.cdist(minority_points, majority_points, 'euclidean')

K = np.argsort(Y)
print (Y)
print ("Ordered data: \n", K)
Y.sort()
print ("After short: \n", Y)
#result
[[2.23606798 1.41421356 1.         1.41421356 2.23606798 2.
  1.         1.         2.         2.23606798 1.41421356 2.23606798
  2.82842712 2.23606798 2.82842712 3.60555128 3.16227766 3.
  3.16227766 3.60555128]
 [2.82842712 2.23606798 2.         2.23606798 2.82842712 2.23606798
  1.41421356 1.41421356 2.23606798 2.         1.         2.
  2.23606798 1.41421356 2.23606798 2.82842712 2.23606798 2.
  2.23606798 2.82842712]
 [3.60555128 2.82842712 2.23606798 2.         2.23606798 3.16227766
  2.23606798 1.         1.41421356 3.         2.         1.
  3.16227766 1.         1.41421356 3.60555128 2.82842712 2.23606798
  2.         2.23606798]
 [3.16227766 3.         3.16227766 3.60555128 4.24264069 2.23606798
  2.         2.82842712 3.60555128 1.41421356 1.         3.16227766
  1.         2.         3.         1.41421356 1.         1.41421356
  2.23606798 3.16227766]
 [3.60555128 3.16227766 3.         3.16227766 3.60555128 2.82842712
  2.23606798 2.23606798 2.82842712 2.23606798 1.41421356 2.23606798
  2.         1.         2.         2.23606798 1.41421356 1.
  1.41421356 2.23606798]]
Ordered data: 
 [[ 2  6  7  1  3 10  5  8  0 13 11  9  4 12 14 17 16 18 15 19]
 [10  6  7 13  9  2 17 11  1  3  5  8 18 12 14 16  0  4 15 19]
 [ 7 11 13  8 14  3 18 10 19  2  4 17  6  1 16  9 12  5 15  0]
 [16 10 12  9 17 15  6 13  5 18  7  1 14  0  2 11 19  8  3  4]
 [17 13 16 10 18 14 12  9 15 11 19  7  6  5  8  2  3  1  4  0]]
After short: 
 [[1.         1.         1.         1.41421356 1.41421356 1.41421356
  2.         2.         2.23606798 2.23606798 2.23606798 2.23606798
  2.23606798 2.82842712 2.82842712 3.         3.16227766 3.16227766
  3.60555128 3.60555128]
 [1.         1.41421356 1.41421356 1.41421356 2.         2.
  2.         2.         2.23606798 2.23606798 2.23606798 2.23606798
  2.23606798 2.23606798 2.23606798 2.23606798 2.82842712 2.82842712
  2.82842712 2.82842712]
 [1.         1.         1.         1.41421356 1.41421356 2.
  2.         2.         2.23606798 2.23606798 2.23606798 2.23606798
  2.23606798 2.82842712 2.82842712 3.         3.16227766 3.16227766
  3.60555128 3.60555128]
 [1.         1.         1.         1.41421356 1.41421356 1.41421356
  2.         2.         2.23606798 2.23606798 2.82842712 3.
  3.         3.16227766 3.16227766 3.16227766 3.16227766 3.60555128
  3.60555128 4.24264069]
 [1.         1.         1.41421356 1.41421356 1.41421356 2.
  2.         2.23606798 2.23606798 2.23606798 2.23606798 2.23606798
  2.23606798 2.82842712 2.82842712 3.         3.16227766 3.16227766
  3.60555128 3.60555128]]

我希望将dominary_points中的每个点的3个最接近的邻居转换为domestor_points,并保持其数组的值,其余的都将被删除。

这是说明:

  1. before resampling/original dataset
  2. after resampling

红点是少数示例,蓝点是多数示例。因此,每个少数派类别都会计算出例如多数派中最近的3个邻居。然后该算法删除了一些不是最近邻居的点。

1 个答案:

答案 0 :(得分:0)

看来您已经走得很远了,您需要一些帮助以继续前进。距离排序的方式存在一个问题。首先创建一个距离数组,然后对它们进行排序,但是这样做会丢失每个距离的上下文信息。您具有所有距离,并且已对它们进行了排序,但是您不知道它们适用于哪些点。这一步对我来说似乎是不必要的,您可以仅以K停止,它是已存在项目的索引(不会丢失上下文信息),同时具有有关其排序位置的信息。如果您查看K,可能会注意到它是一个5x20的矩阵,并且给定majority_pointsminoirty_points的形状(分别为20x2和5x2),这表明{ {1}}是2D矩阵,每行是给定K n个给定minority_point m之间的排序距离的索引。

让我们看一个例子。 majority_point中的第一行是

K

这意味着对于第一个[ 2 6 7 1 3 10 5 8 0 13 11 9 4 12 14 17 16 18 15 19] minority_point,最接近的多数点依次位于索引2、6、7、1、3等,依次为{{1} } [2, 3] [1, 3] [2, 2]等顺序。如果您看一看,前3个是最短的距离,距所讨论的[2, 4]仅1个单位。 (第一个垂直放置,第二个水平放置。)(请注意,排序算法会将最接近的项目放置在输入数组中,同时将 first 放置在它们中。因此,索引2位于6或6之前。 7,即使它们都是相同的距离。)

因此,您要做的就是创建一个新数组,将K中每一行的前3个索引处的内容复制。这与为每个{{表示最近的3个[1, 2] 1}}。

在numpy约定中,这意味着要查看minority_point数组(而不是复制整个内容。)以下行应该可以工作(我已经对其进行了测试):

majority_points

这意味着您从所有行中的minority_pointsmajority_points)中抓取了元素(逗号前的第一个维,都只是majority_points[K[:,0:3]] ,)和前3个元素二维元素。这些就是您要从K获取的索引。

对我来说输出如下:

K[]