美文网首页机器学习机器学习贝叶斯分类器
使用sklearn自带的贝叶斯分类器进行文本分类和参数调优

使用sklearn自带的贝叶斯分类器进行文本分类和参数调优

作者: YoghurtIce | 来源:发表于2016-01-18 20:57 被阅读13408次

    Part 1: 本篇内容简介

    在前一篇文章完全手写,自给自足完成贝叶斯文本分类中,我们使用首先假设在文档中出现的单词彼此独立,利用贝叶斯定理,完成了一个简单的文本分类器的编写,在真实数据的测试上,显示了良好的效果。
    其实要是了解sklearn的人都应该知道,这个python的机器学习库,实现了我们常用的大部分机器学习算法,免除了我们重复造轮子的痛苦。我们使用和上一篇博客同样的数据,使用sklearn自带的贝叶斯分类器完成文本分类,同时和上一篇文章手写的分类器,进行分类精度、速度、灵活性对比。

    Part 2: 朴素贝叶斯的在文本分类中常用模型:多项式、伯努利

    这部分的内容,我参考了朴素贝叶斯分类器的应用这篇文章。朴素贝叶斯分类器是一种有监督学习,常见有两种模型,多项式模型(multinomial model)即为词频型和伯努利模(Bernoulli model)即文档型。二者的计算粒度不一样,多项式模型以单词为粒度,伯努利模型以文件为粒度,因此二者的先验概率和类条件概率的计算方法都不同。计算后验概率时,对于一个文档d,多项式模型中,只有在d中出现过的单词,才会参与后验概率计算,伯努利模型中,没有在d中出现,但是在全局单词表中出现的单词,也会参与计算,不过是作为“反方”参与的。这里暂不虑特征抽取、为避免消除测试文档时类条件概率中有为0现象而做的取对数等问题。

    Part 2.1: 多项式模型

    多项式模型

    Part 2.2: 伯努利模型

    伯努利模型

    Part 2.3: 两个模型的区别

    4.png

    Part 3:在真实数据上的实验结果

    和上一篇博客一样,我使用相同的数据,我这里使用在康奈尔大学下载的2M影评作为训练数据和测试数据,里面共同、共有1400条,好评和差评各自700条,我选择总数的70%作为训练数据,30%作为测试数据,来检测sklearn自带的贝叶斯分类器的分类效果。数据的下载链接见前一篇博客,或者直接邮件找我。

    def get_dataset():
        data = []
        for root, dirs, files in os.walk(r'E:\研究生阶段课程作业\python\好玩的数据分析\朴素贝叶斯文本分类\tokens\neg'):
            for file in files:
                realpath = os.path.join(root, file)
                with open(realpath, errors='ignore') as f:
                    data.append((f.read(), 'bad'))
        for root, dirs, files in os.walk(r'E:\研究生阶段课程作业\python\好玩的数据分析\朴素贝叶斯文本分类\tokens\pos'):
            for file in files:
                realpath = os.path.join(root, file)
                with open(realpath, errors='ignore') as f:
                    data.append((f.read(), 'good'))
        random.shuffle(data)
    
        return data
    
    data = get_dataset()
    

    以上的代码就是读取全部数据,包括训练集和测试集,并随机打乱,返回打乱后的结果。

    def train_and_test_data(data_):
        filesize = int(0.7 * len(data_))
        # 训练集和测试集的比例为7:3
        train_data_ = [each[0] for each in data_[:filesize]]
        train_target_ = [each[1] for each in data_[:filesize]]
    
        test_data_ = [each[0] for each in data_[filesize:]]
        test_target_ = [each[1] for each in data_[filesize:]]
    
        return train_data_, train_target_, test_data_, test_target_
    
    train_data, train_target, test_data, test_target = train_and_test_data(data)
    

    以上的代码是用来划分训练集和测试集。按照7:3的比例划分。

    from sklearn.naive_bayes import MultinomialNB
    from sklearn.pipeline import Pipeline
    from sklearn.feature_extraction.text import TfidfVectorizer, HashingVectorizer, CountVectorizer
    from sklearn import metrics
    from sklearn.naive_bayes import BernoulliNB
    
    nbc = Pipeline([
        ('vect', TfidfVectorizer(
                             
        )),
        ('clf', MultinomialNB(alpha=1.0)),
    ])
    nbc_6.fit(train_data, train_target)    #训练我们的多项式模型贝叶斯分类器
    predict = nbc_6.predict(test_data)  #在测试集上预测结果
    count = 0                                      #统计预测正确的结果个数
    for left , right in zip(predict, test_target):
          if left == right:
                count += 1
    print(count/len(test_target))
    out: 0.793
    

    和我们上一篇完全手写的贝叶斯分类器相比,使用sklearn自带的多项式模型贝叶斯分类器,使用相同的训练集和测试集,结果后者在测试集上的精度达到了79%,比我们原始手写的精度高出将近10%百分点,效果显而易见,并且训练和分类的速度也大大提高。下面我们使用sklearn自带的伯努利模型分类器进行实验。

    nbc_1= Pipeline([
        ('vect', TfidfVectorizer(
                             
        )),
        ('clf', BernoulliNB(alpha=0.1)),
    ])
    predict = nbc_1.predict(test_data)  #在测试集上预测结果
    count = 0                                      #统计预测正确的结果个数
    for left , right in zip(predict, test_target):
          if left == right:
                count += 1
    print(count/len(test_target))
    out: 0.781
    

    和多项式模型相比,使用伯努利模型的贝叶斯分类器,在文本分类方面的精度相比,差别不大,我们可以针对我们面对的具体问题,进行实验,选择最为合适的分类器。

    Part 4:总结

    sklearn真是太强大了,里面分装了绝大部分我们常见的机器学习算法,熟悉这些算法的用法,可以让我们省去重复造轮子的时间,把更多的精力面对我们要解决的问题。所以,如果你不是特别的强迫症患者,还是使用自带的算法,因为这些自带的算法都是经过很多人检验,优化,兼顾速度和精度上的优点。本文选用的训练数据和测试数据都可以从前一篇博客中下载到,如果你嫌麻烦,那么可以直接问我要所有的源代码和数据。

    人生苦短,我用python
    QQ : 1527927373
    EMAIL: 1527927373@qq.com

    相关文章

      网友评论

      • kobeason:也可以用vec.score(test_data, test_target)计算分类准确率
      • ef65b1ae9803:伯努利模型的计算有问题吧。P(tk|c)=(类c下包含单词tk的文件数+1)/(类c下单词总数+2)。类c下单词总数并不是出现单词的文档个数,好像是每个文档中单词出现的总和,不然P(tk|c)的sigma求和就不为1了(在不平滑的情况下)
      • jes2016:文章写得挺好,思路也清晰,就是跟题目“参数调优”,调优太粗狂,没太细的讲解。可以围绕怎么这么调,调那些,稍微展开。
      • lzjqsdd:感觉sklearn确实非常强大,但是中文文档有些少,不知道有没有兴趣加入这个翻译计划https://github.com/lzjqsdd/scikit-learn-doc-cn
        Joyyx:http://sklearn.apachecn.org/ 了解一下,嘿嘿
      • WAY2DataSci:请问你用的Python什么版本?为何我运行nbc_6.fit(train_data, train_target) 会报错?
        kobeason:nbc.fit(train_data, train_target)
        博主前面少写了_6

      本文标题:使用sklearn自带的贝叶斯分类器进行文本分类和参数调优

      本文链接:https://www.haomeiwen.com/subject/aedkkttx.html