2012-07-18 63 views
2

假设我们有这样一个数据库:获取在MySQL数据库中重复最多的类似领域

Actions_tbl:

 
-------------------------------------------------------- 
id | Action_name        | user_id| 
-------------------------------------------------------- 
1 | John reads one book      | 1  
2 | reading the book by john    | 1 
3 | Joe is jumping over fire    | 2 
4 | reading another book     | 2 
5 | John reads the book in library   | 1 
6 | Joe read a book      | 2 
7 | read a book        | 3 
8 | jumping with no reason is Ronald's habit| 3 

Users_tbl:

 
----------------------- 
user_id | user_name | 
----------------------- 
1  |  John 
2  |  Joe 
3  |  Ronald 
4  |  Araz 
----------------------- 

想知道我可以选择最重复的类似行动章程无用的用户,并用其当前用户替换我自己的user_name!

阅读一本书,读这本书,读另一本书,在图书馆读书,读一本书,读一本书是最常用的单词,所以与阅读本书有关的工作人员重复6次,我的系统应显示这六个句子的一个随机与USER_NAME取代阿拉兹

像:阿拉兹读的书

我的想法是

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() 

但是这个根本没有表现!

假设我想为大分贝和少数不同的表做同样的事情。 这将摧毁我的服务器!

还有什么更好的IDEA?

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

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


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

  1. 我m仅限于PHP和MySQL。

  2. 这只是一个例子,在我的实际项目的行动很长的段落。这就是为什么表现是一个问题。真实的情况是:用户输入其项目的描述了几个项目,这些数据可能是太相似(用户必须在同一工作区域),我想,以填补自动(以前的馅料基地)的下一个项目的描述,为了省时间。

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

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


感谢您的知识产权的答案,它真的很感激,如果你能在情况

+0

这里是一个例子:http://stackoverflow.com/questions/4671378/levenshtein-mysql-php – mdo 2012-07-18 09:39:28

+0

检查mysql中的soundex函数。这可以帮助你imo。 – 2012-07-18 09:44:34

+0

@mdo,谢谢,我之前检查过,它的一个术语和字段之间的相似性是我想要的所有行之间的相似性 – 2012-07-18 09:49:16

回答

2

你所谈论的是一个文本聚类过程提供一些线索。您正在尝试查找类似的文本片段,并随意选择其中一个文本。我不熟悉任何采用这种形式的文本挖掘的数据库。

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

如果您的词汇量有限,并且在表格中包含词汇,您可以通过重叠单词的比例来衡量两个操作之间的距离。你有行动中所有单词的清单吗?

+0

感谢您的建议,这张表只是一个样本,其实在现实中,我有一个包含长段的表格,每个段落可以超过10行,表格会有很多这样的!你认为它的实用性列出所有的单词,并做你的话吗?有什么样的PHP? – 2012-07-18 15:46:55

+0

此外,我正在实施某种自动填充,因此系统可以根据用户以前提供的数据填写表格。 – 2012-07-18 15:53:46

+0

您的问题比直接通过数据库解决的问题要复杂得多。你需要一个应用程序。如果您正在使用SAS,则可以查看SAS Text Miner。如果你有表格的列表,并且希望找到最接近每个段落的表格,那么你可以用一包字母的方法做到这一点。无论如何,你都有一个问题,即关系数据库不是为解决问题而设计的(尽管它们可以是解决方案的一部分)。 – 2012-07-18 15:57:57

1

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

如果您只比较一个输入与您的数据库,然后我希望levenshtein距离计算速度足够快到中等数据库大小。除非存储某种形式的关于文本库的当前内容的中间数据结构,否则可能没有办法更快地完成任务。对每个新输入重新计算任何东西可能同样昂贵。

如果你想对每一对进行比较,那么每个对的levenshtein计算将花费太多时间。你必须设计一些其他的相似概念。我想到的第一件事情,对某种词的不同形式有一定的适应能力,那就是suffix tree。您可以将所有段落插入到该树中。如果后缀树通常存储单个指针,则可能需要存储一对索引,一个标识数据库行,另一个指示该行文本中的位置。在构建树之后,可以遍历它以识别常见的子字符串,并为相应的对增加一些相似度计数器。你将不得不试验一下来调整这个措施。在增加计数器之前,您可能需要为公共字符串添加最小长度。长文本即使在语义上不相关的情况下也具有较大的常用单词的机会,您可能需要以某种方式补偿长度。我怀疑有一种规范的方式来做到这一点。

term-document matrix方法suggested by Gordon听起来很有趣,你也应该可以在PHP中实现它。即使根目录是相同的,这种方法也会对词形的变化敏感。另一方面,为数据库中存储的矩阵保留一个合适的矩阵可能更容易,并且在更新主文本表时保持该结构同步。这两种方法都与levenshtein距离有着根本的区别:他们不关心整体秩序。我相信这对你来说是件好事,因为他们会考虑这样的文字:“约翰在湖中游泳后读了一本书”,更类似于“在湖中游泳后,乔读了一本书”将。

你的例子表明你不仅要排列相似性,还要决定边缘的边界,即。说“这些形成一个群体”和“那些属于不同群体”。这不会有一个干净的截断点,所以你也必须尝试启发式算法。除非总是选择最相似的文本或最相似的文本,否则对于您的应用程序就足够了。在任何情况下,我都会先专注于相似性计算,然后添加诸如用户名替换之类的内容。

+0

感谢您的评论,是的,我想比较我的表中的所有行以找到最常见的行,然后选择其中一个作为输出 – 2012-07-26 09:46:10

+0

这里,一个适当的排名是不需要的(不像http://stackoverflow.com/questions/11609348/advance-query-rank-most-related-fields-in-mysql)我们可以应用像你在那里提到的相同的东西。检查所有行(通过左连接)并通过运行一个过程来查找类似的行(如果行类似,则返回true)。问题是如何编写该过程?我不能让字典导致单词不受限制,我无权访问插入事件(我的应用程序是插件)使用其他应用程序输入数据 – 2012-07-26 10:41:44

+0

关于选择,从常见的相似行中随机选择就足够了SELECT * FROM'table' ORDER BY RAND( )LIMIT 0,1;其中表是最常见的类似的行。 [阅读一本书|读书|读另一本书|在图书馆阅读这本书|读一本书|在我们的例子中阅读一本书]。 – 2012-07-26 10:54:52