使用Python实现朴素贝叶斯分类器

3
我正在使用scikit-learn寻找文档的Tf-idf权重,然后使用朴素贝叶斯分类器对文本进行分类。但是,文档中所有单词的Tf-idf权重都是负数,除了一些例外。但就我所知,负值表示不重要的词语。那么,有必要将整个Tf-idf值传递给贝叶斯分类器吗?如果我们只需要传递其中的几个,该如何做?此外,与linearSVC相比,朴素贝叶斯分类器的表现更好还是更差?除了使用Tf-idf之外,是否有更好的方法来查找文本中的标签?
谢谢
3个回答

6
您有很多问题,但我会尽力帮助。
据我所记,TF-IDF不应为负值。TF是术语频率(一个术语在特定文档中出现的频率),而逆文档频率(语料库中的文档数/包含术语的文档数)。通常使用log加权。我们经常将分母加一以避免除以零。因此,唯一会得到负tf * idf的时间是如果该术语出现在语料库的每个文档中(这对搜索并不太有用,因为它不添加信息)。我建议您仔细检查您的算法。
给定术语t,文档d,语料库c:
tfidf = term freq * log(document count / (document frequency + 1))
tfidf = [# of t in d] * log([#d in c] / ([#d with t in c] + 1))

在机器学习中,朴素贝叶斯和支持向量机(SVM)都是好的工具——它们的质量取决于应用场景,我曾经做过一些项目,它们的准确性相当。朴素贝叶斯通常很容易手动实现——在尝试使用SVM库之前,我建议先尝试一下这个。

也许我漏掉了什么,但我不太确定我完全知道您要找什么——非常乐意修改我的答案。


另外,您对训练贝叶斯分类器有何看法?是否有必要使用整个文档的Tf-idf进行训练,还是仅使用具有较高Tf-idf值的单词的Tf-idf值即可? - jvc
首先,文档中大多数单词不应该是负面的。你的语料库有多大?在运行程序之前,显然要删除像“the”、“an”等停用词。我不确定你所说的标签是什么意思,但如果你指的是特征或类似功能的标签,那么我认为这是一个不错的方法。 - Chet
考虑到我们已经找到了1000个文档的tf-idf值,是否有办法使用这些权重来找到要分类的新文档的tf-idf值? - jvc
tf*idf基于词项-文档元组,因此除非您的语料库发生更改,否则您可以将其存储在(term,docid)=>value的字典中。 - Chet
我们如何使用这些数据来训练其他文档? - jvc
显示剩余2条评论

6

这个bug已经在主分支中被修复。需要注意的是,文本向量化API也进行了一些修改,以便更容易地自定义标记化。


有没有可能在Scikit中保存Bayes分类器的值和词汇表,从而使文档的分类变得更加容易? - jvc
保存贝叶斯分类器,我指的是训练会话后的单词概率权重。 - jvc
@jvc:你可以使用scikit-learn中的pickle将整个分类器对象进行序列化。 - Fred Foo

2

我也对这个主题很感兴趣。 当我使用贝叶斯分类(也许这篇俄语文章关于贝叶斯算法可以帮助你http://habrahabr.ru/blogs/python/120194/),我只使用文档中的前20个高频词。我尝试了很多值,但在我的实验中,前20个词获得了最佳结果。 此外,我将通常的tf-idf改为了以下内容:

def f(word):
    idf = log10(0.5 / word.df)
    if idf < 0:
        idf = 0
    return word.tf * idf

在这种情况下,“不良词汇”权重为0。

这可能只是掩盖问题的表象。@ogrisel指出了一个bug,这很有道理。大多数单词不应该有负值。 - Chet
这不是美白问题。因为我的权重词不是经典的tf-idf。而且它(idf)可以是负数。 - lavrton
哦,好的,如果它是不同类型的话。 - Chet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接