类似的名字在一个巨大的列表中


Similar names in a huge list

我有一个50000多家公司的数据库,该数据库不断更新(每月200多家)。

内容重复是一个巨大的问题,因为名称并不总是严格/正确的:
"Super 1 Store"
"超级一店"
"Super 1 Stores"

编辑:另一个例子。。可能需要不同的方法:
"艾米披萨"<--->"Amy and Company有机披萨"

我们需要一个工具来扫描数据中类似的名称。我对Levenstein Distance和LCS有一些经验,但如果两个字符串相似,它们可以很好地进行比较
在这里,我必须扫描50000个名字,每个名字可能都有,然后计算。。。总体相似性评级。。。

我需要如何解决这个问题的建议——预期的结果是有一个10-20组非常相似的名字的列表,并且可能会进一步调整灵敏度以获得更多结果。

大约一年前我也遇到过类似的问题,如果我记得很清楚的话,我用similar_textsoundex解决了(或多或少),就像其他人在评论中说的那样。类似这样的东西:

<?php
$str1 = "Store 1 for you";
$str2 = "Store One 4 You";
similar_text(soundex($str1), soundex($str2), $percent);
if ($percent >= 66){
    echo "Equal";
    //Send an email for review
}else{
    echo "Different";
    //Proceed to insert in database
}
?>

在我的情况下,使用66%的百分比来确定公司是相同的(在这种情况下,不要插入数据库,而是发送电子邮件给我进行审查,并检查是否正确)。

在使用这些解决方案几个月后,我决定为公司使用某种独特的代码(在我的情况下是CIF,因为西班牙的公司是独一无二的)。

纯粹取决于我们应该容忍多大程度上将两个字符串视为相似。。soundex也是有用的

select soundex('Super One Store') returns S165236
    select soundex('Super 1 Store'); returns S16236
    select soundex('Super One Stores') returns S1652362

S16236在所有情况下都很常见,你可以使用下面的过滤器

select * from (
select 'Super One Store' as c 
union
select 'Super 1 Store' as c
union
select 'Super One Stores' as c
union
select  'different one' as c
union 
select  'supers stores' as c
) tmp
where soundex(c) like CONCAT('%', soundex('Super store'), '%')
or soundex(c) like CONCAT('%', soundex('Super one store'), '%')

我认为您应该手动浏览公司列表,并为每个公司创建一个具有唯一条目的表。然后有一个多对一的表格,在那里你可以将不同的名称引用到正确的公司。我认为这就是规范化的含义。

表:companies:

|id|base_name
|1 |Super 1 Store

表:company_mapping:

|id|company_id|name
|1 |1         |Super 1 Store
|2 |1         |Super One Store
|3 |1         |Super 1 Stores