算法|【机器学习】朴素贝叶斯实战


文章目录

  • 【机器学习】朴素贝叶斯实战
    • 1. 贝叶斯公式
    • 2. 朴素贝叶斯分类器
    • 3. 垃圾邮件分类

【机器学习】朴素贝叶斯实战 1. 贝叶斯公式 P ( B i ∣ A ) = P ( B i ) P ( A ∣ B i ) ∑ j = 1 n P ( B j ) P ( A ∣ B j ) ( i = 1 , 2 , … , n ) P\left(B_{i} \mid A\right)=\frac{P\left(B_{i}\right) P\left(A \mid B_{i}\right)}{\sum_{j=1}^{n} P\left(B_{j}\right) P\left(A \mid B_{j}\right)}(i=1,2, \ldots, n) P(Bi?∣A)=∑j=1n?P(Bj?)P(A∣Bj?)P(Bi?)P(A∣Bi?)?(i=1,2,…,n)
【算法|【机器学习】朴素贝叶斯实战】**意义:**在事件A已经发生的条件下,贝叶斯公式可用来寻找导致A发生的各种原因B的概率。
2. 朴素贝叶斯分类器 由贝叶斯公式可以推断朴素贝叶斯分类器是一个生成式模型(建立条件概率模型用于求解最大化后验模型)。
下面举例说明朴素贝叶斯分类器的计算过程。
算法|【机器学习】朴素贝叶斯实战
文章图片

  • 计算先验概率(结果)和条件概率
    算法|【机器学习】朴素贝叶斯实战
    文章图片

  • 样例判别,根据先验类别逐一计算验证
    算法|【机器学习】朴素贝叶斯实战
    文章图片

    注意:当遇到连续型数据时通过高斯分布计算
    f ( x ) = 1 2 π σ exp ? ( ? ( x ? μ ) 2 2 σ 2 ) f(x)=\frac{1}{\sqrt{2 \pi} \sigma} \exp \left(-\frac{(x-\mu)^{2}}{2 \sigma^{2}}\right) f(x)=2π ?σ1?exp(?2σ2(x?μ)2?)
    注意:训练集中属性值未出现的情况下要进行“拉普拉斯修正”
    P ^ ( c ) = ∣ D c ∣ + 1 ∣ D ∣ + N P ^ ( x i ∣ c ) = ∣ D c , x i ∣ + 1 ∣ D ∣ + N i \hat{P}(c)=\frac{\left|D_{c}\right|+1}{|D|+N} \quad \hat{P}\left(x_{i} \mid c\right)=\frac{\left|D_{c, x_{i}}\right|+1}{|D|+N_{i}} P^(c)=∣D∣+N∣Dc?∣+1?P^(xi?∣c)=∣D∣+Ni?∣Dc,xi??∣+1?
    注意:当属性数量多的情况下,导致累乘结果下溢。采用防溢出策略(累乘变累加)
    ln ? ( a ? b ) = ln ? ( a ) + ln ? ( b ) \ln \left(a^{*} b\right)=\ln (a)+\ln (b) ln(a?b)=ln(a)+ln(b)
3. 垃圾邮件分类 算法|【机器学习】朴素贝叶斯实战
文章图片

计算每种结果出现的概率:
P ( S p a m ) = 2 5 P ( H a m ) = 3 5 P(Spam)=\frac{2}{5}\\ P(Ham)=\frac{3}{5} P(Spam)=52?P(Ham)=53?
计算每个词条属性出现的概率(属性所属类别中该属性出现的次数?属性所属类别出现的词条总数):
P ( c h a n n e l ∣ S p a m ) = 2 8 P ( c h a n n e l ∣ H a m ) = 2 8 P ( c h e c k ∣ S p a m ) = 1 8 P ( c h e c k ∣ H a m ) = 2 8 P ( f a n ∣ S p a m ) = 0 8 P ( f a n ∣ H a m ) = 2 8 P ( g r e a t ∣ S p a m ) = 0 8 P ( g r e a t ∣ H a m ) = 2 8 P ( l i k e ∣ S p a m ) = 1 8 P ( l i k e ∣ H a m ) = 2 8 P ( l o v e ∣ S p a m ) = 1 8 P ( l o v e ∣ H a m ) = 2 8 P ( s o n g ∣ S p a m ) = 2 8 P ( s o n g ∣ H a m ) = 2 8 P ( t u b e ∣ S p a m ) = 1 8 P ( t u b e ∣ H a m ) = 2 8 P(channel|Spam)=\frac{2}{8} \quad P(channel|Ham)=\frac{2}{8}\\ P(check|Spam)=\frac{1}{8}\quad P(check|Ham)=\frac{2}{8}\\ P(fan|Spam)=\frac{0}{8} \quad P(fan|Ham)=\frac{2}{8}\\ P(great|Spam)=\frac{0}{8} \quad P(great|Ham)=\frac{2}{8}\\ P(like|Spam)=\frac{1}{8} \quad P(like|Ham)=\frac{2}{8}\\ P(love|Spam)=\frac{1}{8} \quad P(love|Ham)=\frac{2}{8}\\ P(song|Spam)=\frac{2}{8} \quad P(song|Ham)=\frac{2}{8}\\ P(tube|Spam)=\frac{1}{8} \quad P(tube|Ham)=\frac{2}{8} P(channel∣Spam)=82?P(channel∣Ham)=82?P(check∣Spam)=81?P(check∣Ham)=82?P(fan∣Spam)=80?P(fan∣Ham)=82?P(great∣Spam)=80?P(great∣Ham)=82?P(like∣Spam)=81?P(like∣Ham)=82?P(love∣Spam)=81?P(love∣Ham)=82?P(song∣Spam)=82?P(song∣Ham)=82?P(tube∣Spam)=81?P(tube∣Ham)=82?
以love song为例:
P ( S p a m ∣ l o v e s o n g ) = 2 5 × 1 8 × 2 8 = 1 80 P ( H a m ∣ l o v e s o n g ) = 3 5 × 2 8 × 2 8 = 3 80 3 80 > 1 80 所 以 类 别 为 H a m P(Spam|love song) = \frac{2}{5} \times \frac{1}{8} \times \frac{2}{8}=\frac{1}{80}\\ P(Ham|love song) = \frac{3}{5} \times \frac{2}{8} \times \frac{2}{8}=\frac{3}{80}\\ \frac{3}{80}>\frac{1}{80}\\ 所以类别为Ham P(Spam∣lovesong)=52?×81?×82?=801?P(Ham∣lovesong)=53?×82?×82?=803?803?>801?所以类别为Ham
核心代码:
链接:https://pan.baidu.com/s/1L5VnzRLX06CZkBzXicMUDw
提取码:ima9
""" 函数说明:朴素贝叶斯分类器训练函数 Parameters: trainMatrix - 训练文档矩阵,即setOfWords2Vec返回的returnVec构成的矩阵 trainCategory - 训练类别标签向量,即loadDataSet返回的classVec Returns: p0Vect - 正常邮件类的条件概率数组 p1Vect - 垃圾邮件类的条件概率数组 pAbusive - 文档属于垃圾邮件类的概率 """ def trainNB0(trainMatrix, trainCategory): numTrainDocs = len(trainMatrix)# 计算训练的文档数目 print("文档数目:", numTrainDocs) numWords = len(trainMatrix[0])# 计算每篇文档的词条数 print("词条数", numWords) print("---:", trainCategory) # 形状[40,37] print("---:", trainMatrix) pAbusive = sum(trainCategory) / float(numTrainDocs)# 文档属于垃圾邮件类的概率 p0Num = np.ones(numWords) p1Num = np.ones(numWords)# 创建numpy.ones数组,词条出现数初始化为1,拉普拉斯平滑 p0Denom = 2.0 p1Denom = 2.0# 分母初始化为2 ,拉普拉斯平滑 for i in range(numTrainDocs): if trainCategory[i] == 1:# 统计属于侮辱类的条件概率所需的数据,即P(w0|1),P(w1|1),P(w2|1)··· print("p1Num",p1Num) p1Num += trainMatrix[i] print("p1Denom",p1Denom) p1Denom += sum(trainMatrix[i]) else:# 统计属于非侮辱类的条件概率所需的数据,即P(w0|0),P(w1|0),P(w2|0)··· p0Num += trainMatrix[i] p0Denom += sum(trainMatrix[i]) print("1:",p1Num / p1Denom) print("0:",p0Num / p1Denom) p1Vect = np.log(p1Num / p1Denom) p0Vect = np.log(p0Num / p0Denom)#取对数,防止下溢出 return p0Vect, p1Vect, pAbusive# 返回属于正常邮件类的条件概率数组,属于侮辱垃圾邮件类的条件概率数组,文档属于垃圾邮件类的概率""" 函数说明:朴素贝叶斯分类器分类函数 Parameters: vec2Classify - 待分类的词条数组 p0Vec - 正常邮件类的条件概率数组 p1Vec - 垃圾邮件类的条件概率数组 pClass1 - 文档属于垃圾邮件的概率 Returns: 0 - 属于正常邮件类 1 - 属于垃圾邮件类 """ def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1): p1=sum(vec2Classify*p1Vec)+np.log(pClass1) p0=sum(vec2Classify*p0Vec)+np.log(1.0-pClass1) if p1 > p0: return 1 else: return 0

    推荐阅读