我正在尝试按名称匹配两个产品列表。
产品来自不同的网站,它们的名称可能会以许多微妙的方式从一个网站到另一个网站而有所不同,例如“ iPhone 128 GB” 与“ Apple iPhone 128GB” 。
乘积列表相交,但不相等,一个不是另一个的超集;即列表A
中的某些产品不在列表B
中,反之亦然。
给出一个比较两个字符串的算法(产品名称)并返回0到1之间的相似度得分(我已经在这里有了令人满意的实现),我正在寻找一种算法进行列表A
与列表B
的最佳匹配。
换句话说,我想我正在寻找一种算法,以使比赛中所有相似分数的总和最大化。
请注意,一个列表中的产品必须与另一列表中的一个产品最多匹配。
A
中的每个产品,获取与B
中的每个产品的相似性,并保留得分最高的产品,前提是该产品的得分超过某个阈值,例如{{1} }。 匹配这些产品。 0.75
中的另一产品匹配,则以第二至最高的价格为前提,前提是该产品超过了上述阈值。 改为与此人匹配。等
我对这种本机实现的担心是,如果在循环的后面有更好的匹配项,但是在先前的迭代中,已经将A
的产品分配给了B
的另一产品,则该匹配不是最佳的。
为确保产品与其最高相似性产品匹配,我想到了以下实施方案:
A
-A
对预先计算相似性得分B
和产品A
都没有匹配,请匹配这些产品。该算法应最佳地匹配产品对,以确保每个对都具有最高的相似性。
我担心的是这是非常消耗计算和内存的:说我在两个列表中都有5,000个产品,这是要预先计算并可能存储在内存(或数据库)中的25,000,000个相似度得分;实际上,由于最低要求阈值,它会降低,但它仍然会变得很大,并且仍然占用大量CPU。
有没有更高效的算法可以提供与改进版本相同的输出?
答案 0 :(得分:3)
您的模型可以用图形式重新表示:考虑一个完整的加权bipartite图,其中第一部分的顶点是列表A的名称,第二部分的顶点是列表B的名称,并且边用预先计算的相似度分数。
现在,您的问题看上去真的很接近密集的Assignment_problem,可以以Hungarian algorithm(O(n³)复杂度)找到最佳解决方案。
如果最佳解决方案不是您的最终目标,并且一些最佳的近似值也可以满足您的要求,请尝试针对分配问题的启发式算法,这里是另外一个topic,其中简要介绍了它们。
答案 1 :(得分:2)
您的第二个算法应该提供不错的输出,但是它不是最佳的。检查以下情况:
Set0 Set1
A C
B D
Similarities:
A-C = 900
A-D = 850
B-C = 850
B-D = 0
Your algorithm's output: [(A,C), (B,D)]. Value 900.
Optimal output: [(A,D), (B,C)]. Value 1700.
您要处理的问题恰好是Assigment Problem,即“在加权二部图中找到匹配,其中边缘的权重之和要尽可能大”。您可以找到许多方法来最佳,有效地解决此问题。