Text 关于推荐相关文章,有哪些行之有效的算法?

Text 关于推荐相关文章,有哪些行之有效的算法?,text,machine-learning,information-retrieval,document-classification,Text,Machine Learning,Information Retrieval,Document Classification,我敢打赌,这种情况相当普遍。你有一个博客或新闻网站,你有大量的文章或废话或其他你称之为的东西,你想在每一篇文章的底部,推荐那些似乎有关联的人 让我们假设每个项目的元数据很少。也就是说,没有标签,没有类别。将其视为一大块文本,包括标题和作者姓名 您如何着手查找可能相关的文档 我对实际的算法很感兴趣,而不是现成的解决方案,尽管我可以看看用ruby或python实现的东西,或者依赖mysql或pgsql 编辑:目前的答案很好,但我想看更多。这是一个相当大的主题——除了人们在这里给出的答案之外,我还建议

我敢打赌,这种情况相当普遍。你有一个博客或新闻网站,你有大量的文章或废话或其他你称之为的东西,你想在每一篇文章的底部,推荐那些似乎有关联的人

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

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

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


编辑:目前的答案很好,但我想看更多。这是一个相当大的主题——除了人们在这里给出的答案之外,我还建议大家追踪几门信息检索课的教学大纲,并查看分配给他们的课本和论文。也就是说,以下是我自己研究生时代的简要概述:

最简单的方法称为a。每个文档被简化为一个稀疏的
{word:wordcount}
对向量,您可以在表示文档集的向量集上抛出一个NaiveBayes(或其他)分类器,或者计算每个包和每个其他包之间的相似性分数(这称为k-最近邻分类)。KNN查找速度快,但分数矩阵需要O(n^2)存储;然而,对于一个博客来说,n并不是很大。对于大报纸大小的东西,KNN很快变得不切实际,因此动态分类算法有时更好。在这种情况下,您可能会考虑。支持向量机非常简洁,因为它们不会将您限制在线性相似性度量上,而且速度非常快

是单词袋技术的常见预处理步骤;这涉及到在计算单词包之前,将形态相关的单词(如“cat”和“cats”、“Bob”和“Bob's”或“相似”和“相似”)减少到词根。有很多不同的词干生成算法;Wikipedia页面有几个实现的链接

如果bag of words相似度不够好,可以将其抽象为bag of N-grams相似度,在该层中创建表示基于成对或三倍单词的文档的向量。(您可以使用4元组或更大的元组,但实际上这没有多大帮助。)这有一个缺点,即生成更大的向量,因此分类将需要更多的工作,但您得到的匹配在语法上会更接近。OTOH,你可能不需要这个来表示语义相似性;这对于像剽窃检测这样的东西更好,或者将文档简化为轻量级解析树,也可以使用(有树的分类算法),但这对于诸如作者身份问题(“给定一个未知来源的文档,是谁编写的?”)更有用

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

最后,还有一个问题,涉及到解析文档的语义结构;您可以在话语树上运行相似性分类器,就像在分块文档上运行相似性分类器一样


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

不久前,我实现了类似的方法。也许这个想法现在已经过时了,但我希望它能有所帮助

我运行了一个ASP 3.0网站来编写常见任务,并从以下原则开始:用户有疑问,只要他/她能找到关于该主题的有趣内容,他/她就会留在网站上

当用户到达时,我启动了一个ASP 3.0
会话
对象,并记录了所有用户导航,就像一个链表一样。在
Session.OnEnd
事件中,我获取第一个链接,查找下一个链接,并增加一个计数器列,如:

<Article Title="Cookie problem A">
    <NextPage Title="Cookie problem B" Count="5" />
    <NextPage Title="Cookie problem C" Count="2" />
</Article>

因此,为了查看相关文章,我只需列出前n个
NextPage
实体,按计数器列降序排列。

这是每一类机器学习中研究的典型案例。如果你喜欢统计学、数学和计算机科学,我建议你看看无监督的方法,比如,和。特别是,贝叶斯方法是在你正在寻找什么,他们唯一的问题是速度慢(但除非你运行一个非常大的网站,这不应该困扰你太多)


关于一种更实用、理论性更低的方法,我建议您查看一个优秀的代码示例。

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
的定义留给读者作为练习(应该处理零值和不同的长度,但是我们得到了
Array#zip
对吗?)

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

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

对于som