数学建模社区-数学中国

标题: 朴素贝叶斯分类器_以python为工具【Python机器学习系列(十三)】 [打印本页]

作者: 杨利霞    时间: 2022-9-5 16:52
标题: 朴素贝叶斯分类器_以python为工具【Python机器学习系列(十三)】
朴素贝叶斯分类器_以python为工具【Python机器学习系列(十三)】
! s# y+ C5 A- Z$ V
. r6 I1 d- e1 [; F, M6 C文章目录
  o6 J- B% F, U( o* V1. 朴素贝叶斯算法原理
) R. K/ Z7 B6 @  k- E2. sklearn提供的朴素贝叶斯算法) C( U2 B! t, K, O: x* t
3. 伯努利朴素贝叶斯 BernoulliNB()
  K, U3 B  c9 {0 j, u& y5 ^) J4. 多项式朴素贝叶斯 MultinomialNB()4 b* y, A* }0 Z
5. 高斯朴素贝叶斯 GaussianNB()/ }' m/ U( ?9 H/ N) y% _% ?
      ʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞ0 }8 F3 i! ], H3 @/ }
! G  c! a6 @1 \" L
    ʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞʚʕ̯•͡˔•̯᷅ʔɞ% Q: w& Y7 Y  V% ?

* x" ~9 Z' i' u, C1 A4 q大家好,我是侯小啾!
7 y: \. X$ q' ]8 K5 i
. O# T. Z! F4 S8 | 今天分享的话题是朴素贝叶斯分类器算法。
$ O  u' F; c6 f' V  R) A7 M0 |) y' [! v2 Z
🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ
7 M- u7 x: D; k- m) N+ T
0 M3 Q3 w0 e. I8 k; V1. 朴素贝叶斯算法原理& r: y- [2 I# n9 P) W
使用贝叶斯算法,首先需要理解的是以下两个公式:
/ d' [( U7 m: U! W
& ]' g# j* p' s3 U* k9 j- b, h. p全概率公式  o  W# `6 F3 ]# d& ^& _
' t3 s$ W5 {' O3 D0 j6 D
     ( B ) = P ( A 1 ) × P ( B ∣ A 1 ) + P ( A 2 ) × P ( B ∣ A 2 ) + . . . + P ( A n ) × P ( B ∣ A n ) P(B)=P(A_1)×P(B|A_1)+P(A_2)×P(B|A_2)+...+P(A_n)×P(B|A_n)P(B)=P(A 2 K. B+ ^, V  I
1& A/ H( F" S( C$ M. N4 h

* A5 ^( l6 u6 { )×P(B∣A
# ^6 k, ^1 I; c& Z* U! g/ {8 D1. x; n5 A( W6 R. Q
% @; V# w3 E% [7 `3 w# e- y
)+P(A
& b; s9 v: }/ L& V2
: w" |+ w. T/ X) z5 F4 N3 d
% M$ `0 z/ J# P( b )×P(B∣A
- R; a( ?# O4 v5 R' Q* y2! W3 T5 `4 z* v  O* h4 L
- U9 L1 N( o4 A/ a4 N; ]) U8 ]
)+...+P(A
2 p* |& R* I- S. G8 g% Gn
, Z* }7 ~) o" g! P9 y, ?/ k" C+ F8 S: \  e' P
)×P(B∣A . V, q! E+ R8 w7 a7 c. l
n( A! L. l  e; H0 S+ z: c( v) O7 R

$ [+ X  l8 r1 d" F  ` )
7 z8 c# ~: f  u$ ~) W; p
9 T! [1 L+ d8 S. h贝叶斯公式
3 K2 U" o8 H# p
# |8 v# @2 N6 o) q) o  p- D           ( A ∣ B ) = P(A|B)=P(A∣B)=P ( A ) × P ( B ∣ A ) P ( B ) \frac{P(A)×P(B|A)}{P(B)} 8 D+ l5 R' u% D  ^1 x. q4 }$ k$ x! s: J
P(B)- p0 O4 ~- i5 k! M) j& f$ ~) r6 ?( `
P(A)×P(B∣A)( K& O" Z' i% o

9 h) |8 Q4 Q- s, U8 ?9 t1 C6 p# Z; t0 Y( Q, Q# l3 ]

* z$ {3 [- v. \% h: S! ]# _            或
) B) w6 U9 {: \# O- p9 C& c! K& i0 v( R! T) r% j
           ( A n ∣ B ) = P(A_n|B)=P(A
% n! h5 o2 D& ]5 g. W' l$ Mn
0 G& Q- A5 @0 i" `9 \5 s1 _6 d
8 O7 E; v. Q, g  @9 A9 U ∣B)=P ( A n ) × P ( B ∣ A n ) P ( B ) \frac{P(A_n)×P(B|A_n)}{P(B)} + Y* P& w, r. x$ [
P(B)4 q6 B7 A" c; W& A; H
P(A % H3 b0 T6 a7 V3 U" H
n& H8 b' v* b8 a" u+ R& z5 j

4 T" \) b: e. c; z. Z: d: W )×P(B∣A
  a+ m: Q0 O. H7 Z  f$ P0 an" N+ O1 ]( r0 S8 Z
& J5 s- P, \8 j$ L% X' q% B  Q
)
) Q3 M) @4 ]7 W. {* Z5 l. P. x
* G& S! W' T) m7 J: T; Q1 O1 ]3 K9 x( H' x" s' O

# |& N5 }0 Z) }( d8 K通俗地讲,假设需要将对某样本分为为0和1二类,其有A,B,C三个特征且值分别为a、b、c,( z, K9 D+ W6 h/ U
则只需要求出,在类别为0前提下特证A、B、C分别为a、b、c的概率:
( p3 m* C4 j% v( R( i( e3 _4 [& C# m7 y2 Z# o" f7 d
         即P ( A = a , B = b , C = c ∣ 类别为 0 ) P(A=a,B=b,C=c|类别为0)P(A=a,B=b,C=c∣类别为0)
5 @  P$ |4 j7 K+ x8 T
2 H) Z$ O: F* A% C9 L和在类别为1的前提下特征A、B、C分别为a、b、c的概率:
% @9 Q% a7 N, \& s: R& ?0 y- Z, k& ]4 C; |9 k& Q
         即P ( A = a , B = b , C = c ∣ 类别为 1 ) P(A=a,B=b,C=c|类别为1)P(A=a,B=b,C=c∣类别为1)1 o# D0 w) }0 Y+ q# B8 q" E

) K# }. a: f! r' e  n0 z即可。
! ]& n2 V, v9 U# g) D然后将这两个概率作比较,大者,则为朴素贝叶斯决策结果所属类别。  z1 J' J1 d8 L7 X9 h) g
或者也可以求出在特征为目标特征的前提下,类别为某类别的概率,这样比较出的结果也是会是一致的。
5 D1 r9 u# W$ F' ^
6 ?* s, c" g! S! r( R+ j7 j+ ^2. sklearn提供的朴素贝叶斯算法
1 F& W' X# U" o, `在python的scikit-learn库中,一共提供了3个朴素贝叶斯的分类算法,分别是GaussianNB(),MultinomialNB()和BernoulliNB()。
- U6 c' y1 L9 f  v/ n0 |5 o( ?8 Z7 U: w* V: t+ T! N6 H# G- @# Y
其中,1 o9 c4 O( v# U3 K1 c4 ~
BernoulliNB() 则表示先验为 伯努利分布 的朴素贝叶斯;) ]$ g( G' T& o& u) R8 j& W
MultinomialNB() 表示先验为 多项式分布 的朴素贝叶斯;
/ ^9 h# K- h: y6 kGaussianNB() 表示先验为 高斯分布(即正态分布)的朴素贝叶斯。% P% K, f' O* j% s0 \3 C# ~7 D

2 B$ A$ s( }; I: z0 z伯努利朴素贝叶斯" v1 m: X) d% e; G, D/ v
其中伯努利分布的较为简单,因为伯努利分布的样本的特征值是离散型的分布,且特征都只有两个取值(比如0或1,是或否)。9 O6 q' i! j; G+ v
多个特征,则对应多个相互独立的伯努利实验,每个实验只进行一次。比如,特征甲,可以是抛一枚硬币,结果可以是正面和反面。特征乙可以是昨天是否下雨,结果可以是“是”或“否”。& z6 x" i5 V/ w3 e( u9 z; b' R
如果特征值是连续的,则算法中可以设定一个阈值(参数名为binarize),对特征值进行二值化处理,后即可满足伯努利分布。, {  c+ b9 t' ~$ v3 Z
& S* n8 \% Z: L: C& n. n
多项式朴素贝叶斯5 ]$ I1 Z3 W3 {6 n4 c2 T' R
多项式分布则是在伯努利分布的基础上进行了多次实验。多项式分布下的多个特征依然分别对应着相互独立的实验,但与伯努利不同的是,每个特征的实验进行了多次。比如,特征甲可以是抛10次硬币正面的次数,特征乙可以是过去七天中下雨的天数(假设每天下雨的概率都一样)。$ F. J6 L; `6 q* K
1 V/ k5 y/ b& d+ ^% N' j& R) y8 g
高斯朴素贝叶斯; j" B% I7 \8 r7 \5 l* q' i9 T/ U
伯努利朴素贝叶斯算法和多项式朴素贝叶斯算法都是对于离散特征的,高斯朴素贝叶斯则常用于连续特征的情况下。高斯朴素贝叶斯假设特征满足高斯分布(正态分布)。如特征为“某地高中生的身高”时,就使用高斯朴素贝叶斯。
% c# V9 `/ \/ `# U" X( _
9 p3 c# C4 v& Q, q/ M3. 伯努利朴素贝叶斯 BernoulliNB()
) a3 O6 b% d" L" A* W+ F8 J! E4 \导包,并准备一组数据,代码如下图所示:2 g9 l1 N+ d# B

# }" Q4 w" g) E% ]# \* C: A7 }import numpy as np
+ }! i( j  D# g5 s5 vfrom sklearn.naive_bayes import BernoulliNB
  m& \; S" A4 f& ]. i6 Y7 c6 C6 qfrom sklearn.datasets import make_blobs
9 p0 O1 s, i% {; s& kfrom sklearn.model_selection import train_test_split
/ A; t5 \2 k( T+ x& w. o3 S" E$ U
# 500个样本,3个特征,3个标签,范围为(-10.0,10.0)。" w9 \# \0 D6 Y0 S8 `
X, y = make_blobs(n_samples=500, n_features=3, centers=3, center_box=(-10.0, 10.0),random_state=10); x# {6 `2 z# ^4 ]
print(X)
, }" {) @" g# D2 f+ `% H, gprint("=================================================================")) L8 s( Y5 S; o5 j+ E
print(y)2 E, O5 Y' n# [  }7 o
13 G' G* s  X  V
2
4 _: ~3 c' h+ j: M) V& l- q3
! t# ]1 z. D& u0 A' [1 {) U# Q2 {& m4: T2 E$ e+ T, n% k3 T5 E# k% ~
5
4 M0 n) y# _9 _9 T5 D$ r6
1 ^; G1 x7 l2 ]" a2 J7
/ J$ U; b' O% N5 o8  S& `) g( u6 c0 P
94 f, U! W- h: P0 z% |$ W" i7 @
10
- f; ]1 r. y' M0 ~2 ?1 o5 n& z, a数据输出如下:4 D. {5 j( T# I2 h

9 |. V2 k5 a  e
) V/ q, G/ h% u2 h数据如图所示,可以看到,特征数据X的取值为连续的,因此要想使用伯努利朴素贝叶斯,需要先对特征数据做二值化处理。做二值化处理需要在实例化BernoulliNB()的时候,选择binarize属性。该属性默认值为0。& \' p$ o/ t& w8 B: L* i) d9 q
官方文档解释:
4 o' W5 i# O( ]4 D, k. O4 K- ^3 y0 J: V9 Y4 s
binarize : float or None, default=0.0
1 J# ^# V( F9 ^0 O* X+ pThreshold for binarizing (mapping to booleans) of sample features.' _/ D9 \- V/ p. n
If None, input is presumed to already consist of binary vectors.
/ Y: |/ q7 G* b
( V4 j9 H6 K/ p0 j  V. Dbinarize:浮点类型或None,默认值为0.0
0 A( M" H2 \) J样本特征二值化(映射到布尔值)的阈值。4 e+ T, \; c& o. h4 B9 W
如果为None,则假定输入的特征数据已经是二值化的向量了。
, W' P6 u' v! e( H' i
( E3 b1 B5 ~  a) e( Q$ s训练模型,并使用测试集数据检验模型得分:& K4 B& C% r( V

6 e. ?5 G6 {+ d/ rX_train,X_test,y_train,y_test=train_test_split(X, y, random_state=10)1 M. g: ^0 g. i- _8 a7 @' }2 w
nb = BernoulliNB()/ z" o2 J- [2 W; u# c2 ~# ^
nb.fit(X_train, y_train)
8 j' G/ I4 _9 P; q" H( n6 {7 W" Gprint('模型得分:{:.3f}'.format(nb.score(X_test, y_test)))
; |6 s# ?# L, T) l1 g1 ?1
, \) i1 w3 q) |' q/ e% @8 j2
9 H2 ]1 }- P9 l3
! P2 v7 `, d9 F& o+ ^! c5 o4
# t9 ?' G# F- a, P8 u: ]于是模型得到了一个“离谱”的得分1.0(简直不能更好):: p( y2 E; f5 c8 k# T% z" G
) Y# H4 u6 u4 h

+ f' m& O$ H, X( b' I输出预测结果:
' e  g7 U  i* z0 Z4 @5 a% x
: s" _! C2 W  G6 Tpred = nb.predict(X_test)  u0 ]8 `5 E; M' S+ l
print(pred)
7 x* \& C: u# {. G, E" t9 F7 Q1. P9 k2 n' s. v9 {
2! A, b& G% B- c/ B4 J. I( ?
1 x* G& d! V8 o
8 w* D4 l! B  Y* l3 P# c! }  ~
4. 多项式朴素贝叶斯 MultinomialNB()
5 y! q. t6 _3 m) \) G2 |- iMultinomialNB()实现了服从多项分布数据的朴素贝叶斯算法。
: U, r. }9 n' V6 Q也是用于文本分类的两大经典朴素贝叶斯算法之一(文本分类领域中数据往往以词向量表示,尽管在实践中 tf-idf 向量在预测时表现良好)。
& j  X' l9 u1 i* V" N
/ a; I1 S1 i1 h) |生成两组随机数,用于示例展示。一组特征值,一组标签。
0 c8 V( u6 F/ J# A3 |' T9 A! |6 W6 ^9 N5 ~/ ~5 I; l+ I2 n2 f
import numpy as np
2 u8 v8 n1 L1 e* nfrom sklearn.naive_bayes import MultinomialNB' u; f- c3 z0 t
from sklearn.model_selection import train_test_split) B+ ?+ `* Q% ]! C7 k" H
3 O# h5 u2 b# y* N" K. Z! t- }
0 v1 ?2 R* f2 l, N
# 设置随机数种子
: [. x1 l8 l( `* l! A/ g2 Z' j; Xnp.random.seed(10)
' `9 G* H) H% D$ _) P' S5 P$ h# 1000个样本,5个特征,每个样本的取值是[0,9]的整数
5 D( O6 W7 |/ U/ y/ Q$ s! jX = np.random.randint(10, size=(1000, 5))
. C) _: Z& _2 Q5 P' l* e) \4 ]# 标签可以有的取值为0,1,2
8 j" O9 S( j7 t% _. ]y = np.random.randint(3, size=[1000])
& z  N) ]5 z/ K5 ]; Lprint(X)$ x0 J7 b. {9 Q' S
print(y)
5 A8 k' s1 |5 s" W  C  h) @1
8 F/ Z* `- S& x" V, p6 W) v: N0 Z2
9 r1 y1 m4 ?& N4 Y: o4 e: f30 A$ Y5 j8 B, |
4* n; b3 m, }9 R- V; V9 z
5
2 X% q6 z* _+ y3 F( C. }- h6. P7 b5 u- {6 R
7
4 o0 M6 C% E# P# i1 k/ x# e  x8
5 Q8 Z( _( X$ w, k) d/ T, Z90 z' {( l9 s& }2 H. j
106 y% I* Z" l2 Q; z$ n' [
11# x' N/ Q1 [6 X1 k
122 t* B+ v5 |) c( d; B; n' z
13. Y; _; O) X5 A  l3 r( k
部分数据展示如下:
0 G0 W- u* l+ q- T
; T; j( s1 ~; b6 m7 R. |
% B1 l! M: X! E* t6 t! x7 n2 @) P+ `# 分割数据1 [) O% i3 {4 @
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=10)
* p: A" u& w+ Z  a# 训练多项式朴素贝叶斯模型/ Q% n  ~6 F5 X( d" p+ r6 S
nb = MultinomialNB()
& {9 Y4 V1 ?* \* snb.fit(X_train, y_train)
3 L/ ]- |4 U0 r3 H- K+ R
7 x; E9 z9 a% ^7 q# Tprint('模型得分:{:.3f}'.format(nb.score(X_test, y_test)))* g" l1 x9 l" u' H5 U, b
pred = nb.predict(X_test)$ U/ c- k4 P+ O" G6 j
print(pred)6 a  Z* S3 s9 T" D
1
% z0 }7 m9 x: ~% {+ ?) W2# W3 V  d1 e3 s4 h5 e' {% W! A
3" m/ V, f+ S0 E7 b
4" {5 p: x2 q  Q2 u
5) A9 E0 [9 [! B+ J
6
6 q, }2 c$ P2 d/ }7( g; C; }, l; w" S& @* p: M
89 Y/ ^3 K3 d7 c: ~+ m2 \2 ^
94 W# t5 g" s! w4 ~, f( X8 V
模型得分及预测结果如下图所示:
: D0 {$ ]# U" F  P/ N$ x2 Q& E; g2 w
2 B3 }$ w# B( `0 l$ N, }' y因为数据是随机生成的,所以这里的特征与标签之间无逻辑关系可言,以至于这里的模型得分偏低。但是算法是有效的。/ \7 l6 ~8 _+ B: L9 A% I* ?  M0 \

* p7 f. M" w9 U# L4 F# Y2 U0 A7 X3 L5. 高斯朴素贝叶斯 GaussianNB()
$ C: ~% ^1 {0 Q, ?符合高斯分布的数据也是连续的数值,所以不像伯努利分布的特征数据那样直接可以直接计算概率,但是也不是要做二值化处理。因为其符合正态分布,所以可以直接从正态分布中找到其概率值,
/ |7 W! j; l8 W( e6 q: w8 r; ^: l8 s- H
假设以某学校同学的身高数据为例,其中男生身高满足均值为176,标准差差为10的正态分布,则已知某同学为男生,其身高为180的概率为:
- S3 z. i) x2 r, O7 N* e$ Q. M7 L) p) v5 ^8 q. H6 T, ?
print(stats.norm.pdf(180, 174, 6))
, P- V, f1 F, a* ]) t  Y" U1  F+ b8 {, o7 T! T2 U1 {
( {/ c/ h6 j1 O* S. q7 v% v& K
这个概率值虽然不大,但是如果与女生的数据相比,若女生的身高为180的概率小于0.0368,则由此可以判断出该同学为男生。; W' I" s, s$ X6 @6 M% f& h3 e

2 U. {! g2 ]  y+ ~, O6 J5 u根据这样原理,我们使用sklearn库做如下高斯贝叶斯代码示例:
+ i8 d) G1 }4 J
1 N; [: `. b8 G& r9 fimport numpy as np' @5 ?3 t# o+ b; P9 d
from sklearn.naive_bayes import GaussianNB
9 n; w" i& W6 v8 T9 G/ ?/ Z) Vfrom sklearn.model_selection import train_test_split
/ x* t0 b) [) Q) \$ ~9 @% U6 X. O% x7 S% Y

2 {5 [% M3 o$ D# 设置随机数种子
9 q/ b7 g) F1 k) v/ I: H1 jnp.random.seed(10)
0 l1 F5 x4 H! ~# 特征值:均值为4,标准差为5的正态分布,10000个样本,3个特征
2 D' d0 U8 |) [, WX = np.random.normal(4, 5, (10000, 3)). B! ]; i" ^+ A2 D, k4 w
# 标签值:0,1,2+ b0 S" J( Z$ [8 G0 H5 C
y = np.random.randint(3, size=[10000])
4 ^9 v, p& ^3 `3 U9 S6 V/ q' p  D& P% F  N
print(X)
* F: h/ U# A- `/ r$ }6 U8 uprint(y), d6 d; ^0 U8 a7 P' f# X  \: c
1
: E- R+ h/ M9 n. ]2, ?. E% H  B+ R& w  O' b
33 P& Y2 O# q( d/ \/ Q3 @6 o% q
4
9 P$ O/ i; a  E! G2 ^" h) W+ P5
+ K$ v% Z7 {% c  [; F1 B+ a( a61 Q; D- h6 K# L  b
7' p* U6 X2 P6 P1 S
8
. b* E8 z0 |- g& I  P3 r& r! c95 Y9 Q2 c6 o. o  G, W- Z
10
9 B' S; u* t- O1 T# s11: d, U" L: C! y( M
12
  k- b& c2 B% W6 ^: e5 ~- Z/ m13% B, H" u% g5 \' `
149 _, m! B% B3 m. m
生成数据如下图所示:
8 y' y) ?6 h* {0 {/ V) D5 U# h5 a! O1 Y' j7 X& ]( g1 l+ J7 K
. E# c1 |" k% P3 V4 K+ e2 H
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=10)9 r5 X& ~' O" }+ l( v7 j
nb = GaussianNB()& O  D4 U. x+ [# I6 w9 {* K! a
nb.fit(X_train, y_train)
% a2 M6 O2 y: Q
7 k. H# G, E* Uprint('模型得分:{:.3f}'.format(nb.score(X_test, y_test)))
3 p1 j$ m9 q. B% L# ^" g+ G- ?$ {) V: r7 p0 A& E0 X! e
pred = nb.predict(X_test)& b4 B# Q' s9 g, {
print(pred): j* J; s- F' C  @( {
————————————————
1 a1 y* O' t  C' l版权声明:本文为CSDN博主「侯小啾」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。) d# w  l* `8 N( u2 @/ m+ Z3 ]! l
原文链接:https://blog.csdn.net/weixin_48964486/article/details/126337511
9 T- Q* D& [0 C, X, `
0 _1 X8 r0 i, E4 W) E/ D, l
* H& ^5 J9 d1 F, ]1 Z$ p# O2 }




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5