【问题标题】:PHP/MySQL - find items that have similar or matching propertiesPHP/MySQL - 查找具有相似或匹配属性的项目
【发布时间】:2011-08-10 20:04:21
【问题描述】:

我正在尝试开发一种方法来获取具有多个属性的实体并在数据库中搜索类似的实体(以正确的顺序匹配尽可能多的属性)。这个想法是,它会返回相似程度的百分比。

还要考虑属性的顺序,所以开头的属性比结尾的更重要。

例如:

第 1 项 - A、B、C、D、E

第 2 项 - A、B、C、D、E

100% 匹配

第 1 项 - A、B、C、D、E

第 2 项 - B、C、A、D、E

这不会是完美的匹配,因为属性的顺序不同

第 1 项 - A、B、C、D、E

第 2 项 - F、G、H、I、A

将是一个低匹配,因为只有一个属性是相同的并且它在位置 5

此算法将运行成千上万条记录,因此它需要高性能和高效。关于如何在 PHP/MySQL 中以快速有效的方式执行此操作有什么想法吗?

我正在考虑levenshtein,但据我所知,这也会查看两个完全不同的单词在拼写方面的距离。除非我只是以错误的方式使用它,否则似乎不适合这种情况..

它可能只在 MySQL 中完成,可能使用全文搜索或其他方式。

这似乎是nice solution,虽然不是为这种情况设计的。也许可以以某种方式使用二进制比较?

【问题讨论】:

  • 你忘了告诉我们 A/B/C/D/E 是否是同一个表中的字段,在不同的表中,都是一个大的 varchar/text/something。请更新一些表定义。
  • 目前完全处于理论阶段,因此可以提出建议(这将取决于效率)。实际属性将是字符串,但也许可以使用它们的数字 id 进行比较。它们可以存储在单独的表中并作为连接处理,但这效率很低,所以我想知道它们是否也可以作为字符串缓存在同一个表中,它只是将字符串视为一个整体比较时。另一个想法是它可以为每个项目创建某种指纹并基于它进行搜索(如果这样会更快)
  • 你想要的确切的o/p是什么?只有完美的结果?
  • 不,只是部分或完全匹配的所有结果的列表,按匹配百分比排序
  • 所有属性值都已知吗?所有实体都具有相同数量的属性吗?

标签: php mysql compare


【解决方案1】:

我要做的是将订单和属性值编码为一个数字。数字具有快速比较的优势。

这是一个普遍的想法,可能仍需要一些工作,但我希望它会在某些方面有所帮助。

为每个属性计算一个数字(某种形式的哈希),然后乘以代表项目属性出现顺序的数字。

假设 item1 有 3 个属性 A、B 和 C。

散列(A) = 123, 散列(B) = 345, 散列(C) = 456

假设我们有已知数量的属性,然后将其乘以出现顺序:

(hash(A) * 1,000,00) + (hash(B) * 1,000) + (hash(C) * 1) = someval

可以调整乘数的大小以反映您的数据集。您必须识别散列函数。 soundex 可能吗?

由于哈希冲突,问题现在被简化为唯一性问题,但我们可以非常确定不匹配的属性。

此外,通过使用乘数的大小从生成的数字中提取哈希值,可以相对轻松地检查属性是否以不同的顺序出现在另一个项目中。

HTH。

编辑:检查匹配的示例

给定 item1(a b c) 和 item2(a b c)。计算的项目哈希值将相等。这是最好的情况。无需进一步计算。

给定 item1(a b c) 和 item2(d e a)。计算的项目哈希不相等。继续分解属性哈希...

假设属性 a = 1、b = 2、c = 3、d = 4、e = 5 的哈希表,乘数为 10^n。 item1 的计算哈希为 123,item2 为 451,分解每个属性的计算哈希并比较每个 item1(变为 item1(1 2 3))和 item2(变为 item2(4 5 1) 的所有属性组合))。然后计算分数。

另一种看待它的方法是逐个比较属性,除了这一次,您使用的是数字而不是实际的字符串值

【讨论】:

  • 非常有趣的概念,我真的很喜欢比较数字的想法。我刚刚将其作为电子表格进行了尝试,我认为缺陷在于散列。在此示例中,哈希只是属性的增量 ID - 1、2、3 等。产生的问题是乘数,如果 ID 是一个大数字,则计算出的数字会变得非常高。查看s4.postimage.org/5f0kogg2x/… 并查看实体 1,2 和 3 之间的区别 - 与没有相似值的实体 4 相比,实体 3 的最终值非常高。
  • 预计数字会相对较高。对于 8 tho 的样本集,乘数可以是 10 的幂的增量。因此最高哈希结果将低于 1000。正在考虑任意精度(bigints)数字,而不仅仅是 32 或 64 位整数。
  • 对不起,我只是不明白它是如何工作的。在实体 4 乘以 4 x 10 的示例中,总是大于 1 x 10(实体 1),而实体3 应该更近,但实际上是 8 x 10(使其离实体 1 比实体 4 更远)。看这张图中的“与实体1的区别”和“顺序”,根据实体的属性,顺序完全错误-img683.imageshack.us/img683/7570/screenshot20110425at131.png
  • 不需要道歉。如果我没有更清楚地解释它,那将是我的错。您仍然需要遍历计算的各个哈希值以进行比较。
  • 你会在循环过程中进行什么比较?你能举个例子吗?
【解决方案2】:

您可以从各种sequence alignment 算法(如Smith-Waterman)中汲取灵感(或彻底解决算法)。实际上,您正在寻找的似乎是对序列比对的描述。但是,我不确定是否可以将其作为 SQL 查询来执行。

【讨论】:

  • 确实是序列比对问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-03
  • 1970-01-01
  • 1970-01-01
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多