2

我正在尝试构建一种算法,能够根据我以前喜欢的文章预测我是否会喜欢一篇文章。

例子:

  • 我读了 50 篇文章,我喜欢 10 篇。我告诉我的程序我喜欢它们。
  • 然后有 20 篇新文章来了。我的程序必须根据我之前喜欢的 10 篇文章为每篇新文章提供一个“喜欢百分比”。

我在这里找到了线索: Python: tf-idf-cosine: to find document similarity

>>> from sklearn.feature_extraction.text import TfidfVectorizer
>>> from sklearn.datasets import fetch_20newsgroups
>>> twenty = fetch_20newsgroups()
>>> tfidf = TfidfVectorizer().fit_transform(twenty.data)

然后,将数据集的第一个文档与数据集中的其他文档进行比较:

>>> from sklearn.metrics.pairwise import linear_kernel
>>> cosine_similarities = linear_kernel(tfidf[0:1], tfidf).flatten()
>>> cosine_similarities
array([ 1.        ,  0.04405952,  0.11016969, ...,  0.04433602,
    0.04457106,  0.03293218])

对于我的情况,我想我会做的是连接我的 10 篇文章的文本,运行 TfidfVectorizer,然后将新的大向量与每篇新文章进行比较。

但我想知道如何进行比较:

  • 大向量(10 篇文章)与小向量相比或
  • 小个子和大个子的比较

我不知道你是否明白我的意思,但在第一种情况下,大向量中 90% 的单词不会出现在小向量中。

所以我的问题是:余弦相似度是如何计算的?您认为我的项目有更好的方法吗?

4

1 回答 1

4

朴素贝叶斯分类器应该表现更好。您的问题类似于经典的垃圾邮件分类问题。在您的情况下,您不是在识别垃圾邮件(您不喜欢什么),而是在识别火腿(您喜欢什么文章)。

从前 50 篇带标签的文章中,很容易计算出以下统计数据:

p(word1|like)   -- among all the articles I like, the probability of word1 appears
p(word2|like)   -- among all the articles I like, the probability of word2 appears
...
p(wordn|like)   -- among all the articles I like, the probability of wordn appears

p(word1|unlike) -- among all the articles I do not like, the prob of word1 appears
...

p(like)  -- the portion of articles I like (should be 0.2 in your example)
p(unlike) -- the portion of articles I do not like. (0.8)

然后给出第 51 个新示例,您应该在其中找到所有看到的单词,例如,它只包含 word2 和 word5。朴素贝叶斯的好处之一是它只关心词汇表中的单词。甚至大向量中超过 90% 的词都不会出现在新向量中,这不是问题,因为所有不相关的特征都会相互抵消而不影响结果。

似然比将是

   prob(like|51th article)      p(like) x p(word2|like) x p(word5|like)
 ---------------------------- = -----------------------------------------
   prob(unlike|51th article)    p(unlike)xp(word2|unlike)xp(word5|unlike)

只要比率> 1,您就可以将文章预测为“喜欢”。此外,如果您想提高识别“喜欢”文章的精度,您可以通过将阈值比值从 1.0 增加到更大的值来发挥精度-召回平衡。另一方面,如果要提高召回率,可以降低阈值等。

有关文本域中朴素贝叶斯分类的进一步阅读,请参见此处

该算法可以很容易地修改为进行在线学习,即一旦用户“喜欢”或“不喜欢”新示例,就更新学习模型。由于上述统计表中的每一件事基本上都是标准化的计数。只要您保留每个计数(每个单词)和保存的总计数,您就可以在每个实例的基础上更新模型。

要将单词的tf-idf 权重用于朴素贝叶斯,我们将权重视为单词的计数。即没有tf-idf,每个文档中的每个单词都计为1;使用 tf-idf,文档中的单词被计为它们的 TF-IDF 权重。然后,您使用相同的公式获得朴素贝叶斯的概率。这个想法可以在这篇论文中找到。我认为scikit-learn 中的多项朴素贝叶斯分类器应该接受 tf-idf 权重作为输入数据。

请参阅 MultinomialNB 的评论:

多项式朴素贝叶斯分类器适用于具有离散特征的分类(例如,用于文本分类的字数)。多项分布通常需要整数特征计数。但是,在实践中,诸如 tf-idf 之类的小数计数也可能起作用。

于 2014-10-19T07:05:24.037 回答