推荐相关文章的尝试算法有哪些?
machine-learning
4
0

我敢打赌,这是很普遍的情况。您有一个博客或新闻网站,并且有大量文章或b俩或任何您称呼的文章,并且您想在每篇文章的底部建议其他似乎相关的文章。

假设每个项目的元数据很少。也就是说,没有标签,类别。视为一大段文字,包括标题和作者姓名。

您如何查找可能的相关文档?

我对实际的算法感兴趣,而不是现成的解决方案,尽管我可以看看用ruby或python实现的东西,还是依赖mysql或pgsql。

编辑:当前答案是相当不错,但我想看到更多。也许一两个东西的一些真正的示例代码。

参考资料:
Stack Overflow
收藏
评论
共 4 个回答
高赞 时间 活跃

您应该阅读《编程集体智慧:构建智能Web 2.0应用程序》(ISBN 0596529325)!

对于某些方法和代码:首先问自己,是否要基于单词匹配找到直接相似性,还是要显示可能与当前文章不直接相关,但属于同一类文章的相似文章。

请参阅聚类分析/分区聚类

查找直接相似性的非常简单(但理论上又缓慢)的方法是:

预处理:

  1. 按文章存储平面词列表(请勿删除重复的词)。
  2. “交叉连接”文章:计算文章A中与文章B中相同词匹配的词数。您现在有了一个矩阵int word_matches[narticles][narticles] (您不应该那样存储它,A-> B相似与B-> A相同,因此稀疏矩阵可节省近一半的空间)。
  3. 将word_matches计数标准化为范围0..1! (查找最大数量,然后将任何数量除以该数量)-您应该在其中存储浮点数,而不是int;)

查找类似的文章:

  1. 从word_matches中选择匹配度最高的X篇文章
收藏
评论

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正确了吗?)

顺便说一句,示例文档摘自Deerwester等人的SVD论文:)

收藏
评论

这是一个很大的话题-除了人们在这里提出的答案之外,我还建议您跟踪一些信息检索课程的教学大纲,并检查分配给他们的教科书和论文。也就是说,这是我自己读研究生时的简要概述:

最简单的方法称为单词袋 。每个文档都被简化为{word: wordcount}对的稀疏向量,并且您可以在代表您的文档集合的向量集合处抛出NaiveBayes(或其他)分类器,或者计算每个袋子与其他袋子之间的相似性得分袋(这称为k最近邻分类)。 KNN的查找速度很快,但需要O(n ^ 2)来存储分数矩阵。但是,对于博客而言,n并不是很大。对于大型报纸而言,KNN很快就变得不切实际,因此动态分类算法有时会更好。在这种情况下,您可以考虑使用排名支持向量机 。 SVM整洁,因为它们不限制您进行线性相似性度量,而且速度仍然很快。

词干处理是词袋技术的常见预处理步骤。这涉及在计算单词袋之前,将与词法相关的词(例如“猫”和“猫”,“鲍勃”和“鲍勃”或“相似”和“相似”)减少到其词根。那里有很多不同的词干算法。 Wikipedia页面具有指向多个实现的链接。

如果单词袋相似度不够好,则可以将其抽象为N-grams袋相似度,然后在此基础上创建基于单词对或三元组表示文档的向量。 (您可以使用4元组甚至更大的元组,但实际上并没有太大帮助。)这具有产生较大矢量的缺点,因此分类将花费更多的工作,但是获得的匹配将更接近句法上。 OTOH,出于语义相似性,您可能不需要它。最好用于窃检测之类的东西。也可以使用分块 (或将文档简化为轻量级的解析树)(有树的分类算法),但这对于诸如作者身份问题(“给定来源不明的文档,是谁写的?”之类的东西)更有用。 )。

也许对您的用例更有用的是概念挖掘,它涉及将单词映射到概念(使用诸如WordNet这样的词库),然后根据所使用概念之间的相似性对文档进行分类。由于从单词到概念的映射是简化的,因此这通常最终比基于单词的相似性分类更有效,但是预处理步骤可能会非常耗时。

最后,还有语篇解析 ,它涉及解析文档的语义结构。您可以像在分块文档上一样,在话语树上运行相似性分类器。

这些几乎都涉及从非结构化文本生成元数据。在原始文本块之间进行直接比较是很棘手的,因此人们首先将文档预处理为元数据。

收藏
评论

这是文档分类的一个典型案例,在每个机器学习课程中都进行了研究。如果您喜欢统计学,数学和计算机科学,我建议您看一下无监督方法,例如kmeans ++贝叶斯方法LDA 。特别是,贝叶斯方法非常适合您要寻找的东西,它们的唯一问题是运行缓慢(但是除非您运行的站点很大,否则您不会因此而烦恼)。

在一种更实用,更不理论的方法上,我建议您看看this其他出色的代码示例。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号