如何使用sklearn KNearest邻居获得1:1对应匹配

2024-09-19 23:36:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个算法,根据兴趣相似性,使用最接近的邻居(n_neights=1),将setA的每个人与setB的每个人进行匹配

这就是我到目前为止所做的:

dfA = pd.DataFrame(np.array([[1, 1, 1, 1], [1,1,2,2], [4, 5, 2, 0], [8, 8, 8, 8]]),
                   columns=['interest0', 'interest2', 'interest3','interest4'],
                  index=['personA0','personA1','personA2','personA3'])


dfB = pd.DataFrame(np.array([[1, 1, 1, 1], [1, 1, 1, 2], [2,3,2,2], [8, 6, 8, 8]]),
                   columns=['interest0', 'interest2', 'interest3','interest4'],
                  index=['personB0','personB1','personB2','personB3'])


knn = NearestNeighbors(n_neighbors = 1, metric = my_dist).fit(dfA)
distances, indices = knn.kneighbors(dfB)


>>> dfA
          drink  interest2  interest3  interest4
personA0      1          1          1          1
personA1      1          1          2          2
personA2      4          5          2          0
personA3      8          8          8          8



>>> dfB
          drink  interest2  interest3  interest4
personB0      1          1          1          1
personB1      1          1          1          2
personB2      2          3          2          2
personB3      8          6          8          8

>>> print("Distances\n\n", distances, "\n\nIndices\n\n", indices)

Distances

 [[0.   ]
 [0.125]
 [1.125]
 [0.5  ]] 

Indices

 [[0]
 [0]
 [1]
 [3]]

从输出来看,它表明personB0最匹配的是person0(距离=0)。然而,personB1的头号对手也是Personal0(距离=0.125)

我想以某种方式将personB0与personA0进行匹配(因为它们之间的距离最小),将它们移动到另一个表中,然后重新运行K-neights算法,这将有希望表明personB1最匹配的是personA1(因为A0现在被删除)。我已经开始编写一个for循环来迭代这个过程,但是,它对我来说相当复杂(必须迭代多个不同的数组、数据帧等),所以我想知道什么是最好的方法?我想要一个如下的最终数据帧,它有1:1的对应关系:

  SetA         SetB
personA0     personB0
personA1     personB1
personA2     personB3
personA3     personB2



Tags: 算法距离dfadfbpersonb1interest3persona3persona2
1条回答
网友
1楼 · 发布于 2024-09-19 23:36:46

您可以使用列表来检查一个人是否匹配。此外,您需要通过更改传递给参数n_neighbors的值,获得按距离排序的邻居列表,而不是最近的邻居

knn = NearestNeighbors(n_neighbors=len(dfB)).fit(dfB)
distances, indices = knn.kneighbors(dfA)

matched = []
pairs = []
for indexA, candidatesB in enumerate(indices):
    personA = dfA.index[indexA]
    for indexB in candidatesB:
        if indexB not in matched:
            matched.append(indexB)
            personB = dfB.index[indexB]
            pairs.append([personA, personB])
            break

matches = pd.DataFrame(pairs, columns=['SetA', 'SetB'])

生成的数据帧如下所示:

       SetA      SetB
0  personA0  personB0
1  personA1  personB1
2  personA2  personB2
3  personA3  personB3

请注意,我使用了默认度量(p=2的minkowski)。如果将metric=my_dist传递给NearestNeighbors,结果可能会有所不同

相关问题 更多 >