获取MySQL数据库中重复次数最多的类似字段


Get the most repeated similar fields in MySQL database

让我们假设我们有一个数据库,如:

动作_tbl:

--------------------------------------------------------id |操作名称|用户id|--------------------------------------------------------1|约翰读了一本书|12|阅读约翰的书|13|乔正在跳火|24|正在阅读另一本书|25|约翰在图书馆看书|16|乔看书|27|看书|38 |罗纳德的习惯是无缘无故地跳|3

用户_tbl:

-----------------------user_id |用户名称|-----------------------1|约翰2|乔3|罗纳德4|Araz-----------------------

想知道我是否可以选择重复次数最多的类似操作,而不管它的用户是谁,并用它的当前用户替换我自己的user_name!

读一本书,读这本书,再读一本,在图书馆里读这本,读一本和读一本是最常见的单词,所以与阅读这本书相关的工作人员被重复6次,我的系统应该随机显示这六个句子中的一个,并将Araz替换为user_name

喜欢:Araz读这本书

我的想法是

select replace(a.action_name , b.user_name) from actions_tbl a, user_tble b where a.user_id = b.user_id group_by

然后使用在php中逐一检查相似性

levenshtein()

但是这个根本没有表演!

假设我想对一个大数据库和几个不同的表做同样的事情。这将摧毁我的服务器!!!

有更好的想法吗?

在http://www.artfulsoftware.com/infotree/queries.php#552这个levenstein()函数是作为MySQL函数实现的,但首先,你认为它有足够的性能吗?然后,如何在我的情况下使用它?也许一辆自加入的面包车可以解决这个问题,但我对sql不太好!

*类似的动作,是指具有超过X%的常用词的动作


**更多信息和注意事项:**

  1. 我仅限于PHP和MySQL。

  2. 这只是一个例子,在我的真实项目中,动作是很长的段落。这就是为什么表演是一个问题。真实的场景是:用户输入了几个项目的项目描述,这些数据可能太相似(用户的工作领域相同),我想自动填充(基于以前的填充)下一个项目的描述,以节省时间。

  3. 如果您能提供任何实用解决方案,我将不胜感激。我检查了与NLP相关的解决方案,尽管它们很有趣,但我不认为其中很多是准确的,并且可以使用PHP实现。

  4. 输出应该有意义,并且像所有其他项目一样是一个合适的段落。这就是为什么我想从以前的选择。


感谢您的智慧回答,如果您能阐明以下情况,我们将不胜感激

您所说的是文本聚类过程。你试图找到相似的文本片段,并任意选择其中一个。我不熟悉任何可以进行这种形式的文本挖掘的数据库。

对于您所描述的内容,一种非常基本的文本挖掘技术可能会起作用。创建一个术语文档矩阵,其中包含除用户名之外的所有单词。然后使用奇异值分解得到最大的奇异值和向量(这是相关矩阵的第一个主分量)。类似的活动应该沿着这条线聚集在一起。

如果你的词汇量有限,并且表中有这些术语,你可以通过重叠单词的比例来衡量两个动作之间的距离。你有行动中所有单词的清单吗?

首先,您必须决定是将给定的输入与所有现有文本进行比较,还是对所有文本进行成对比较。你的问题要求后者,但你概述的应用程序听起来更像前者。

如果你只将单个输入与数据库进行比较,那么我希望Levenstein距离计算在中等数据库大小下足够快。除非存储某种形式的关于文本库当前内容的中间数据结构,否则可能没有什么方法可以加快速度。为每一个新的输入重新计算任何东西都可能同样昂贵。

如果你想对每一对进行比较,那么对它们进行Levenstein计算会花费太多时间。你必须想出一些其他相似性的概念。我首先想到的是后缀树,它对一个词的不同形式有一定的弹性。你可以将所有段落插入到树中。在后缀树通常存储单个指针的情况下,您可能希望存储一对索引,一个标识数据库行,另一个表示该行文本中的位置。在构建树之后,您可以遍历它来识别常见的子字符串,并为相应的对增加一些相似性计数器。你必须做一些实验来调整这个度量。在递增计数器之前,您可能需要为公共字符串设置一个最小长度。由于长文本有更大的机会出现常见单词,即使它们在语义上不相关,你可能不得不以某种方式补偿长度。我怀疑是否有规范的方法可以做到这一点。

Gordon提出的术语文档矩阵方法听起来也很有趣,您也应该能够在PHP中实现它。即使词根相同,这种方法也会对单词形式的变化更敏感。另一方面,为数据库中存储的矩阵保留一个合适的矩阵可能会更容易,并在更新主文本表时保持该结构的同步。这两种方法都与Levenstein距离有根本区别:它们不太关心整体秩序。我相信,在你的情况下,这是一件好事,因为他们会认为"约翰在湖中游泳后读了一本书"这句话比Levenstein distance更像"在湖中游泳之后,乔读了一本书"。

你的例子表明,你不仅想对相似性进行排序,还想决定聚类边界,即说"这些组成一个组"answers"那些属于不同的组"。这不会有一个明确的界限,所以你也必须尝试启发式方法。除非总是选择最相似的文本,或者k最相似的文字,否则对于您的应用程序来说就足够了。在任何情况下,我都会先专注于相似性计算,然后添加用户名替换之类的内容。