機器學習之貝葉斯演算法影象分類
阿新 • • 發佈:2019-02-02
資料集:資料集採用Sort_1000pics資料集。資料集包含1000張圖片,總共分為10類。分別是人(0),沙灘(1),建築(2),大卡車(3),恐龍(4),大象(5),花朵(6),馬(7),山峰(8),食品(9)十類,每類100張,(資料集可以到網上下載)。
ubuntu16.04虛擬作業系統,在分配記憶體4G,處理器為1個CPU下的環境下執行。
將所得到的圖片至“./photo目錄下”,(這裡採用的是Anaconda3作為開發環境)。可以參考上一篇
伯努利分佈理論基礎:
該分佈研究的是一種特殊的實驗,這種實驗只有兩個結果要麼成功要麼失敗,且每次實驗是獨立的並每次實驗都有固定的成功概率p。用伯努利樸素貝葉斯實現對影象的分類,首先伯努利分類物件是0,1分類,故此需要將影象畫素進行閾值0,1劃分。
import datetime starttime = datetime.datetime.now() import numpy as np from sklearn.cross_validation import train_test_split from sklearn.metrics import confusion_matrix, classification_report import os import cv2 X = [] Y = [] for i in range(0, 10): #遍歷資料夾,讀取圖片 for f in os.listdir("./photo/%s" % i): #開啟一張圖片並灰度化 Images = cv2.imread("./photo/%s/%s" % (i, f)) image=cv2.resize(Images,(256,256),interpolation=cv2.INTER_CUBIC) hist = cv2.calcHist([image], [0,1], None, [256,256], [0.0,255.0,0.0,255.0]) X.append(((hist/255).flatten())) Y.append(i) X = np.array(X) Y = np.array(Y) #切分訓練集和測試集 X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=1) #隨機率為100%(保證唯一性可以對比)選取其中的30%作為測試集 from sklearn.preprocessing import binarize from sklearn.preprocessing import LabelBinarizer class ML: def predict(self, x): #預測標籤 X = binarize(x, threshold=self.threshold) #使對數似然函式最大的值也使似然函式最大 #Y_predict = np.dot(X, np.log(prob).T)+np.dot(np.ones((1,prob.shape[1]))-X, np.log(1-prob).T) #等價於 lnf(x)=xlnp+(1-x)ln(1-p) Y_predict = np.dot(X, np.log(self.prob).T)-np.dot(X, np.log(1-self.prob).T) + np.log(1-self.prob).sum(axis=1) return self.classes[np.argmax(Y_predict, axis=1)] class Bayes(ML): def __init__(self,threshold): self.threshold = threshold self.classes = [] self.prob = 0.0 def fit(self, X, y): #標籤二值化 labelbin = LabelBinarizer() Y = labelbin.fit_transform(y) self.classes = labelbin.classes_ #統計總的類別,10類 Y = Y.astype(np.float64) #轉換成二分類問題 X = binarize(X, threshold=self.threshold)#特徵二值化,threshold閾值根據自己的需要適當修改 feature_count = np.dot(Y.T, X) #矩陣轉置,對相同特徵進行融合 class_count = Y.sum(axis=0) #統計每一類別出現的個數 #拉普拉斯平滑處理,解決零概率的問題 alpha = 1.0 smoothed_fc = feature_count + alpha smoothed_cc = class_count + alpha * 2 self.prob = smoothed_fc/smoothed_cc.reshape(-1, 1) return self clf0 = Bayes(0.2).fit(X_train,y_train) #0.2表示閾值 predictions_labels = clf0.predict(X_test) print(confusion_matrix(y_test, predictions_labels)) print (classification_report(y_test, predictions_labels)) endtime = datetime.datetime.now() print (endtime - starttime)
實驗結果為:
[[20 0 0 0 0 1 0 10 0 0] [ 1 2 5 0 0 0 0 23 0 0] [ 3 0 9 0 1 0 0 13 0 0] [ 0 0 1 18 0 1 1 5 0 3] [ 0 0 0 0 30 1 0 0 0 1] [ 0 0 0 0 1 6 0 26 0 1] [ 3 0 0 2 0 0 21 3 0 1] [ 0 0 0 0 0 0 0 26 0 0] [ 2 0 0 2 1 1 0 21 2 2] [ 2 0 2 3 1 0 1 15 0 6]] precision recall f1-score support 0 0.65 0.65 0.65 31 1 1.00 0.06 0.12 31 2 0.53 0.35 0.42 26 3 0.72 0.62 0.67 29 4 0.88 0.94 0.91 32 5 0.60 0.18 0.27 34 6 0.91 0.70 0.79 30 7 0.18 1.00 0.31 26 8 1.00 0.06 0.12 31 9 0.43 0.20 0.27 30 avg / total 0.70 0.47 0.45 300 0:00:05.261369
大家可根據自己的資料集影象,調整劃分閾值,可以得到不同的分類精度。程式碼參考了from sklearn.naive_bayes import BernoulliNB裡面的程式碼。下面貼出整合的程式碼:
import datetime
starttime = datetime.datetime.now()
import numpy as np
from sklearn.cross_validation import train_test_split
from sklearn.metrics import confusion_matrix, classification_report
import os
import cv2
X = []
Y = []
for i in range(0, 10):
#遍歷資料夾,讀取圖片
for f in os.listdir("./photo/%s" % i):
#開啟一張圖片並灰度化
Images = cv2.imread("./photo/%s/%s" % (i, f))
image=cv2.resize(Images,(256,256),interpolation=cv2.INTER_CUBIC)
hist = cv2.calcHist([image], [0,1], None, [256,256], [0.0,255.0,0.0,255.0])
X.append(((hist/255).flatten()))
Y.append(i)
X = np.array(X)
Y = np.array(Y)
#切分訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=1)
from sklearn.naive_bayes import BernoulliNB
clf0 = BernoulliNB().fit(X_train, y_train)
predictions0 = clf0.predict(X_test)
print (classification_report(y_test, predictions0))
endtime = datetime.datetime.now()
print (endtime - starttime)
precision recall f1-score support
0 0.52 0.42 0.46 31
1 0.48 0.52 0.50 31
2 0.39 0.54 0.45 26
3 0.63 0.59 0.61 29
4 0.76 0.88 0.81 32
5 0.58 0.41 0.48 34
6 0.94 0.53 0.68 30
7 0.51 0.69 0.59 26
8 0.47 0.52 0.49 31
9 0.75 0.80 0.77 30
avg / total 0.61 0.59 0.59 300
0:00:05.426743