【机器学习基础】朴素贝叶斯对B站弹幕分类(是否永久封禁)

    科技2026-02-21  6

    朴素贝叶斯分类

    文章目录

    朴素贝叶斯分类前言一、使用条件概率进行分类二、获取B站小黑屋弹幕数据三、代码参考文献


    前言

    朴素贝叶斯分类是对于贝叶斯概率理论的一个应用,他可以对数据进行分类,是一个很常用的分类算法。

    一、使用条件概率进行分类

    计算在不同分类下的条件概率,哪个分类的概率大那么就将其归到概率大的分类一方。

    在实际计算时候使用概率的对数进行计算,这样可以避免乘法下溢。初始化是对计算概率的分子和分母初始化值不为0,但要保证分母>分子。这样可以避免有0值和除0。在比较不同的条件概率时,可以只计算分子(分母是一样的)。

    二、获取B站小黑屋弹幕数据

    见博客爬取B站小黑屋 获取到的数据为以下json格式

    [ {'type': xxx // 表示封禁信息 'article': xxx} //表示实际弹幕信息 ]

    本文中获取到的数据一共有2108组,使用前2050组为训练集,剩下的数据做测试数据集。 由于单词划分方式是直接进行对汉字和符号进行划分的(不够合理),错误率也比较高(25%左右)

    三、代码

    import numpy as np import json class Bayes(): def __init__(self): pass def loadData(self, url): #导入json文件 with open(url, 'r', encoding='utf-8') as f: data_dect = json.load(f) # print(data_dect) label = [] posting_list = [] self.data_size = len(data_dect) for item in data_dect: label.append(item['type']) posting_list.append([word for word in item['article']]) return_label = [] # 分为永久封禁和非永久封禁 for example in label: if example == '永久封禁': return_label.append(1) else: return_label.append(0) # print(label) # print(posting_list) return posting_list, return_label def creat_vocabulary_list(self, data_set): # 创建单词表 vocabulary_list = set([]) for document in data_set: # 合并两个集合 vocabulary_list = vocabulary_list | set(document) return list(vocabulary_list) def is_word_in_vocab(self, vocab_list, input_set): # 某句话中是否有某个单词 构建词向量 return_vector = [0] * len(vocab_list) for word in input_set: if word in vocab_list: return_vector[vocab_list.index(word)] = 1 else: print("Word: %s have not deteced!" % word) return return_vector def train_naive_bayes(self, train_set, train_category_set): # 训练模型,返回先验概率,及 # 永久封禁的总概率 # 在永久封禁弹幕的条件下,词向量表中每个单词出现的概率 # 在非永久封禁弹幕条件下,词向量表中每个带刺出现的概率 # train_set 文件词向量矩阵 # train_category_set 文档类型列表 num_train_document = len(train_set) num_words = len(train_set[0]) # 永久封禁弹幕的总概率 p_abusive = sum(train_category_set) / num_train_document # 在所有文档某个单词总出现次数(永久/非永久) p_abusive_num = np.ones(num_words) p_unabusive_num = np.ones(num_words) # 在所有文档中单词出现总次数(永久/非永久) p_abusive_all_num = 2.0 p_unabusive_all_num = 2.0 for i in range(num_train_document): if train_category_set[i] == 1: # 永久封禁弹幕 p_abusive_num += train_set[i] p_abusive_all_num += np.sum(train_set[i]) else: p_unabusive_num += train_set[i] p_unabusive_all_num += np.sum(train_set[i]) # 永久封禁弹幕 计算log, 防止乘法下溢 p_abusive_vec = np.log(p_abusive_num/p_abusive_all_num) # 非永久封禁弹幕 p_unabusive_vec = np.log(p_unabusive_num/p_unabusive_all_num) # print(p_unabusive_vec, p_abusive_vec, p_abusive) return p_abusive, p_abusive_vec, p_unabusive_vec def classify(self, input_x, p_abusive, p_abusive_vec, p_unabusive_vec): # input_x 为一个词向量 # 这里可以只比较分子, 分母相同 p1 = np.sum(input_x * p_abusive_vec) + np.log(p_abusive) p0 = np.sum(input_x * p_unabusive_vec) + np.log(1.0 - p_abusive) # print(p1, p0) if p1 > p0: return 1 else: return 0 def test(self): # 测试 URL = r'2020\ML\ML_action\\3.NaiveBayes\data\blackroom.json' posting_list, class_vec = self.loadData(URL) vocab_list = self.creat_vocabulary_list(posting_list) print("len = ", len(posting_list)) train_size = 2050 # 划分数据 test_list = posting_list[train_size:] test_label = class_vec[train_size:] posting_list = posting_list[:train_size] class_vec = class_vec[:train_size] train_set = [] for posting_document in posting_list: train_set.append(self.is_word_in_vocab(vocab_list, posting_document)) # print(train_set, class_vec) index = 0 rate = 0 pAb, p1v, p0v = self.train_naive_bayes(np.array(train_set), np.array(class_vec)) print(pAb, p1v, p0v) for example in test_list: test_input_data = np.array(self.is_word_in_vocab(vocab_list, example)) print(example) # print(test_input_data) test_result = self.classify(test_input_data, pAb, p1v, p0v) # print("Bayes send back: %s, real class %s" % (test_result, test_label[index])) if test_result != test_label[index]: rate += 1 index += 1 print("error rate: %f" % float(rate/len(test_label))) DEBUG = True nb = Bayes() if DEBUG: nb.test()

    参考文献

    机器学习实战书籍https://github.com/apachecn/AiLearning/blob/master/docs/ml/4.%E6%9C%B4%E7%B4%A0%E8%B4%9D%E5%8F%B6%E6%96%AF.mdhttps://www.cnblogs.com/jpcflyer/p/11069659.html
    Processed: 0.014, SQL: 9