樸素貝葉斯法

學習與分類算法

先從訓練數據中計算先驗概率和條件概率,然後對於給定的實例計算最大的條件概率,輸出該條件對應的類別。形式化的描述如下:


這裏寫圖片描述

貝葉斯估計

最大似然估計有個隱患,假設訓練數據中沒有出現某種參數和類別的組合怎麼辦?此時估計的概率值爲0,但是這不代表真實數據中就沒有這樣的組合。解決辦法是採用貝葉斯估計

1、條件概率的貝葉斯估計:


這裏寫圖片描述

其中平滑因子.png,Sj表示xj可能取值的種數。分子和分母分別比最大似然估計多了一點東西,其意義是在隨機變量每個取值的頻數上加一個常量平滑因子.png。當此常量取0時,就是最大似然估計,當此常量取1時,稱爲拉普拉斯平滑。

2、先驗概率的貝葉斯估計:


這裏寫圖片描述

貝葉斯情感極性分析器

這裏分析一個基於貝葉斯文本分類器實現的簡單情感極性分析器。

調用實例:

  1. # -*-coding:utf-8 -*-
  2. #Filename: Bayes.py
  3. # Authorhankcs
  4. # Date:2015/2/6 22:25
  5. from math import log, exp
  6.  
  7.  
  8. class LaplaceEstimate(object):
  9.     """
  10.     拉普拉斯平滑處理的貝葉斯估計
  11.     """
  12.  
  13.     def __init__(self):
  14.         self.d = {}   # [-詞頻]map
  15.         self.total = 0.0   全部詞的詞頻
  16.         self.none = 1   當一個詞不存在的時候,它的詞頻(等於0+1
  17.  
  18.     def exists(self, key):
  19.         return key in self.d
  20.  
  21.     def getsum(self):
  22.         return self.total
  23.  
  24.     def get(self, key):
  25.         if not self.exists(key):
  26.             return False, self.none
  27.         return True, self.d[key]
  28.  
  29.     def getprob(self, key):
  30.         """
  31.         估計先驗概率
  32.         :param key: 
  33.         :return: 概率
  34.         """
  35.         return float(self.get(key)[1]) / self.total
  36.  
  37.     def samples(self):
  38.         """
  39.         獲取全部樣本
  40.         :return:
  41.         """
  42.         return self.d.keys()
  43.  
  44.     def add(self, key, value):
  45.         self.total += value
  46.         if not self.exists(key):
  47.             self.d[key] = 1
  48.             self.total += 1
  49.         self.d[key] += value
  50.  
  51.  
  52. class Bayes(object):
  53.     def __init__(self):
  54.         self.d = {}   # [標籤概率] map
  55.         self.total = 0   全部詞頻
  56.  
  57.  
  58.     def train(self, data):
  59.         for d in data:  # d[[詞鏈表], 標籤]
  60.             c = d[1]   # c是分類
  61.             if c not in self.d:
  62.                 self.d[c] =LaplaceEstimate()   # d[c]是概率統計工具
  63.             for word in d[0]:
  64.                 self.d[c].add(word, 1)   統計詞頻
  65.         self.total = sum(map(lambda x: self.d[x].getsum(), self.d.keys()))
  66.  
  67.     def classify(self, x):
  68.         tmp = {}
  69.         for c in self.d: 分類
  70.             tmp[c] = log(self.d[c].getsum()) - log(self.total)   # P(Y=ck)
  71.             for word in x:
  72.                 tmp[c] += log(self.d[c].getprob(word))           # P(Xj=xj | Y=ck)
  73.         ret, prob = 0, 0
  74.         for c in self.d:
  75.             now = 0
  76.             try:
  77.                 for otherc in self.d:
  78.                     now += exp(tmp[otherc] - tmp[c])            將對數還原爲1/p
  79.                 now = 1 / now
  80.             except OverflowError:
  81.                 now = 0
  82.             if now > prob:
  83.                 ret, prob = c, now
  84.         return (ret, prob)
  85.  
  86.  
  87. class Sentiment(object):
  88.     def __init__(self):
  89.         self.classifier = Bayes()
  90.  
  91.     def segment(self, sent):
  92.         words = sent.split(' ')
  93.         return words
  94.  
  95.     def train(self,neg_docs, pos_docs):
  96.         data = []
  97.         for sent in neg_docs:
  98.             data.append([self.segment(sent), u'neg'])
  99.         for sent in pos_docs:
  100.             data.append([self.segment(sent), u'pos'])
  101.         self.classifier.train(data)
  102.  
  103.     def classify(self, sent):
  104.  
  105.         return self.classifier.classify(self.segment(sent))
  106.  
  107. =Sentiment()
  108. s.train([u'糟糕', u' 差勁'], [u'優秀', u' ']) 空格分詞
  109.  
  110. print s.classify(u" 優秀")

輸出

  1. (u'pos', 0.6666666666666665)

說明“好優秀”這句話具有正能量的概率是66%,雖然“好”這個詞語也存在於負極性的語句中,但是分類器還是準確地區分了它。

上面的貝葉斯分類器使用了拉布拉斯平滑處理策略,在進行條件概率的時候,不是連乘,而是取對數相加,最後逐差取指數,這個過程會發生歸一化,得出一個概率出來。

原文作者:hankcs
原文地址:http://www.hankcs.com/ml/naive-bayesian-method.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章