條件:類別數一定,?i,i=1,2,3,…c ;
已知類先驗概率和類條件概率密度 ?(??), ?(?│?? ), ?=1,2,…, ?
兩類情況:
i??(?? |?)> ?(?? |?) then ?∈??
if?(?? |?)< ?(?? |?) then ?∈??
多類情況:
if?(??│?)=max(?(??│?) then"?∈?? ?=?,?,…,?
已知:?(??), ?(?│?? ), ?=1,2,…, ?
資料集包括四部分:訓練影象、訓練標籤(表示影象為哪個數字)、測試影象、測試標籤
二值特徵提取將進行分割處理轉化為0,1數字資訊,方便操作
匯入資料集後,利用訓練影象和訓練標籤訓練模型,模型的訓練結果為:數字0-9出現的概率(?(??),**中sum)、每個數字中圖形二值化後和的概率(?j(?? ),**中的shape)
注:此處分子+1為了防止概率為0(拉普拉斯修正)
利用訓練出的shape處理測試集中的影象,即:
影象當前位置為1,乘以shape,為0時乘以1-shape,最後乘以該數字在訓練集**現的概率,可得到0-9個數字出現的概率,根據貝葉斯決策理論可得出概率大的數字即為當前數字
對比測試資料的label,判斷該步測試是否準確
環境:win10+pycharm+anconda3(python 3.7)
import numpy as np
import struct
from collections import defaultdict
def normalize(data): # 將畫素二值化
m, n = data.shape
for i in range(m):
for j in range(n):
if data[i, j] != 0: # 位置有畫素即為1
data[i, j] = 1
else:
data[i, j] = 0
return data
def read_data():
path = [r'c:\users\19759\desktop\data\t10k-images-idx3-ubyte',
r'c:\users\19759\desktop\data\t10k-labels-idx1-ubyte',
r'c:\users\19759\desktop\data\train-images-idx3-ubyte',
r'c:\users\19759\desktop\data\train-labels-idx1-ubyte'] # 4個資料集路徑
data = defaultdict(dict) # 宣告乙個空的字典 存放對映結果
for i in range(0, 4):
file = open(path[i], 'rb') # 開啟資料集
f = file.read()
file.close()
# 以下進行資料的轉化,、標籤轉化為數字資訊
if i % 2 == 0: #
img_index = struct.calcsize('>iiii')
_, size, row, column = struct.unpack('>iiii', f[:img_index])
imgs = struct.unpack_from(str(size * row * column) + 'b', f, img_index)
imgs = np.reshape(imgs, (size, row * column)).astype(np.float32)
imgs = normalize(imgs)
if i == 0:
key = 'test'
else:
key = 'train'
data[key]['images'] = imgs
else: # 標籤
label_index = struct.calcsize('>ii')
_, size = struct.unpack('>ii', f[:label_index])
labels = struct.unpack_from(str(size) + 'b', f, label_index)
labels = np.reshape(labels, (size,))
tmp = np.zeros((size, np.max(labels) + 1))
tmp[np.arange(size), labels] = 1
labels = tmp
if i == 1:
key = 'test'
else:
key = 'train'
data[key]['labels'] = labels
return data
def train(data): # 訓練模型
imgs = data['train']['images'] # 開啟訓練集
labels = data['train']['labels']
# n為訓練集的訓練個數(6w) dimsnum為轉化後儲存的所需的0 1位數 labelnum為標籤的個數(10個 0-9)
n, dimsnum = imgs.shape
n, labelnum = labels.shape
# 初始化sum和shape
sum = np.zeros(labelnum)
shape = np.zeros((labelnum, dimsnum))
for i in range(0, n): # n個資料
# 找出第i個中最大的下標 labels[i][j]=1代表第i張為數字j 其餘為0
pos = np.argmax(labels[i])
# 該數字出現次數+1
sum[pos] = sum[pos] + 1
for j in range(0, dimsnum): # 轉化後的n個維度
shape[pos][j] = shape[pos][j] + imgs[i][j] # shape[pos][j]代表數字pos第j維1的和
for i in range(0, labelnum):
for j in range(0, dimsnum):
shape[i][j] = (shape[i][j] + 1) / (sum[i] + 2) # 將shape轉化為概率
sum = sum / n # 將sum轉化為概率
return sum, shape
def test(data, sum, shape): # 測試模型
imgs = data['test']['images'] # 開啟測試集
labels = data['test']['labels']
# n為測試集個數 dimsnum為測試轉化後的位數(維度) labelnum標籤個數(0-9十個)
n, dimsnum = imgs.shape
n, labelnum = labels.shape
correct = 0 # 測試時根據訓練模型準確的個數
for i in range(0, n):
pos = np.argmax(labels[i]) # 對應的數字pos
maxx = 0 # 0-9中的最大概率
vpos = -1 # 0-9中的對應最大概率的數字
for k in range(0, labelnum): # 數字0-9
ans = 1
for j in range(0, dimsnum): # dimsnum維
if imgs[i][j] == 1: # 第i個的第j維對應為1 '出現此概率'
ans *= shape[k][j]
else: # 未出現
ans *= (1 - shape[k][j])
ans *= sum[k] # 乘數字k在訓練集中的概率 理想狀態下為0.1
if ans > maxx:
maxx = ans
vpos = k
if vpos == pos: # 當找到的數字和測試集的數字相同 測試成功數+1
correct += 1
return correct, n # 返回成功數和測試集總數
if __name__ == '__main__':
data = read_data()
sum, shape = train(data)
correct, num = test(data, sum, shape)
print("測試正確率為:", correct / num)
測試正確率為: 0.841 樸素貝葉斯分類器
p a b frac 類別 結果 a出現在特徵b樣本裡的概率 frac 假設乙個學校裡有60 男生和40 女生。女生穿褲子的人數和穿裙子的人數相等,所有男生穿褲子。隨機看到了乙個穿褲子的學生,那麼這個學生是女生的概率是多少?begin 特徵 穿褲子 類別 女生 p 女生 穿褲子 frac frac ...
樸素貝葉斯分類器
樸素貝葉斯分類器是用來做分類的乙個簡便方法。在貝葉斯公式的基礎上,引人條件獨立的假設,使得貝葉斯分類器具有簡單易行的優點和假設時常與實際不符的缺點。下面簡單介紹一下樸素貝葉斯分類器。首先規定一下資料格式 輸入的每乙個樣本為 其中 i 為樣本編號,x 為樣本的特徵,是乙個 n 維向量,x cdots ...
樸素貝葉斯分類器
所謂 條件概率 conditional probability 就是指在事件b發生的情況下,事件a發生的概率,用p a b 來表示。根據文氏圖,可以發現 同理可得,所以,即 其中,p a 稱為 先驗概率 prior probability 即在b事件發生之前,我們對a事件概率的乙個判斷 p a b ...