【发布时间】:2019-11-18 17:44:15
【问题描述】:
我正在尝试按名称匹配两个产品列表。
产品来自不同的网站,它们的名称可能因一个网站而异,以许多微妙的方式出现在另一个网站上,例如“iPhone 128 GB” vs “Apple iPhone 128GB”。
产品列表相交,但不相等,并且一个不是另一个的超集;即A 列表中的某些产品不在B 列表中,反之亦然。
给定一个算法,比较两个字符串(产品名称)并返回 0 和 1 之间的相似度分数(我这里已经有一个令人满意的实现),我正在寻找一种算法执行列表 A 与列表 B 的最佳匹配。
换句话说,我想我正在寻找一种算法,可以最大化匹配中所有相似分数的总和。
请注意,一个列表中的产品最多只能与另一个列表中的一个产品匹配。
我最初的想法
- 对于
A中的每个产品,获取与B中每个产品的相似度,并保留得分最高的产品,只要它超过一定的阈值,例如0.75。 匹配这些产品。 - 如果得分最高的产品在循环的早期已经与
A中的另一个产品匹配,则取第二高的产品,前提是它超过了上述阈值。 改为匹配这个。
等等
我对这个原生实现的担心是,如果在循环的后面有更好的匹配,但来自B 的产品已经在之前的迭代中分配给来自A 的另一个产品,则匹配不是最佳的。
改进版
为了确保产品与其相似度最高的对应物相匹配,我想到了以下实现:
- 预先计算所有
A-B对的相似度分数 - 丢弃低于上述阈值的相似度
- 按相似度排序,最高优先
- 对于每一对,如果产品
A和产品B均未匹配,则匹配这些产品。
此算法应优化匹配产品对,确保每对产品的相似度最高。
我担心计算和内存非常密集:假设我在两个列表中都有 5,000 个产品,即需要预先计算并可能存储在内存(或数据库)中的 25,000,000 个相似度分数;实际上,由于所需的最低阈值,它会更低,但它仍然可以变得非常大并且仍然是 CPU 密集型的。
我错过了什么吗?
是否有更有效的算法可以提供与此改进版本相同的输出?
【问题讨论】:
-
假设由于某种算法原因您不会计算特定配对的分数,那么您可能会错过最佳解决方案(据我们所知,它的分数可能非常高):所以您将必须计算所有分数。
-
您听说过matching algorithms 吗?关于大小,一个5000 x 5000的距离矩阵并没有那么大,如果它不增长太多,它可以很容易地处理。
-
@trincot 确实有道理!
-
@m.raynal 不,我没有听说过这些,我是图论的新手,感谢您的指点。 5000x5000 可能仍然可以管理,但随着数字的增长,它变得更加困难。 10,000x10,000 呢? 20,000x20,000?我开始明白无论如何我都别无选择,因此部分解决方案可能在于设计应用程序,在产品数量和重新匹配频率方面具有合理限制(可能不时需要随着产品数据库的发展)。
-
我目前正在使用 200,000 x 200,000,它变得非常大并且实际上是一个问题(构建距离矩阵需要 250GB...)。一种解决方法是利用这些权重中的绝大多数应该非常低的事实。因此,您可以定义一个阈值,低于该阈值将权重设置为零,并使用图形的sparse matrix 表示。它是一种非常常见的数据结构,用于处理大图实例。