学习与分类算法
先从训练数据中计算先验概率和条件概率,然后对于给定的实例计算最大的条件概率,输出该条件对应的类别。形式化的描述如下:

贝叶斯估计
最大似然估计有个隐患,假设训练数据中没有出现某种参数和类别的组合怎么办?此时估计的概率值为0,但是这不代表真实数据中就没有这样的组合。解决办法是采用贝叶斯估计
1、条件概率的贝叶斯估计:

其中
,Sj表示xj可能取值的种数。分子和分母分别比最大似然估计多了一点东西,其意义是在随机变量每个取值的频数上加一个常量
。当此常量取0时,就是最大似然估计,当此常量取1时,称为拉普拉斯平滑。
2、先验概率的贝叶斯估计:

贝叶斯情感极性分析器
这里分析一个基于贝叶斯文本分类器实现的简单情感极性分析器。
调用实例:
- # -*-coding:utf-8 -*-
- #Filename: Bayes.py
- # Author:hankcs
- # Date:2015/2/6 22:25
- from math import log, exp
-
-
- class LaplaceEstimate(object):
- """
- 拉普拉斯平滑处理的贝叶斯估计
- """
-
- def __init__(self):
- self.d = {} # [词-词频]的map
- self.total = 0.0 # 全部词的词频
- self.none = 1 # 当一个词不存在的时候,它的词频(等于0+1)
-
- def exists(self, key):
- return key in self.d
-
- def getsum(self):
- return self.total
-
- def get(self, key):
- if not self.exists(key):
- return False, self.none
- return True, self.d[key]
-
- def getprob(self, key):
- """
- 估计先验概率
- :param key: 词
- :return: 概率
- """
- return float(self.get(key)[1]) / self.total
-
- def samples(self):
- """
- 获取全部样本
- :return:
- """
- return self.d.keys()
-
- def add(self, key, value):
- self.total += value
- if not self.exists(key):
- self.d[key] = 1
- self.total += 1
- self.d[key] += value
-
-
- class Bayes(object):
- def __init__(self):
- self.d = {} # [标签, 概率] map
- self.total = 0 # 全部词频
-
-
- def train(self, data):
- for d in data: # d是[[词链表], 标签]
- c = d[1] # c是分类
- if c not in self.d:
- self.d[c] =LaplaceEstimate() # d[c]是概率统计工具
- for word in d[0]:
- self.d[c].add(word, 1) # 统计词频
- self.total = sum(map(lambda x: self.d[x].getsum(), self.d.keys()))
-
- def classify(self, x):
- tmp = {}
- for c in self.d: # 分类
- tmp[c] = log(self.d[c].getsum()) - log(self.total) # P(Y=ck)
- for word in x:
- tmp[c] += log(self.d[c].getprob(word)) # P(Xj=xj | Y=ck)
- ret, prob = 0, 0
- for c in self.d:
- now = 0
- try:
- for otherc in self.d:
- now += exp(tmp[otherc] - tmp[c]) # 将对数还原为1/p
- now = 1 / now
- except OverflowError:
- now = 0
- if now > prob:
- ret, prob = c, now
- return (ret, prob)
-
-
- class Sentiment(object):
- def __init__(self):
- self.classifier = Bayes()
-
- def segment(self, sent):
- words = sent.split(' ')
- return words
-
- def train(self,neg_docs, pos_docs):
- data = []
- for sent in neg_docs:
- data.append([self.segment(sent), u'neg'])
- for sent in pos_docs:
- data.append([self.segment(sent), u'pos'])
- self.classifier.train(data)
-
- def classify(self, sent):
-
- return self.classifier.classify(self.segment(sent))
-
- s =Sentiment()
- s.train([u'糟糕', u'好 差劲'], [u'优秀', u'很 好']) # 空格分词
-
- print s.classify(u"好 优秀")
|
输出
- (u'pos', 0.6666666666666665)
|
说明“好优秀”这句话具有正能量的概率是66%,虽然“好”这个词语也存在于负极性的语句中,但是分类器还是准确地区分了它。
上面的贝叶斯分类器使用了拉布拉斯平滑处理策略,在进行条件概率的时候,不是连乘,而是取对数相加,最后逐差取指数,这个过程会发生归一化,得出一个概率出来。
原文作者:hankcs
原文地址:http://www.hankcs.com/ml/naive-bayesian-method.html