获取具有相似声音的记录

Posted

技术标签:

【中文标题】获取具有相似声音的记录【英文标题】:Get records with similar sounds 【发布时间】:2014-04-10 09:56:09 【问题描述】:

我想从联系人表中查找名称与声音匹配的所有重复名称。例如:Rita 或 Reeta、Microsoft 或 Microsift、Mukherjee 或 Mukherji。

我使用了以下查询:

SELECT contacts.id 
FROM contacts 
INNER JOIN (
    SELECT first_name, last_name, count(*) AS rows 
    FROM contacts 
    WHERE deleted = 0 
    GROUP BY SOUNDEX(first_name), SOUNDEX(last_name) 
    HAVING count(rows) > 1
) AS p 
WHERE contacts.deleted = 0 
AND p.first_name SOUNDS LIKE contacts.first_name 
AND p.last_name SOUNDS LIKE contacts.last_name 
ORDER BY contacts.date_entered DESC

上面的查询给出了正确的结果,但是当有很多记录时会花费很多时间。

【问题讨论】:

它会的。您的问题无法快速解决,因为“听起来很相似”的事情无法快速解决。因此,SOUNDEX 很慢,整个查询也很慢 除了使用跑得更快的SOUNDEX,还有其他方法吗? 确定哪些字符串“听起来相似”?不,但如果你可以简化“听起来很相似”这个词 - 可能是 【参考方案1】:

我不知道有比SOUNDEX() 更好的(本地)方法。它缓慢的原因是因为它是一个函数,因此需要处理所有记录以计算值并从那里开始工作。解决此问题的一种方法是将结果直接存储到表中。我在 mysql 中没有使用这些函数的经验,但根据documentation,您似乎可以将WHERE 子句转换为

[...] AND SOUNDEX(p.first_name) = SOUNDEX(contacts.first_name) [...]

因此,如果您已经预先计算(并编制了索引!)这些值,那么搜索匹配记录的速度应该会快得多!

也就是说,我很难弄清楚您的问题。我认为您不需要那里的HAVING COUNT(*) > 1,即使那样我也对您要如何对联系人进行分组/过滤感到困惑!?

你想要这样的东西吗:

SELECT c1.id as contact_id, 
       c2.id as similar_id
  FROM contacts c1 
  JOIN contacts c2
    ON c2.id <> c1.id
   AND c2.deleted = 0
   AND SOUNDEX(c2.first_name) = SOUNDEX(c1.first_name)
   AND SOUNDEX(c2.last_name) = SOUNDEX(c1.last_name)
 WHERE c1.deleted = 0 
ORDER BY c1.date_entered DESC

然后您可以按照上面的建议进行优化

SELECT c1.id as contact_id, 
       c2.id as similar_id
  FROM contacts c1 
  JOIN contacts c2
    ON c2.id <> c1.id
   AND c2.deleted = 0
   AND c2.first_name_soundex = c1.first_name_soundex
   AND c2.last_name_soundex = c1.last_name_soundex
 WHERE c1.deleted = 0 
ORDER BY c1.date_entered DESC

其中 first_name_soundex 保存 SOUNDEX(first_name) 等的结果。 编制索引时,您可能希望在deletedfirst_name_soundexlast_name_soundex 上有一个覆盖索引。 (AFAIK MySQL 还不支持过滤索引,否则您可以将索引限制为仅deleted = 0)。

【讨论】:

【参考方案2】:

SOUNDEX(恕我直言)的效用非常有限。一个极端的例子……

SELECT SOUNDEX('cholmondley');
+------------------------+
| SOUNDEX('cholmondley') |
+------------------------+
| C4534                  |
+------------------------+

SELECT SOUNDEX('chumleigh');
+----------------------+
| SOUNDEX('chumleigh') |
+----------------------+
| C542                 |
+----------------------+

【讨论】:

以上是关于获取具有相似声音的记录的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 获取声音输入并查找相似的声音

如何根据用户类型用相似的记录重新填充组合框

所有记录的Python sklearn余弦相似度循环

模拟音频数字化的过程

每日学习记录20230321_Bert

永久存储具有512个浮点数和100万条记录的数组以便快速搜索的最佳方法是什么?