4

所以我在数据库中有大量条目(MySql

我在创建我的 Web 应用程序时使用PythonDjango 。

这是我正在使用的基本 Django 模型:

class DJ(models.Model):
    alias = models.CharField(max_length=255)
    #other fields...

在我的数据库中,我现在有重复项

例如。超越,超越,超越,超越DJ , 超越Disk Jokey , ...

这是一个问题......因为它在我的数据库和我的应用程序中炸了一个大洞。


我相信其他人也遇到过这个问题并考虑过。

我的想法如下:

  • 创建一组规则以便无法创建新条目?

    例如。无法创建“DJ Beyond and Beyond” ,因为“Above & Beyond”在数据库中

  • 以某种方式将这些别名相互关联?

    例如。将“DJ Beyond and Beyond”“Above & Beyond”联系起来


我真的不知道如何继续这件事,即使有人能指出我一个非常有帮助的方向。

任何帮助将不胜感激!感谢你们。

4

9 回答 9

4

我想你可以根据Levenshtein distance做一些事情,但是没有真正的方法可以自动做到这一点 - 无需创建一个相当复杂的基于规则的系统。

除非您可以定义一个可以解决任何问题x以及y是否x与 重复的规则系统,否则您y将不得不以一种模糊的、人性化的方式来处理这个问题。

Stack Overflow 有一种相当不错的处理方式——根据 Levenshtein 距离(可能还有某种规则引擎)之类的东西,警告用户是否有重复的内容,然后允许一部分用户将内容合并为重复如果其他用户忽略警告。

于 2010-01-21T15:16:42.493 回答
3

从您提供的示例中,听起来您遇到的自然语言问题多于精确匹配问题。鉴于自然语言匹配本质上是不精确的,您不太可能提出完美的解决方案。

  • 字符串距离实际上不起作用,因为算法上接近的字符串在语义上可能不接近(例如,“DJ Above & Beyond”应该匹配“Above and Beyond”,而不是“DJ Above & Beyond 2”,后者在 Levenshtein 距离中更接近。
  • 自然语言解析的一些廉价替代品是soundex,它将通过语音匹配,以及Stemming,它删除前缀/后缀以对词干进行规范化。我想你可以创建一个词根的链接列表,但这也不是非常准确。
  • 如果这是一个与用户交互的程序,您可以向用户回显“near misses”,例如“您打算输入其中之一吗?”
  • 您可以以某种方式规范化条目,以便不同的条目映射到相同的规范化值(例如,大小写规范化、“&”->“和”等,等等,上面的一些建议可能是一个步骤)找到未命中或将多个输入映射到单个值。

补充一点,我的经验仅适用于英语,例如,英语 PorterStemmer 不会识别您输入的一个法语标题。

于 2010-01-21T15:24:19.560 回答
2

我认为这更像是一个社会问题而不是编程问题。像这样的自然语言处理的任何类型的编程解决方案都将是错误的并且容易出错。很难区分接近的事物,但与您正在谈论的那种不受欢迎的重复是合法的不同。

正如 Dominic 所提到的,Stack Overflow 的标签系统是一个很好的模型。它向用户提供提示,鼓励他们在适当的情况下使用现有标签(用户键入时下拉列表),它允许受信任的用户重新标记个别问题,并允许版主进行大规模重新标记。

这确实是一个必须有人直接参与的过程。

于 2010-01-21T16:01:17.120 回答
1

首先,编程任务(如前所述的 NLP 等)当然很有趣。但如前所述,旨在完善它是矫枉过正的。

但是另一种观点如前所述(“社交”),谁输入数据,谁查看它,它应该持续多长时间和正确程度?所以这是一个命名约定问题,让我想起了伟大的项目 musicbrainz.org - 如果您的网站“正常工作”还是您更喜欢遵循标准,在后一种情况下,我会沿着 mb 项目定位自己 - 如果您没有没做过,没听说过。IE。请参阅此处的“以上”和“超越”:他们定义了别名,他们使用它来匹配用户搜索。 http://musicbrainz.org/show/artist/aliases.html?artistid=58438 还可以查看 wiki 中的 Artist_Alias 页面。

数据模型值得一看,甚至还有几个用于同步数据的 API 绑定,也在 python 中。

于 2010-01-22T08:36:01.633 回答
1

您可以尝试仅针对此实例解决此问题(将“&”替换为“&”,将“DJ”替换为“磁盘笑话”或忽略“DJ”等)。如果你的桌子只包含 DJ,你可以设置一堆这样的规则。如果您的表格包含更多不同的东西,您将不得不采用更结构化的方法。您能否提供数据集的样本?

于 2010-01-21T15:47:02.803 回答
1

这不是一个完整的解决方案,但我认为我有:

class DJ(models.Model):
    #other fields, no alias!

class DJAlias(models.Model):
    dj = models.ForeignKey(DJ)

这将允许您为同一个 dj 拥有多个别名。

但是您仍然需要找到一种正确的方法来确保将别名添加到正确的 dj。见多米尼克的帖子。

但是,如果您检查一个别名与指向一个 dj 的其他几个别名,算法可能会更好。

于 2010-01-21T15:23:13.910 回答
1

如何将模型更改为“别名”,使其成为其他表的键列表,如下所示(跳过“the”、“and”等小词): 1 => Above; 2 => 超越;3 => 磁盘;4 => 玩笑;

然后,当您要插入新记录时,只需检查表中已有多少标题中的重要单词并匹配当前存在的模型实体。如果超过 50%(例如),您可能会遇到巧合,您可以向访问者展示他们的列表并询问“您是指其中的一些吗”。

于 2010-01-23T15:47:13.417 回答
0

看起来fuzzywuzzy非常适合您的需求。

本文解释了设置它的原因,它非常符合您的要求 - 基本上,用于处理两个不同事物名称略有不同的情况:

我们最令人沮丧的问题之一是试图弄清楚两个门票清单是否是针对同一个现实生活中的事件(也就是说,没有得到我们实习生大军的帮助)。
...<br> 为了实现这一点,我们建立了一个“模糊”字符串匹配例程库来帮助我们。

于 2012-11-07T18:28:32.403 回答
0

如果您只关注艺术家姓名或通常与媒体相关的名称,那么使用 last.fm 或 echonest 的 API 可能会更好,因为它们已经拥有庞大的规则集和庞大的数据库可供选择。

于 2012-11-08T10:15:54.960 回答