【實驗項目名稱】
基於貝葉斯分類器的手寫數字識別
【實驗目的】
在實驗1模板匹配基礎上,以貝葉斯分類器為判別函數,對模板化后的手寫數字進行分類識別,達到熟練掌握貝葉斯分類器的目的。
【實驗原理】
(1)利用樣本計算每個數字的先驗概率, 即每個數字出現的概率。
(2)讀取標准化后的數字0~9,二值化,對每個數字進行等分區域分割,統計每個區域內的黑色像素點的個數,即為特征初值。利用公式計算類條件概率密度。
(3)利用貝葉斯求后驗概率,最大的后驗概率就是所屬密度。
【實驗要求】
給定數字0-9的原始樣本集合,每個數字都有10個大小為240*240的樣本圖像。要求如下:
1、輸出每種數字的先驗概率
2、輸出條件概率密度矩陣
3、輸出測試結果
4、從統計意義上,給出每個數字的識別率。
5、對本實驗進行總結
0.朴素貝葉斯;
1.流程圖:

2.三種概率的計算與分析:
先驗概率:
其中N為總樣本數,Ni為每類樣本的個數,由此可以計算出每類樣本的先驗概率。
類條件概率:
--公式4
類條件概率:在特征空間ωi中出現樣本特征X的概率,即為每個數字的特征空間中出現X的概率,所以針對每一個測試樣本,需要計算出十個類條件概率。每個類條件概率通過 X 的每個特征在該類特征庫里所占的比例來確定(公式4),最后通過各特征獨立,直接相乘計算出來。
后驗概率:
后驗概率:樣本特征X屬於ωi的概率。利用先驗概率、類條件概率,計算得到后驗概率(一個test樣本對應十個后驗概率),其中概率最大的類別即為識別出來的類別。
3.測試結果(部分截圖):

4.統計意義上的識別率:
數字 0 識別的正確率 = 85.00% ,錯誤率 = 15.00%
數字 1 識別的正確率 = 85.00% ,錯誤率 = 15.00%
數字 2 識別的正確率 = 65.00% ,錯誤率 = 35.00%
數字 3 識別的正確率 = 50.00% ,錯誤率 = 50.00%
數字 4 識別的正確率 = 65.00% ,錯誤率 = 35.00%
數字 5 識別的正確率 = 40.00% ,錯誤率 = 60.00%
數字 6 識別的正確率 = 60.00% ,錯誤率 = 40.00%
數字 7 識別的正確率 = 70.00% ,錯誤率 = 30.00%
數字 8 識別的正確率 = 60.00% ,錯誤率 = 40.00%
數字 9 識別的正確率 = 45.00% ,錯誤率 = 55.00%
5.關於錯誤率較大的分析:
一是由於圖片結構的原因,白色字符區域過小,背景區域過大,並且特征壓縮(降維)比較嚴重,可以適當保留更多的特征,當然保留更多特征帶來的是更為龐大的計算量;二是朴素貝葉斯假定特征之間相互獨立,當數據之間獨立性較大時,分類效果較好,反之,當各屬性之間存在關聯時,會導致分類效果大大降低。顯然,其特征之間存在關聯。
6.代碼:
1 # Bayes手寫數字識別 2 import os 3 import Function 4 # 1.樣本特征,不需預處理 5 # 2.圖像壓縮表示,28*28——7*7,存儲於(picture_bayes(i).txt) 6 # 3.根據數字類別分別存儲於不同的txt 7 root_dir = "E:/train-images" # 訓練數據集 8 file_bayes = [] 9 for i in range(10): 10 file_bayes.append(open("E:/PatternRecognition/pic_txt/picture_bayes" + str(i) + ".txt", 'w')) # 覆蓋寫模式 11 sum_num = 0 12 Priori_pro = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 13 for fl in os.listdir(root_dir): # 循環處理所有train圖片 14 img_str = fl[0:-4] + ":" + Function.Image_Compression(root_dir + '/' + fl) # 圖像壓縮,返回壓縮數據流 15 file_bayes[eval(fl[0])].write(img_str + '\n') # 壓縮后的圖像數據寫入文本存儲 16 Priori_pro[eval(fl[0])] += 1 # 統計每一類數字的個數 17 sum_num += 1 18 for i in range(10): 19 file_bayes[i].close() 20 # 3.bayes概率計算,先驗概率、類條件概率、后驗概率 21 # 先驗概率--Priori_pro 22 for i in range(10): 23 Priori_pro[i] = Priori_pro[i] / sum_num 24 # 類條件概率--Class_pro && 后驗概率--Posterior_pro 25 Class_pro = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # 某個樣本的類條件概率 26 Posterior_pro = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # 某個樣本的后驗概率 27 Correct_rate = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # 識別率 28 ############ 29 root_dir = "E:/test-images" # 測試test-images數據集 30 for fl in os.listdir(root_dir): # 循環處理所有test圖片 31 class_pic = 0 # 比較得出后驗概率最大的圖片類別 32 max_pxh = 0 # 最大的后驗概率 33 px_h_deno = 0 # 后驗概率中的分母 34 test_img_str = Function.Image_Compression(root_dir + '/' + fl) 35 for i in range(10): # 計算類條件概率 36 Class_pro[i] = Function.Class_conditional_pro(test_img_str, i) 37 px_h_deno += Priori_pro[i] * Class_pro[i] 38 # print("{:.3e}".format(Class_pro[i]), end=" ") 39 for i in range(10): # 計算后驗概率 40 Posterior_pro[i] = Priori_pro[i] * Class_pro[i] / px_h_deno 41 if max_pxh < Posterior_pro[i]: # 根據后驗概率判斷分類 42 max_pxh = Posterior_pro[i] 43 class_pic = i 44 if class_pic == eval(fl[0]): 45 print("測試數字:", fl[0:-4], " -- 識別出來的結果:", class_pic) # 數字的識別結果 46 Correct_rate[class_pic] += 1 47 else: 48 print("測試數字:", fl[0:-4], " -- 識別出來的結果:", class_pic, "識別錯誤!!!") 49 # print() 50 print("------------------------------------------------") 51 for i in range(10): 52 print("數字 {:d} 識別的正確率 = {:.2f}% ,錯誤率 = {:.2f}%".format(i, Correct_rate[i]*5, 100 - Correct_rate[i]*5)) 53 print("success!")
Class_conditional_pro(test_str, n)
(應該設計為,一次讀取一行數據,然后同時處理49位數字,而非讀取49次文件,不過都可實現)
1 ####################### 2 # 計算Pj(Wi),在此基礎上計算P(X/Wi) 3 # 返回一個double類型數據,為在某一類數字(0-9)的特征空間中出現X的概率 4 # 某類數字的特征空間中出現該樣本X的概率 5 ####################### 6 def Class_conditional_pro(test_str, n): 7 file = open("E:/PatternRecognition/pic_txt/picture_bayes" + str(n) + ".txt", 'r') # 只讀模式 8 p_x_wi = 1.0 9 for i in range(len(test_str)): 10 sum_pj_wi = 0 11 while True: 12 line = file.readline() 13 if not line: # 已讀完整個文檔,光標返回開頭,結束此次匹配 14 file.seek(0) 15 break 16 train_str = line[-50:-1] 17 sum_pj_wi += eval(train_str[i]) 18 if eval(test_str[i]) == 1: 19 p_x_wi *= (sum_pj_wi + 1) / (100 + 2) 20 else: 21 p_x_wi *= 1 - (sum_pj_wi + 1) / (100 + 2) 22 file.close() 23 return p_x_wi
2021-04-30
