基於朴素貝葉斯的手寫數字識別


【實驗項目名稱】

基於貝葉斯分類器的手寫數字識別

【實驗目的】

在實驗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!")
View Code

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
View Code

2021-04-30


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM