String 查找具有相似文本的文章的算法
我在数据库中有很多文章(有标题、文本),我正在寻找一种算法来查找X篇最相似的文章,就像Stack Overflow在你提问时的“相关问题” 我试着用谷歌搜索这篇文章,但只找到了关于其他“相似文本”问题的页面,比如将每篇文章与所有其他文章进行比较,并将相似性存储在某个地方。在我刚刚输入的文本上,这是“实时”的String 查找具有相似文本的文章的算法,string,algorithm,text,language-agnostic,similarity,String,Algorithm,Text,Language Agnostic,Similarity,我在数据库中有很多文章(有标题、文本),我正在寻找一种算法来查找X篇最相似的文章,就像Stack Overflow在你提问时的“相关问题” 我试着用谷歌搜索这篇文章,但只找到了关于其他“相似文本”问题的页面,比如将每篇文章与所有其他文章进行比较,并将相似性存储在某个地方。在我刚刚输入的文本上,这是“实时”的 如何进行?您可以使用SQL Server全文索引进行智能比较,我相信使用ajax调用也是如此,它执行查询以返回类似的问题 你在使用什么技术?这里的教程听起来可能正是你所需要的。这是很容易遵循
如何进行?您可以使用SQL Server全文索引进行智能比较,我相信使用ajax调用也是如此,它执行查询以返回类似的问题 你在使用什么技术?这里的教程听起来可能正是你所需要的。这是很容易遵循和工作得很好
他的算法既奖励普通的子字符串,也奖励这些子字符串的普通顺序,因此应该很好地挑选出类似的标题。我建议使用一个完全用Java编写的高性能、全功能文本搜索引擎库为您的文章编制索引。这项技术几乎适用于任何需要全文搜索的应用程序,尤其是跨平台的应用程序。编制索引后,您可以很容易地找到相关文章。仅在标题上进行比较,而不在问题正文上进行比较,因此仅在较短的字符串上进行比较 你可以在文章标题和关键词上使用他们的算法(不知道它是什么样子)。
如果您有更多的cpu时间需要消耗,也可以在文章摘要上使用。支持Lucene对全文的建议,但请注意java不是必需的。另请参阅,以获取指向其他项目的链接,包括。也许您正在寻找的是一些有用的东西。我对这一点只有粗略的了解,但释义是一个概念,用来确定文本中的两段是否真的意味着同一件事——尽管可能使用完全不同的词
不幸的是,我不知道有什么工具可以让你做到这一点(尽管我很有兴趣找到一个)如果你想寻找伤害相似的单词,你可以转换为soundex和soundex单词来匹配。。。为我工作这取决于你对相似者的定义 该算法是(拉丁语)词典建议的标准算法,可以处理整个文本。如果两篇文章的单词(字母)顺序基本相同,那么它们就是相似的。因此,以下两篇书评将相当相似: 1) “这是一本好书” 2) “这些不是好书” (要删除、插入、删除或更改以将(2)转换为(1)的字母数称为“编辑距离”。) 要实现这一点,您需要以编程方式访问每个评论。这可能不像听起来那么昂贵,如果成本太高,您可以作为后台任务进行比较,并将最相似的n个存储在数据库字段中 另一种方法是了解一些(拉丁)语言的结构。如果去掉短词(非大写或引号),并为常用或唯一的词(或前缀)指定权重,则可以进行贝叶斯比较。以下两个书评可能是相似的,并且被发现是相似的: 3) “法国大革命是空谈战争和平空谈法国。”->法国/法国(2)大革命(1)战争(1)和平 4) “这本书简直是法国烹饪的一场革命。”->法国(1)革命(1) 要实现这一点,您需要在创建/更新评论时识别评论中的“关键字”,并在查询的where子句中使用这些关键字(如果数据库支持,最好是“全文”搜索),并可能对结果集进行后处理,以对找到的候选项进行评分
书籍也有分类——以法国为背景的惊悚片是否与法国历史研究相似,等等?标题和文本之外的元数据可能有助于保持结果的相关性。使用的一种常见算法是。 这是一种神经网络,可以自动对文章进行分类。然后,您可以简单地找到当前文章在地图中的位置,并且它附近的所有文章都是相关的。该算法的重要部分是如何实现。有几种处理文本的方法。你可以散列你的文档/标题,你可以计算单词数,并将其用作n维向量,等等。希望这能有所帮助,尽管我可能已经为你打开了一个潘多拉盒子,告诉你AI的无尽旅程。不太可能是候选项,因为它取决于拼写/词序,考虑到您实际感兴趣搜索的文档的大小和数量,计算成本比Will让您相信的要高得多
像Lucene这样的东西是最好的选择。为所有文档编制索引,然后当希望查找与给定文档类似的文档时,将给定文档转换为查询,并搜索索引。Lucene将在内部使用和,以使整个过程花费的时间与可能匹配的文档数量成比例,而不是集合中的文档总数。我尝试了一些方法,但没有一种效果很好。可能会得到这样一个相对满意的结果: 首先:为所有文本的每个段落获取一个Google SimHash代码,并将其存储在数据库中。 第二:SimHash代码的索引。 第三:如上所述处理要比较的文本,得到一个SimHash码,并通过SimHash索引搜索所有文本,该索引以5-10的汉明距离分开。然后将相似性与术语向量进行比较。
这可能适用于大数据。比较摘要之间相似性的最简单、最快速的方法可能是利用集合概念。首先将抽象文本转换成一组单词。然后检查每套有多少
class Statistics {
std::unordered_map<std::string, int64_t> _counts;
int64_t _totWords;
void process(std::string& token);
public:
explicit Statistics(const std::string& text);
double Dist(const Statistics& fellow) const;
bool IsEmpty() const { return _totWords == 0; }
};
namespace {
const std::string gPunctStr = ".,;:!?";
const std::unordered_set<char> gPunctSet(gPunctStr.begin(), gPunctStr.end());
}
Statistics::Statistics(const std::string& text) {
std::string lastToken;
for (size_t i = 0; i < text.size(); i++) {
int ch = static_cast<uint8_t>(text[i]);
if (!isspace(ch)) {
lastToken.push_back(tolower(ch));
continue;
}
process(lastToken);
}
process(lastToken);
}
void Statistics::process(std::string& token) {
do {
if (token.size() == 0) {
break;
}
if (gPunctSet.find(token.back()) != gPunctSet.end()) {
token.pop_back();
}
} while (false);
if (token.size() != 0) {
auto it = _counts.find(token);
if (it == _counts.end()) {
_counts.emplace(token, 1);
}
else {
it->second++;
}
_totWords++;
token.clear();
}
}
double Statistics::Dist(const Statistics& fellow) const {
double sum = 0;
for (const auto& wordInfo : _counts) {
const std::string wordText = wordInfo.first;
const double freq = double(wordInfo.second) / _totWords;
auto it = fellow._counts.find(wordText);
double fellowFreq;
if (it == fellow._counts.end()) {
fellowFreq = 0;
}
else {
fellowFreq = double(it->second) / fellow._totWords;
}
const double d = freq - fellowFreq;
sum += d * d;
}
return std::sqrt(sum);
}