【问题标题】:How to efficiently find similar documents如何有效地找到相似的文件
【发布时间】:2015-07-14 09:27:06
【问题描述】:

我有很多使用聚类算法聚类的文档。在聚类算法中,每个文档可能属于多个聚类。我创建了一个存储document-clusterassignment 的表和另一个存储cluster-document 信息的表。当我查找与给定文档相似的文档列表时(让我们坐下d_i)。我首先检索它所属的集群列表(从document-cluster 表中),然后对于document-cluster 中的每个集群c_j,我从cluster-document 表中检索属于c_j 的文档列表。 c_j 不止一个,所以很明显会在多个列表中。每个列表都有许多文档,显然这些列表之间可能存在重叠。

在下一阶段,为了找到与 d_i 最相似的文档,我根据它们与 d_i 的共同聚类数对相似文档进行排名。

我的问题是关于最后一个阶段。一个天真的解决方案是创建一种排序类型的 HashMap,其中文档作为键,# common clusters 作为值。但是,由于每个列表可能包含许多文档,因此这可能不是最佳解决方案。有没有其他方法可以对类似项目进行排名?任何预处理或..?

【问题讨论】:

  • 定义相似。您是在寻找语义相似的东西,还是几乎重复的东西?如果是后者,则欺骗:stackoverflow.com/q/23053688/572670
  • 就我个人而言,如果您能在问题中添加 details 将会对我有很大帮助。 (保留这个问题,并在同一个线程中添加另一个问题。)更详细地说明你所做的事情。 “我来自密苏里……show我。”然后,您的问题将更容易获得所需的良好答案。
  • 让我总结一下我的问题:我有多个大尺寸数组。数组的元素有重叠(例如,一个元素可能存在于多个数组中)。我想创建一个所有数组元素的排序列表,排序标准是每个元素的出现次数。最简单的方法是创建一个排序的 hashmap,但考虑到数组的大小,这可能不是很有效。有更好的方法吗?

标签: java performance algorithm information-retrieval tf-idf


【解决方案1】:

假设数组的数量与元素的数量相比相对较少(特别是数组的数量在o(logn)),你可以通过修改bucket sort来做到这一点:

设 m 为数组的数量 创建一个包含 m 个桶 buckets[] 的列表,其中每个 bucket[i] 是一个哈希集

for each array arr:
   for each element x in arr:
      find if x is in any bucket, if so - let that bucket id be i:
          remove x from bucket i  
          i <- i + 1
      If no such bucket exist, set i=1
      add x to bucket i

for each bucket i=m,m-1,...,1 in descending order:
   for each element x in bucket[i]:
      yield x

以上运行时间为 O(m^2*n):

  • 遍历每个数组
  • 遍历每个数组中的所有元素
  • 找到相关的桶。

请注意,最后一个可以通过添加 map:element->bucket_id 来完成,并且使用哈希表在 O(1) 内完成,因此我们可以将其改进为 O(m*n)


另一种方法是将哈希图用作从元素映射到其出现次数的直方图,然后根据直方图对包括所有元素的数组进行排序。这种方法的好处:它可以通过map-reduce很好地分发:

map(partial list of elements l):
    for each element x:
       emit(x,'1')
reduce(x, list<number>):
   s = sum{list}
   emit(x,s)
combine(x,list<number>):
   s = sum{list} //or size{list} for a combiner
   emit(x,s)

【讨论】:

  • 这是否比 O(n) 传递创建直方图(哈希图),然后是 O(n log n) 排序的天真方法要好得多?如果 m 在o(log n) 中,则O(m*n)O(n log n) 之间没有渐近 差异。当然,现实世界的运行时间可能会有很大不同。我对做出这种判断的算法的复杂性没有很好的感觉。
  • @JimMischel (1) 有。它是小 O 符号,而不是大 O 符号。 (2) 注意这里n是每个列表的平均元素个数,而不是元素的总数,所以如果#uniques很高,天真的复杂度是O(nmlog(nm)) ~= O(nmlog(n)假设m &lt; n,所以你还是保存增加了logn。直观地,注意桶排序在数据大小上是线性的,假设m&lt;n,似乎就是这样。
  • 感谢您的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-08
  • 2016-03-30
  • 2012-01-20
  • 2019-03-10
相关资源
最近更新 更多