一、实验目的
1、熟悉朴素贝叶斯的求解公式;
2、掌握朴素贝叶斯的代码实现;
3、比较朴素贝叶斯算法的优劣;
4、熟悉numpy的使用。
二、实验设备
计算机:CPU四核i7 6700处理器;内存8G; SATA硬盘2TB硬盘; Intel芯片主板;集成声卡、千兆网卡、显卡; 20寸液晶显示器。
编译环境:python解释器、Pycharm编辑器
三、实验内容
1、新建项目和文件,并导入numpy和matplotlib
(1)打开Pycharm,新建项目,并在该项目下新建文件naive_bayes_classifier.py。
(2)在该项目下存放实验所需要的图片文件夹。
(3)导入一些编程中需要的包。
import numpy as np
import os
from PIL import Image
import time
2、构造一个函数data_transformer
(1)定义函数头data_transformer,该函数有一个参数,path_images,表示图片的存放路径。
(2)将图片读取为103000785的训练数据和102000785的测试数据。
def data_transformer(path_images):
list_image = os.listdir(path_images)
data = []
for nums in list_image:
path_num = path_images + "\\" + nums
list_num = os.listdir(path_num)
data_num = []
for idx in range(0, 5000):
img = Image.open(path_num + '\\' + list_num[idx])
data_vector = list(np.array(img).flatten())
data_vector.append(int(nums))
data_num.append(data_vector)
data.append(data_num)
data = np.array(data)
data_train = data[:, 0:3000, :]
data_test = data[:, 3000:, :]
print(data.shape)
data = data.reshape([15000, 785])
print(data.shape)
data = data.reshape([15000, 785])
print(data.shape)
np.savetxt('data.txt', data, fmt='%d')
return data_train, data_test
3、编写一个类NaiveBayesClassifier
(1)构造一个类NaiveBayesClassifier,并构造函数,需要训练数据集和测试数据集作为输入。
(2)构造类方法Classify,实现朴素贝叶斯分类。
代码如下:
class NaiveBayesClassifier:
def __init__(self, data_train, data_test, num):
self.data_train = data_train
self.data_test = data_test
self.test_nums = num
def classify1(self): # 懒惰学习法
num = 0
acurracy = 0
for z in range(np.size(self.data_test, axis=1)):
for l in range(np.size(self.data_test, axis=0)):
matrix = self.data_train[:, :, :-1] == self.data_test[l, z, :-1]
x = np.sum(matrix, axis=1) #求每行的和
x = (x + 1) / (3000 + 256)
max_p = np.log(x).sum(axis=1) + np.log(1 / 10)
if np.argmax(max_p) == self.data_test[l, z, 784]:
acurracy += 1
num = num + 1
if num == self.test_nums:
print("测试精度为", acurracy / num)
return
def classify2(self): # 查表法
a = np.zeros((256, 784, 3))
for i in range(256):
matrix = self.data_train[:, :, :-1] == i
x = np.sum(matrix, axis=1)
x = (x + 1) / (3000 + 256) # 10*784
x = x.T # 784*10
a[i] = x # a为256*784*10
num = 0
acurracy = 0
for z in range(np.size(self.data_test, axis=1)):
for l in range(np.size(self.data_test, axis=0)):
feature = self.data_test[l, z, :-1]
list = np.zeros((784, 3))
for i in range(784):
b = a[feature[i], i, :]
list[i] = b # 784*10
max_p = np.log(list).sum(axis=0) + np.log(1 / 10)
if np.argmax(max_p) == self.data_test[l, z, 784]:
acurracy += 1
num = num + 1
if num == self.test_nums:
print("测试精度为", acurracy / num)
return
4、编写if __name __ = =" __ main __”:
(1)构造if __name __ = =" __ main __”:并在其中调用data_transformer获取数据。
(2)初始化NaiveBayesClassifier类的一个对象my_nbc,调用classify方法。
if __name__ == "__main__":
data_train, data_test = data_transformer("D:\\下载\\pythonProject\\venv\\Lib\\site-packages\\PIL\\图片集")
test_nums = 1000
my_nbc = NaiveBayesClassifier(data_train, data_test, test_nums)
a = time.time()
my_nbc.classify1()
b = time.time()
my_nbc.classify2()
c = time.time()
t1 = b-a
t2 = c-b
print("懒惰学习计算时间为", t1, "秒")
print("查表法计算时间为", t2, "秒")
实验截图:
6、实验总结:
本次实验学习了朴素贝叶斯分类的实现过程,在实验中,遇到的繁琐问题较多,大多都是一些基本的语法问题,最终花费了一些时间完成实验,通过这次实验也发现了自己的基础不够好,对当时学习过的知识,遗忘的较多,需要再加以练习,回顾和学习。我改变了Test_num的值,发现懒惰学习和查表法随着test_num的变化与表格要求一致,甚至更快一些。