如何使用sklearn K近邻获取1:1对应的匹配项
How to get 1:1 corresponding matches using sklearn KNearest neighbors
我正在编写一种算法,根据兴趣相似度,使用 NearestNeighbors(n_neighbors = 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 的最佳匹配是 personA0(距离 = 0)。然而,personB1 的顶级匹配也是 personA0(distance = 0.125)!
我想以某种方式将 personB0 与 personA0 匹配(因为它们的距离最小),将它们移动到另一个 table,然后重新 运行 K-Neighbors 算法,希望现在可以建议personB1 的最佳匹配项是 personA1(因为 A0 现在已被删除)。我已经开始编写一个 for 循环来遍历这个,但是,这对我来说非常复杂(必须遍历多个不同的数组、数据帧等)所以我想知道什么是最好的方法?我想要一个像下面这样的最终数据框,它有 1:1 个对应关系:
SetA SetB
personA0 personB0
personA1 personB1
personA2 personB3
personA3 personB2
您可以使用列表来检查某个人是否已匹配。此外,您需要通过更改传递给参数 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
请注意,我使用了默认指标(minkowski,p=2)。如果将 metric=my_dist
传递给 NearestNeighbors
,结果可能会有所不同。
我正在编写一种算法,根据兴趣相似度,使用 NearestNeighbors(n_neighbors = 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 的最佳匹配是 personA0(距离 = 0)。然而,personB1 的顶级匹配也是 personA0(distance = 0.125)!
我想以某种方式将 personB0 与 personA0 匹配(因为它们的距离最小),将它们移动到另一个 table,然后重新 运行 K-Neighbors 算法,希望现在可以建议personB1 的最佳匹配项是 personA1(因为 A0 现在已被删除)。我已经开始编写一个 for 循环来遍历这个,但是,这对我来说非常复杂(必须遍历多个不同的数组、数据帧等)所以我想知道什么是最好的方法?我想要一个像下面这样的最终数据框,它有 1:1 个对应关系:
SetA SetB
personA0 personB0
personA1 personB1
personA2 personB3
personA3 personB2
您可以使用列表来检查某个人是否已匹配。此外,您需要通过更改传递给参数 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
请注意,我使用了默认指标(minkowski,p=2)。如果将 metric=my_dist
传递给 NearestNeighbors
,结果可能会有所不同。