【Python】大数据挖掘课程作业3——使用朴素贝叶斯分类对B站评论进行分析

【Python】大数据挖掘课程作业3——使用朴素贝叶斯分类对B站评论进行分析

参考资料:《Python数据科学手册》
【Python】大数据挖掘课程作业3——使用朴素贝叶斯分类对B站评论进行分析_第1张图片

数据来源:B站观察者网、观视频工作室、央视新闻、小央视频、环球网、环球时报2020年1月到5月所有与新冠疫情相关的投稿视频的弹幕与评论,爬取视频共计13902个,爬取弹幕共计825869条,爬取评论共计16901540条。

算法的选择

朴素贝叶斯分类是一种常用的有监督机器学习算法,我使用的是scikit-learn提供的朴素贝叶斯分类模型,sklearn提供两种朴素贝叶斯分类,一种是高斯朴素贝叶斯,一种是多项式朴素贝叶斯,其中,后者常用于文本的分类。

数据的预处理

因为需要对中文进行贝叶斯分类,所以在训练模型之前要对中文文本进行分词并去掉停用词,这里我是用的分词工具是jieba,停用词表是从网上随便搜的。

因为贝叶斯是有监督的机器学习算法,所以我需要手动标记出一个训练集,这里我选择随机抽取500条弹幕和500条评论进行手动标记(可以看到相对整体数据,我使用的训练集很小,但是似乎没有更好的方案)。

为了将分词后的文本数据进行合理的量化,这里使用sklearn提供的TfidfVectorizer工具计算词频-逆文档频率。

数据分类相关代码

为了方便进行分类,我将所有数据转化为了pandas的DataFrame对象,并使用python内置的pickle模块储存到硬盘上,需要使用时直接从硬盘加载(代码中的dms和cts对象)。

dms和cts的content列分别表示弹幕和评论的分词后的结果。

我将训练集(500条弹幕+500条评论)储存为了csv文件,分类时加载并用于模型训练。

对于最后的训练结果,我同样将其使用pickle模块储存至硬盘。

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import make_pipeline
from datetime import datetime

import pandas as pd

import csv
import jieba
import pickle


def __apply_jiebe(ser: pd.Series) -> pd.Series:
    tmp = jieba.cut(ser['content'])
    res = ''
    for i in tmp:
        if i not in stop_words:
            res = i if res == '' else res + ' ' + i
    ser['content'] = res
    return ser


def __load_stop_words():
    f = open(file='./stop_words.txt', mode='r', encoding='utf-8')
    res = set()
    while lin := f.readline():
        res.add(lin[:-1])
    return res


def load_train_data(file1: str, file2: str) -> (pd.Series, pd.Series):
    w1 = csv.reader(open(file=file1, mode='r', encoding='utf-8', newline=''))
    w2 = csv.reader(open(file=file2, mode='r', encoding='utf-8', newline=''))

    content = []
    in_out = []

    for i in w1:
        tmp = jieba.cut(i[0])
        res = ''
        for j in tmp:
            if j not in stop_words:
                res = j if res == '' else res + ' ' + j
        content.append(res)
        in_out.append(int(i[1]))

    for i in w2:
        tmp = jieba.cut(i[0])
        res = ''
        for j in tmp:
            if j not in stop_words:
                res = j if res == '' else res + ' ' + j
        content.append(res)
        in_out.append(int(i[1]))

    return pd.Series(content), pd.Series(in_out)


stop_words = __load_stop_words()

if __name__ == '__main__':
    begin = datetime.now()

    # 加载数据
    dms = pickle.load(file=open(file='../PickledFile/dm_split.pickled', mode='rb'))  # type: pd.DataFrame
    cts = pickle.load(file=open(file='../PickledFile/comments_split.pickled', mode='rb'))  # type: pd.DataFrame
    # 加载训练集
    train_data, train_target = load_train_data(file1='./弹幕sample.csv', file2='./评论sample.csv')
    print('数据加载与分词结束………………………………………………………………………………………………………………………………………………………………………………………………………………')

    model = make_pipeline(TfidfVectorizer(), MultinomialNB())
    model.fit(train_data, train_target)
    print('模型训练结束……………………………………………………………………………………………………………………………………………………………………………………………………………………………')

    print('开始预测……………………………………………………………………………………………………………………………………………………………………………………………………………………………………')
    dms['res'] = model.predict(dms['content'])
    cts['res'] = model.predict(cts['content'])

    dms = dms.drop(labels=['content'], axis=1)
    cts = cts.drop(labels=['content'], axis=1)

    end = datetime.now()
    print(end - begin)

    # 储存分类结果
    pickle.dump(obj=dms, file=open(file='../PickledFile/dm_predicted(3).pickled', mode='wb'))
    pickle.dump(obj=cts, file=open(file='../PickledFile/comments_predicted (3).pickled', mode='wb'))

分类结果1

这里,我将数据分为3类:内容聚焦于国内情况(图中蓝色)、内容聚焦于国外情况(途中黄色)、内容没有明显关注倾向(图中未画出),结果如下图所示:
【Python】大数据挖掘课程作业3——使用朴素贝叶斯分类对B站评论进行分析_第2张图片

可以发现,分类结果基本与实际疫情的发展相符。

分类结果2

这里我将数据分为4类:内容带有调侃倾向(图中蓝色)、内容带有鼓励倾向(图中黄色)、内容带有严肃的事实讨论(图中绿色)、其他(图中未画出)。
【Python】大数据挖掘课程作业3——使用朴素贝叶斯分类对B站评论进行分析_第3张图片

可以发现,分类结果能够与实际疫情的发展阶段相符。

你可能感兴趣的:(一入Python深似海,python,机器学习,sklearn,朴素贝叶斯算法,数据科学)