需求起因:
在使用k邻近算法,或者决策树的时候,也有可能产生错误的分类结果, 要求 分类器 给出 一个 最优 的 类别 猜测 结果, 同时 给出 这个 猜测 的 概率 估计 值。
准备知识:
贝叶斯思想:如果一个坐标系中,有两堆点,用P1,P2表示点的类型,如果新增一个数据点(x,y),用P1(x,y)代表这个数据点属于P1类的概率,那么,如果:P1(x,y)>P2(x,y) ,则认为 这个数据点属于P1这个类型; 只从数据本身获得结论,并不考虑逻辑推理和先验知识。
*************************************************************************************************************************************************************************************************
概率的准备知识:
1. 如果一个罐子中,一共有7个石头,3个灰,4个黑, 那么,取得灰色的概率是 :3 / 7
2. 如果有两个桶子,A(2灰,2黑)B(1灰,2黑), 那么条件概率的定义: 已知石头出自B桶的条件下,取出灰色石头的概率, 记为: p(灰色 | 出自B桶) = 1/3
又有如下公式: p(灰色 | 出自B桶)(条件概率) = p(灰色&&出自B桶)/ p(出自B桶)
p(灰色&&出自B桶) = B桶的灰色石头数 / 总石头个数 = 1/7;
(理解为石头有两个属性[颜色,桶],放在一起抽,抽出的石头是[灰,B桶]的概率)
*已知石头出自B桶的条件下,取出灰色石头的概率 不等于 抽出标记为B桶的灰色石头 的概率。
p(石头出自B桶)= B桶石头总数 / 所有石头总数 = 3 /7;
(1/7) / (3/7) 刚好等于 1/3;
*当特征值很多的时候,这个复杂的公式就很有效,问题: 特征值是指 “桶子”很多,还是“颜色”很多,还是这两个都算特征?
贝叶斯准则:用于交换条件概率中的 条件与结果,即:已知P(X|C) , 求 P(C|X) , P(C|X) = P(x|c)*P(C) / P(X)
p(c1|x,y) ,代表某个由 x、y的数据点,该数据点来自类别c1的概率。
p(x,y|c1),代表c1这个类别,在样本中的概率(猜测)。*使用贝叶斯准则来交换概率中的 条件与结果,就是,已知三个概率值,来计算未知的概率值。
如果 P(c1|x,y) > p(c2|x,y),那么类别属于c1
(**由统计学知,如果每个特征需要N个样本,那么,对于10个特征,就需要N的10次方个样本;如果特征之间相互独立,那么样本就可以减少到10*N个)
(所谓独立,就是一个特征,这里指单词,出现的可能性和其他单词相邻没有关系,实际上,某些单词,出现在某些特定单词的概率,其实是有区别的)
(朴素贝叶斯的另一个假设是,每个特征同样重要,就是等权)。
************************************************************************************************************************************************************************************************
使用朴素贝叶斯进行文档分类:
*数据准备:
1.准备一些已经分好类的文档作为“训练数据”,数据形式:
word1,word2,.....类型A;
word3,word4,.....类型B;
word5,word6,.....类型C;
word7,word8,.....类型A;
............
2. 统计所有训练数据的文档,出现的所有单词,而且不重复的,形成词汇表[word1,word2,word3,word4,word5,word6......];事实上需要考虑有没有必要将所有词都放入词汇表。数据训练:
1.对于词汇表中的每个单词,在文章中是否出现,形成[1(word1出现),0(word2没有出现),........],长度和词汇表一样,这个过程,又叫“将文本转换为数字向量的过程”。
(根据贝叶斯准则,将之前的p(c|x,y)或者p(c|X),以W代表一个文档的数字向量,转换为模型p(ci|w)=p(w|ci)p(ci)/p(w)。p(ci|w),表示这个文档,属于ci的概率;p(ci),表示ci类文档,在所有文档的比例;p(w) ,表示 p(w1)*p(w2)*p(w3)...)
2.计算p(w|ci),展开p(w0,w1,w2,....|Ci),由于朴素贝叶斯是假设w0,w1,w2出现的概率是相互独立的,所以p(w|ci) = p(w0|ci) * p(w1|ci) * p(w2|ci)......... p(wi|ci) = wi这个词数 / 在ci类别中的总词数
亦即 计算出这个文档:
类别c1: (w0在类别c1中出现的概率,w1在类别c1中出现的概率,.............)
类别c2: (w0在类别c2中出现的概率,w1在类别c3中出现的概率,.............)
类别c3: (w0在类别c2中出现的概率,w1在类别c3中出现的概率,.............)
计算 每个 类别 中的 文档 数目
对 每 篇 训练 文档:
对 每个 类别:
如果 词条 出现 在 文档 中 :
增加 该 词条 的 计 数值
增加 所有 词条 的 计 数值
对 每个 类别:
对 每个 词条:
将 该 词条 的 数目 除以 总 词条 数目 得到 条件 概率
返回 每个 类别 的 条件 概率
//在计算p(w0|ci) * p(w1|ci) * p(w2|ci).... 时,如果其中一个概率值为0,那么最后的乘积也为0,为了消除这种影响,“该词条计数值” 初始值设为1;
//由于p(w0|ci)的数值太小,那么相乘的时候,就会趋向0,代数中,有ln(a*b) = ln(a)+ln(b),而且f(x) 和 ln(f(x))具有相同的曲线形状,那么,原来比较f(x) = p(ci|w) 就可以等价于比较 ln(p(ci|w)),以避免精度损失了。
又 在各个类型的概率 都除以 p(w),所以,最终:
比较:p(ci|w)=p(w|ci)p(ci)/p(w) 等价于 比较 ln(sum(w1)/sum(ci's word)) + ln(sum(w2)/sum(ci's word)) + .....+ ln(p(ci)) 的大小
//最终分类函数
def classify(待分类数据中的数字向量,训练数据中各个p(w|ci),训练数据各个p(ci))
对于每个类型ci:
p(ci|w) = ln(p(w1|ci) * 数字向量[0] + ln(pw2|ci)数字向量[1] + ......+ ln(p(ci))
返回最大的p (ci|w) 的ci
*********************************************************************************************************************************************************
改进:上面的数字向量,是根据词有没有出现,以1或0作为特征值,改进后,应该以词出现的次数,作为特征值。
**********************************************************************************************************************************************************