关于python:使用scikit-learn预测有趣的文章

Predict interesting articles with scikit-learn

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

示例:

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

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

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

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

1
2
3
4
5
>>> 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%的单词不会在小向量中。

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


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

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

1
2
3
4
5
6
7
8
9
10
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%的单词都不会出现在新单词中,这不是问题,因为所有不相关的特征在不影响结果的情况下会相互抵消。

似然比将为

1
2
3
   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的注释:

The multinomial Naive Bayes classifier is suitable for classification
with discrete features (e.g., word counts for text classification).
The multinomial distribution normally requires integer feature counts.
However, in practice, fractional counts such as tf-idf may also work.