2

假设我们有一个像这样的数据库:

Actions_tbl:

-------------------------------------------------- ------
编号 | 动作名称 | 用户ID|
-------------------------------------------------- ------
1 | 约翰读一本书 | 1     
2 | 阅读约翰的书| 高分辨率照片| CLIPARTO 1
3 | 乔跳过火| 2
4 | 读另一本书| 2
5 | 约翰在图书馆看书 | 1
6 | 乔读了一本书 | 2
7 | 读一本书| 3
8 | 无缘无故跳是罗纳德的习惯| 3

用户表:

----------------------
用户 ID | 用户名 |
----------------------
1 | 约翰
2 | 乔
3 | 罗纳德
4 | 阿拉兹
----------------------

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

读一本书,读一本书,再读一本书,在图书馆读一本书,读一本书和读一本书是最常见的单词,所以与读书相关的工作人员重复了6次,我的系统应该显示随机选择这六个句子之一并将 Araz 替换为 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 在 php 中一一检查相似之处

levenshtein()

但这一个根本没有表现!

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

有更好的想法吗?

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

* 相似动作,是有超过 X% 常用词的动作


**更多信息和说明:**

  1. 我仅限于 PHP 和 MySQL。

  2. 这只是一个例子,在我的真实项目中,动作是长段落。这就是为什么性能是一个问题。真实场景是:用户为多个项目输入了其项目的描述,这些数据可能过于相似(用户将有相同的工作领域),我想自动填写(基于之前的填写)下一个项目的描述,为了省时间。

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

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


感谢您的智慧回答,如果您能对这些情况有所了解,我们将不胜感激

4

2 回答 2

2

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

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

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

于 2012-07-18T13:22:09.277 回答
1

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

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

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

Gordon 建议术语-文档矩阵方法听起来也很有趣,您也应该能够在 PHP 中实现它。即使词根相同,这种方法也会对词形的变化更加敏感。另一方面,为存储在数据库中的矩阵保留一个合适的矩阵,并在更新主文本表时保持该结构同步可能会更容易。这两种方法都与 levenshtein distance 有根本的区别:它们不太关心整体顺序。我相信这对你来说是件好事,因为他们会认为“约翰在湖里游泳后读了一本书”比“在湖里游泳后,乔读了一本书”更类似于 levenshtein distance将。

您的示例表明您不仅要对相似性进行排名,还要确定集群边界,即“这些构成一个组”和“这些属于不同的组”。对此没有明确的界限,因此您还必须尝试使用​​启发式方法。除非总是选择最相似的文本,或者k个最相似的文本,对于您的应用程序来说就足够了。无论如何,我会先专注于相似度计算,然后再添加诸如用户名替换之类的东西。

于 2012-07-26T07:40:13.520 回答