这种情况很常见。假设你有一个博客或新闻网站,有许多文章或博客或其他你称之为的内容,你想在每篇文章底部建议看起来相关的其他文章。
让我们假设每个项目都没有太多元数据。也就是说,没有标签、分类。将其视为一个大文本块,包括标题和作者名。
如何找到可能相关的文档呢?
我对实际算法非常感兴趣,而不是现成的解决方案,虽然我愿意查看用ruby或python实现的某些东西,或者依赖于mysql或pgsql。
编辑:目前的答案非常好,但我想看到更多。也许有一两个例子的真正基本代码。
这种情况很常见。假设你有一个博客或新闻网站,有许多文章或博客或其他你称之为的内容,你想在每篇文章底部建议看起来相关的其他文章。
让我们假设每个项目都没有太多元数据。也就是说,没有标签、分类。将其视为一个大文本块,包括标题和作者名。
如何找到可能相关的文档呢?
我对实际算法非常感兴趣,而不是现成的解决方案,虽然我愿意查看用ruby或python实现的某些东西,或者依赖于mysql或pgsql。
编辑:目前的答案非常好,但我想看到更多。也许有一两个例子的真正基本代码。
{word: wordcount}
对,您可以将NaiveBayes(或其他)分类器投向表示文档集合的向量集合,或者计算每个包与每个其他包之间的相似性得分(这称为k-nearest-neighbour分类)。KNN用于查找很快,但需要O(n^2)存储得分矩阵;然而,对于博客来说,n不是很大。对于像大报纸那样的东西,KNN很快变得不切实际,因此,即时分类算法有时更好。在这种情况下,您可以考虑使用排名支持向量机。SVM非常有用,因为它们不会限制您的线性相似度度量,并且仍然非常快。
Stemming是词袋技术的常见预处理步骤;这涉及到在计算词袋之前将形态上相关的单词,例如“cat”和“cats”,“Bob”和“Bob's”或“similar”和“similarly”缩小到它们的根。有许多不同的词干提取算法;维基百科页面链接到几个实现。int word_matches[narticles][narticles]
(您不应该像那样存储它,A->B的相似度与B->A相同,因此稀疏矩阵可以节省将近一半的空间)。
3. 将word_matches计数归一化为0..1范围! (找到最大计数,然后将任何计数除以此)-您应该在那里存储浮点数,而不是整数;)
查找相似文章:
一个用Ruby实现的小型向量空间模型搜索引擎。基本思想是如果两个文档包含相同的单词,则它们相关。因此,我们计算每个文档中单词的出现次数,然后计算这些向量之间的余弦值(每个术语都有一个固定的索引,如果出现则在该索引处为1,否则为零)。如果两个文档具有所有术语共同点,则余弦值为1.0,如果它们没有共同点,则余弦值为0.0。您可以直接将其转换为%值。
terms = Hash.new{|h,k|h[k]=h.size}
docs = DATA.collect { |line|
name = line.match(/^\d+/)
words = line.downcase.scan(/[a-z]+/)
vector = []
words.each { |word| vector[terms[word]] = 1 }
{:name=>name,:vector=>vector}
}
current = docs.first # or any other
docs.sort_by { |doc|
# assume we have defined cosine on arrays
doc[:vector].cosine(current[:vector])
}
related = docs[1..5].collect{|doc|doc[:name]}
puts related
__END__
0 Human machine interface for Lab ABC computer applications
1 A survey of user opinion of computer system response time
2 The EPS user interface management system
3 System and human system engineering testing of EPS
4 Relation of user-perceived response time to error measurement
5 The generation of random, binary, unordered trees
6 The intersection graph of paths in trees
7 Graph minors IV: Widths of trees and well-quasi-ordering
8 Graph minors: A survey
Array#cosine
的定义留给读者自己练习(应该要处理nil值和不同长度,但这个问题可以用Array#zip
来解决,对吧?)前段时间我实现了类似的东西。也许这个想法现在已经过时了,但我希望它能有所帮助。
我运行了一个ASP 3.0网站,用于编程常见任务,并从以下原则开始:用户有疑问,只要他/她能在该主题上找到有趣的内容,就会停留在网站上。
当用户到达时,我启动了一个ASP 3.0 Session
对象,并记录了所有用户导航,就像一个链接列表。在Session.OnEnd
事件中,我获取第一个链接,查找下一个链接并增加计数器列,例如:
<Article Title="Cookie problem A">
<NextPage Title="Cookie problem B" Count="5" />
<NextPage Title="Cookie problem C" Count="2" />
</Article>
所以,为了检查相关文章,我只需要列出前 n 个按计数器列降序排列的 NextPage
实体。