如何有效地找到类似的文件

时间:2015-05-04 20:38:10

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

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

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

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

1 个答案:

答案 0 :(得分: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-&gt; 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)