我构建了一个函数,该函数可以通过某种度量找到某种对齐方式。
它获得一个已经计算出相似度值的矩阵:
weighted_res
可能是:
[[0.2, 0.5, 0.3],
[0.1, 0.2, 0.4],
[0.8, 0.2, 0.4],
[0.1, 0.2, 0.7],
[0.1, 0.2, 0.4],
我的函数使exs1和exs2的所有索引组合的值总和最大化,但是没有索引可以取两次。结果是这些最佳指标。 (0,1),(2,0),(3,2)的总和,因此0.5 + 0.8 + 0.7产生了最高分。
在许多情况下,仅对每一列/每行查找最大值是不够的。令矩阵为:
[[0.1, 0.0, 0.1]
[0.5, 0.6, 0.4],
[0.5, 0.8, 0.3],
[0.0, 0.0, 0.2]]
在这里,它选择(1,1),(2,1),(3,2),因为0.5 + 0.8 + 0.2是最大可达分数。
我的代码如下所示,我担心,它最大程度地无效。我很高兴能找到一些提示,以找到一种更有效的算法,而不是计算所有可能性并进行总结和最大化。这是代码:
def one_to_one(weighted_res, exs1, exs2, mask):
inner_cube_len = min(len(list(exs1)), len(list(exs2)))
turned = False
if (len(exs1) < len(exs2)):
exs1, exs2 = exs2, exs1
weighted_res = weighted_res.T
mask = mask.T
turned = True
x_to_choose = np.array(list(itertools.permutations(range(len(exs1)), inner_cube_len)))
y_to_choose = np.array(list(range (len(exs2))))
weighted_res_overall = \
weighted_res[x_to_choose,y_to_choose].sum(axis=1)
best_overall_row = np.argmax(weighted_res_overall)
best_x_values = np.array (x_to_choose[best_overall_row] )
valid_mask = mask[best_x_values,y_to_choose]
best_res1 = best_x_values[valid_mask]
best_res2 = y_to_choose[valid_mask]
if not valid_mask.any():
return [],[]
if turned:
left_value = best_res2.tolist()
right_values = [[x] for x in best_res1.tolist()]
exs1, exs2 = exs2, exs1
weighted_res = weighted_res.T
mask = mask.T
else:
right_values = [[x] for x in best_res2.tolist()]
left_value = best_res1.tolist()
return left_value, right_values
在输入值的长度为输入结果的8和6的情况下,weighted_res_overall
的大小为20160,并且增长很快。
答案 0 :(得分:0)
如果对矩阵进行转置,则可以轻松找到每一列的最大值,而无需重复以下操作:
from numpy import array
mat = [[0.2, 0.5, 0.3],
[0.1, 0.2, 0.4],
[0.8, 0.2, 0.4],
[0.1, 0.2, 0.7],
[0.1, 0.2, 0.4]]
mat = array(mat).T
maxis = [max(col) for col in mat]
如果您随后想要的是总和而不是最大值列表,则可以将最终生成器表达式更改为:
max_sum = sum(max(col) for col in mat)
希望这会有所帮助。
答案 1 :(得分:0)
我找到了它,它被称为匈牙利算法,但是最大化而不是最小化分数。 https://en.wikipedia.org/wiki/Hungarian_algorithm
有一个scipy实现: https://docs.scipy.org/doc/scipy-0.18.1/reference/generation/scipy.optimize.linear_sum_assignment.html
或 https://github.com/src-d/lapjv
感谢您的考虑!