使用scikit-learn预测有趣文章

2 投票
1 回答
951 浏览
提问于 2025-04-28 07:16

我正在尝试建立一个算法,能够根据我之前喜欢的文章来预测我是否会喜欢一篇新文章。

举个例子:

  • 我读了50篇文章,喜欢了其中10篇。我告诉我的程序我喜欢这些文章。
  • 然后有20篇新文章出现。我的程序需要根据我之前喜欢的10篇文章,给每篇新文章一个“喜欢的百分比”。

我在这里找到了一些线索:Python: tf-idf-cosine: 用于查找文档相似性

>>> 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%的词可能在小向量中找不到。

所以我的问题是:余弦相似度是怎么计算的?你觉得我这个项目有没有更好的方法?

暂无标签

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这样的分数计数也可能有效。

撰写回答