Python實現貝葉斯分類器
阿新 • • 發佈:2019-02-01
使用樸素貝葉斯分類器,對一片文章進行分類處理
貝葉斯分類器的優缺點:
優點:
- 速度相對較快,因為針對每個分類的特徵詞不會太多
- 演算法比較簡單
- 可以動態的新增訓練資料集合
- 分類的過程可以檢視
缺點:
- 無法處理基於特徵組合所產生的變化結果
貝葉斯—文字分類的步驟:
- 對中文進行分詞處理 —jieba分詞
- 對分開的詞語進行處理,去除重複詞彙,去除標點和單個虛擬詞彙如:你,我,他。。。
- 選擇特徵詞,很重要,要總結出符合某一型別的關鍵特徵詞
- 對分類器進行訓練,即傳入一些已經分好類的文章,讓分類器可以知道其中的一些特徵詞。
- 計算出特徵詞在各個分類中出現的概率。
- 為每個特徵詞設定權重值
- 計算整篇文件的概率,將每個特徵值的概率相乘,即求出了在某一分類條件下,這篇文章出現的概率P(Document|Category)
- 根據P(Document|Category)應用貝葉斯定理求出P(Category|Document)
- 判定文章所屬的分類
python程式碼實現
#-*_coding:utf8-*- import jieba from sqlite3 import dbapi2 as sqlite #將傳入文件分詞,並去除重複和不必要的詞彙。 def getwords(doc): doc1 = list(jieba.cut(doc)) words = [] for s in doc1: if(len("".join(s))>1): if(s not in words): words.append(s) return words class classifier: def __init__(self, getfeatures, filename='test1.db'): #記錄位於各分類中不同特徵值的數量 self.fc = {} #統計每個分類中的文件數量(即各分類被使用的次數) self.cc = {} #從即將被歸類的內容項中提取特徵出來 self.getfeatures = getfeatures #連結資料庫 self.con = sqlite.connect(filename) self.con.execute('create table if not exists fc(feature,category,count)') self.con.execute('create table if not exists cc(category,count)') #增加對特徵/分類組合的計數值 def incf(self,f,cat): count = self.fcount(f,cat) if(count==0): self.con.execute("insert into fc values ('%s','%s',1)" % (f,cat)) else: self.con.execute("update fc set count=%d where feature='%s' and category='%s'" % (count+1,f,cat)) #增加對某一分類的技術值 def incc(self,cat): count = self.catcount(cat) if(count==0): self.con.execute("insert into cc values ('%s',1)" % (cat)) else: self.con.execute("update cc set count=%d where category='%s'" % (count+1,cat)) #某一特徵出現於某一分類的的次數 def fcount(self,f,cat): res = self.con.execute("select count from fc where feature='%s' and category='%s'" % (f,cat)).fetchone() if(res==None):return 0 else: return float(res[0]) #某一種分類的內容項數量 def catcount(self,cat): res = self.con.execute("select count from cc where category='%s'" % (cat)).fetchone() if(res==None):return 0 else:return float(res[0]) #所有內容向的數量 def totalcount(self): res = self.con.execute("select sum(count) from cc").fetchone() if(res==None):return 0 return res[0] #所有分類的列表 def categories(self): cur = self.con.execute("select category from cc") return [d[0] for d in cur] #訓練 def train(self,item,cat): features=self.getfeatures(item) #針對該分類為每一個特徵增加計數值 for f in features: self.incf(f,cat) #增加針對該分類的計數值 self.incc(cat) #向資料庫提交資料 self.con.commit() #計算概率 def fprob(self,f,cat): if self.catcount(cat)==0: return 0 #特徵在分類總出現的總次數,除以分類中包含內容項的總數 return self.fcount(f,cat)/self.catcount(cat) #加入概率的權重值 def weightedprob(self,f,cat,prf,weight=1.0,ap=0.5): #計算當前的概率值 basicprob=prf(f,cat) #統計特徵在所有分類中出現的次數 totals = sum([self.fcount(f,c) for c in self.categories()]) # print("所有次數:") # print(totals) #計算加權平均 bp = ((weight*ap)+(totals*basicprob))/(weight+totals) return bp #最終的分類方法 def classify(self,item,default=None): probs={} #尋找概率最大的分類 max=0.0 for cat in self.categories(): probs[cat] = self.prob(item,cat) if probs[cat] > max: max = probs[cat] best = cat return best #新建一個classifier的子類 class naivebayes(classifier): #提取特徵詞,並將所有單詞的概率相乘,以求出整體的概率。P(Document|Category) def docprob(self,item,cat): features = self.getfeatures(item) #將所有的特徵概率相乘 p=1 for f in features:p *= self.weightedprob(f,cat,self.fprob) return p #已知P(Document|Category)應用貝葉斯定理求出P(Category|Document) def prob(self,item,cat): catprob=self.catcount(cat)/self.totalcount() docprob = self.docprob(item,cat) return docprob * catprob
呼叫方法:
import docClass
cl = docClass.naivebayes(docClass.getwords)
cl.train('訓練的文章1')
cl.train('訓練的文章2')
cl.train('...')
cl.train('訓練的文章n')
print(cl.classify('待分類的文章', default='unknow'))
ok,以上的程式碼就實現了貝葉斯的分類器,程式碼中用到了jieba分詞模組,sqlite嵌入式資料庫。