【问题标题】:algorithm/library for text similarity [closed]文本相似度的算法/库
【发布时间】:2013-05-11 20:40:29
【问题描述】:

我需要实现算法(或在开源库中找到一种算法)来评估文本相似性。对于给定的任意两组文档(相对较少的大文本块),我需要一种有效的算法,以便在它们之间创建匹配对 - 最有可能从哪个文档生成哪个文档。

我相信我会将其一分为二——定义每一对的相似系数——然后应用一些分配问题算法。虽然对于分配算法,我可以找到大量的解决方案,但我找不到用于计算相似系数的好解决方案。

请注意,文档是事先不知道的 - 文本的计算索引(如果有的话)也必须很快。

我知道 Hamming 距离、Levenshtein 距离以及其他一些用于字符串差异的算法。不过,这不是我想要的——我是故意使用文本这个词而不是字符串。

我不是在寻找短语搜索算法​​,也不是在寻找像 Lucene 和 Xapian 这样的库的用途(至少看起来如此)。

可能是基于 tf–idf 的东西。

我想问题是,是否有一些东西已经解决了这个问题,或者是否有可能使用像 lucete 这样的库来解决这个问题。

【问题讨论】:

标签: c++ algorithm text


【解决方案1】:

这是我将做的一个起点(只是因为它简单快捷):

  • 使用共享映射或 hash_map 将单词映射到数字
  • 为每个文本构建对应的词级三元组计数图
  • 比较重叠

我们可以假设字典大小是

void CountTrigrams(const vector<string>& words, 
                   map<string, int> * dict, 
                   map<int64, int> * result) {
  int64 trigram = 0;
  for (int i = 0; i < words.size(); i++) {
    const& word = words[i];
    int id;
    auto di = dict->find(word);
    if (di == dict->end()) {
      id = dict.size();
      dict[word] = id;
    } else {
      id = di->second;
    }
    trigram = ((trigram << 21) | id) & 0x7fffffffffffffff;
    if (i > 2) {
      auto ti = result->find(trigram);
      if (ti == result->end()) {
        result[trigram] = 1;
      } else {
        ti->second++;
      }
    }
  }
}

然后比较每一对的结果:

int Compare(const map<int64, int> & t1, const map<int64, int> & t2) {
  int score = 0;
  for (auto i = t1.first(); i != t1.end(); i++) {
    auto j = t2.find(t1->first);
    if (j != t2.end()) {
      score += MAX(i->second, j->second);
    }
  }
  return score;
}

以某种方式标准化分数可能是有意义的,例如除以三元组的总数。

【讨论】:

    猜你喜欢
    • 2011-08-13
    • 2023-03-27
    • 1970-01-01
    • 2011-09-17
    • 2017-02-28
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    相关资源
    最近更新 更多