python实现朴素贝叶斯
背景知识
贝叶斯公式为:
其中
因此对于在二分类问题中,对于两个不同的类别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.