通过python在imdb数据集上实现朴素贝叶斯

背景知识

贝叶斯公式为:

在这里插入图片描述

其中

在这里插入图片描述
在这里插入图片描述

因此对于在二分类问题中,对于两个不同的类别C1和C2有:

在这里插入图片述
在这里插入图片描述

	两者分别表示对于一个给定的样本数据,其属于C1或C2类别的概率,最终判断时,取较大
概率值所属的类别,所以此时的P(X)可以不做考虑。最终比较大小的两个值为P(X|C1)*P(C1)	
与P(X|C2)*P(C2)。

模型实现流程

	朴素贝叶斯的实现过程主要分为四部分:
		(1)数据集的导入
		(2)预处理(划分训练和测试数据, 将训练和测试数据用向量表示(one_hot
	 				encoding、 count encoding、tf-idf encoding三种方式))
	    (3)用训练集的数据训练得到朴素贝叶斯模型
	    (4)用测试集的数据进行模型评估
	    
    数据集的导入和预处理是每个模型都有的,本文重点在(3)的训练过程。
    	根据背景知识所提到的公式,模型的实现即是计算P(X|C1),P(C1)与P(X|C2),P(C2)。

python代码如下

"""
    step:
        1.选择数据集并导入数据
        2.数据预处理:1)使用uni-gram和bi-grams对数据集进行Token(特征化)
                    2)特征向量化(此处使用one-hot encoding)
        3.训练模型:根据输入样本得到具有各概率值的分类器
        4.测试模型:分类
"""

import numpy as np
import tensorflow as tf
from tensorflow import keras

def load_data():
    imdb = tf.keras.datasets.imdb
    (x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=5000)
    print(len(x_train))
    print(x_train[0])
    print(len(x_train[0]))
    return x_train, y_train, x_test, y_test

def data_process(x_train, x_test):
    """
    step:
        1.将样本数据填充为fixed length(one-hot时为词表长度)
        2.切片进行token话
    """
    vocab_size = 5000
    train_length = len(x_train)
    train_data = np.zeros((train_length, vocab_size))
    for i in range(len(x_train)):
        train_data[i, x_train[i]] = 1

    test_length = len(x_test)
    test_data = np.zeros((test_length, vocab_size))
    for i in range(len(x_test)):
        test_data[i, x_test[i]] = 1
    return train_data, test_data

def NB_train(train_data, y_train):
    """
    数据来源:训练集数据
    step:
        1.计算P(c=C0), P(c=C1)
        2.计算P(x1|C0), P(x2|C0), ... ,P(xn|C0)
        3.计算P(x1|C1), P(x2|C1), ... ,P(xn|C1)
    """
    train_length = train_data.shape[0]  # 样本数
    sum_C0 = 0  # C0类样本的数目
    sum_C1 = 0
    for i in range(len(y_train)):
        if y_train[i] == 0:
            sum_C0 += 1
        else:
            sum_C1 += 1
    P0 = sum_C0/train_length      # 属于C0类的概率 ---- P(C0)
    P1 = sum_C1/train_length      #                    P(C1)
    n = train_data.shape[1]
    sum_xn_0 = np.zeros((1, n))
    sum_xn_1 = np.zeros_like(sum_xn_0)
    for i in range(0, train_length):
        for j in range(0, n):
            if train_data[i, j] == 1:
                if y_train[i] == 0:
                    sum_xn_0[0, j] += 1
                elif y_train[i] == 1:
                    sum_xn_1[0, j] += 1
    px0 = sum_xn_0 / sum_C0                
    px1 = sum_xn_1 / sum_C1      # px1的第4列为 P(x3|C1)
    return P0, P1, px0, px1

def NB_test(test_data, y_test, P0, P1, px0, px1):
    """
    通过训练得到的分类器进行预测
    数据来源:测试集数据,训练模型
    step:
        1.遍历每个样本
        2.计算其属于C0或C1的概率值fc0, fc1
        3.比较fc0和fc1,将结果放入predict
        4.将predict与真实label比较,得到准确率
    """
    m, n = test_data.shape
    print(m, n)
    predict = np.zeros((m, ))  # 比较fc0和fc1
    for i in range(m):
        fc0 = P0  # 属于第一类的概率值
        fc1 = P1
        for j in range(0, n):
            if test_data[i, j] == 1:
                fc0 *= px0[0, j]
                fc1 *= px1[0, j]
        if fc0 >= fc1:
            predict[i] = 0
        else:
            predict[i] = 1
    acc = np.sum((predict == y_test)) / m
    print(acc)
    return acc

x_train, y_train, x_test, y_test = load_data()
train_data, test_data = data_process(x_train, x_test)
P0, P1, px0, px1 = NB_train(train_data, y_train)
acc = NB_test(test_data, y_test, P0, P1, px0, px1)

转载声明

本文所有文章均属原创,欢迎转载,请注明文章出处:https://blog.csdn.net/qq_39667545/article/details/109529203.

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值