我需要实现算法(或在开源库中找到一个)来评估文本的相似性。我需要一个有效的算法,给定两个任意文档集(相对较少的大块文本),以便在它们之间创建匹配对 - 哪个文档最有可能从哪个文档生成。
我相信我会把它分成两部分 - 定义每对的相似系数 - 然后应用一些赋值问题算法。对于分配算法,我可以找到很多解决方案,我找不到一个好的解决方案来计算相似系数。
请注意,文档事先是未知的 - 文本的计算索引(如果有)也必须快速。
我知道汉明距离,Levenshtein距离一些其他算法的字符串差异。这不是我想要的 - 我正在使用文字而不是字符串。
我不是在寻找短语搜索算法以及像Lucene和Xapian这样的库(至少看起来像是这样)。
可能基于tf-idf。
我想问题是,是否有某些东西已经解决了这个问题,或者是否有可能像lucete这样的库来做到这一点。
答案 0 :(得分:1)
以下是我要做的起点(仅仅因为它简单而快速):
我们可以假设字典大小是< 1m(或21bit),所以我们可以在int64中编码一个三元组。
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;
}
以某种方式将分数标准化可能是有意义的,例如除以三卦总数。