朴素贝叶斯

朴素贝叶斯

朴素贝叶斯分类器是一个以贝叶斯定理为基础的多分类的分类器。

对于给定数据,首先基于特征的条件独立性假设,学习输入输出的联合概率分布,然后基于此模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出y。

概率论基础

概率定义为一件事情发生的可能性。事情发生的概率可以通过观测数据中的事件发生次数来计算,事件发生的概率等于该事件发生次数除以所有事件发生的总次数。举一些例子:

  • 扔出一个硬币,结果头像朝上
  • 某天是晴天
  • 某个单词在未知文档中出现

我们将事件的概率记作P(X),那么假设这一事件为X属于样本空间中的一个类别,那么0≤P(X)≤1。

联合概率与条件概率

  • 联合概率

是指两件事情同时发生的概率。那么我们假设样本空间有一些天气数据:

编号 星期几 天气
1 2 晴天
2 1 下雨
3 3 晴天
4 4 晴天
5 1 下雨
6 2 下雪
7 3 下雪

那么天气被分成了三类,那么
P\left(X=sun\right){=}\frac{3}{7}
,假如说天气=下雪且星期几=2?这个概率怎么求?这个概率应该等于两件事情为真的次数除以所有事件发生 的总次数。我们可以看到只有一个样本满足天气=下雪且星期几=2,所以这个概率为1/7。一般对于X和Y来说,对应的联合概率记为P(XY)。

  • 条件概率

那么条件概率形如P(XY),这种格式的。表示为在Y发生的条件下,发生X的概率。假设X代表星期,Y代表天气,则 P(X=3∣Y=sun)如何求?

从表中我们可以得出,
P\left({X=3,Y=sun}\right){=}\frac{1}{7},P\left({Y}\right){=}\frac{3}{7}

P\left({X=3}\mid{Y=sun}\right){=}\frac{1}{3}{=}\frac{P\left({X=3,Y=sun}\right)}{P\left({Y}\right)}

在条件概率中,有一个重要的特性

  • 如果每个事件之间相互独立

那么则有
P\left({X_1,X_2,X_3,...,X_n}\mid{Y_i}\right){=}{P}\left({X_1}\mid{Y_i}\right) {P}\left({X_2}\mid{Y_i}\right) {P}\left({X_3}\mid{Y_i}\right){...}{P}\left({X_n}\mid{Y_i}\right)
这个式子的意思是给定条件下,所有的X的概率为单独的Y条件下每个X发生的概率乘积,我们通过后面再继续去理解这个式子的具体含义。

贝叶斯公式

首先我们给出该公式的表示,
P\left({c_i}\mid{W}\right){=}\frac{P\left({W}\mid{c_i}\right)P\left({c_i}\right)}{P\left({W}\right)}
,其中ci为类别,W为特征向量。

贝叶斯公式最常用于文本分类,上式左边可以理解为给定一个文本词向量W,那么它属于类别ci的概率是多少。那么式子右边分几部分,P(Wci)理解为在给定类别的情况下,该文档的词向量的概率。可以通过条件概率中的重要特性来求解。

假设我们有已分类的文档,

a = "life is short,i like python"
b = "life is too long,i dislike python"
c = "yes,i like python"
label=[1,0,1]

词袋法的特征值计算

若使用词袋法,且以训练集中的文本为词汇表,即将训练集中的文本中出现的单词(不重复)都统计出来作为词典,那么记单词的数目为n,这代表了文本的n个维度。以上三个文本在这8个特征维度上的表示为:

词袋.png

上面a',b'就是两个文档的词向量的表现形式,对于贝叶斯公式,从label中我们可以得出两个类别的概率为:
P\left({c_i=1}\right){=}0.5,P\left({c_i=0}\right){=}0.5
对于一个给定的文档类别,每个单词特征向量的概率是多少呢?

提供一种TF计算方法,为类别yk每个单词出现的次数Ni/N,除以文档类别yk中所有单词出现次数的总数N
P_i{=}\frac{N_i}{N}
首先求出现总数,对于1类别文档,在a'中,就可得出总数为1+1+1+1+1+1=6,c'中,总共1+1+1+1=4,故在1类别文档中总共有10次

每个单词出现总数,假设是两个列表,a'+c'就能得出每个单词出现次数,比如
P\left({w=python}\mid{ci=1}\right){=}\frac{2}{10}{=}{0.20000000}
,同样可以得到其它的单词概率。最终结果如下:

# 类别1文档中的词向量概率
p1 = [0.10000000,0.10000000,0.20000000,0.10000000,0,0.20000000,0,0,0.20000000,0.10000000]
# 类别0文档中的词向量概率
p0 = [0.16666667,0.16666667,0.16666667,0,0.16666667,0,0.16666667,0.16666667,0.16666667,0]

拉普拉斯平滑系数

为了避免训练集样本对一些特征的缺失,即某一些特征出现的次数为0,在计算
P\left({X_1,X_2,X_3,...,X_n}\mid{Y_i}\right)
的时候,各个概率相乘最终结果为零,这样就会影响结果。我们需要对这个概率计算公式做一个平滑处理:
P_i{=}\frac{N_i+\alpha}{N+\alpha*m}
其中m为特征词向量的个数,α为平滑系数,当α*=1,称为拉普拉斯平滑.

上述主要讲述的是离散的数据特征例如词向量,连续数据条件概率采用的高斯分布.

如果没理解透彻,请参考周志华《机器学习》中的第7章7.3节.

sklearn中的朴素贝叶斯

在sklearn库中,实现了三个朴素贝叶斯分类器,如下表所示:

朴素贝叶斯.png

GaussianNB应用于连续数据

MultinomialNB和BernoulliNB主要用于文本分类,其中BernoulliNB为二分类数据

  • sklearn.naive_bayes.GaussianNB

  • 主要参数:

    • priors :类似数组,形状为(n_classes,),给定各个类别的先验概率。如果为空,则按训练数据的实际情况进行统计;如果给定先验概率,则在训练过程中不能更改。

    • class_prior_:数组,形状为(n_classes,),是每个类别的概率 。

    • class_count_:数组,形状为(n_classes,),是每个类别包含的训练样本数量。

    • theta_:数组,形状为(n_classes,n_features),是每个类别上,每个特征的均值。

    • sigma_:数组,形状为(n_classes,n_features),是每个类别上,每个特征的标准差。

  • 模型方法:

    • fit(X, y[, sample_weight]):训练模型。

    • partial_fit(X, y[, classes, sample_weight]):分批训练模型。

      该方法主要用于大规模数据集的训练。此时可以将大数据集划分成若干个小数据集,然后在这些小数据集上连续调用partial_fit方法来训练模型。

    • predict(X):用模型进行预测,返回预测值。

    • predict_log_proba(X):返回一个数组,数组的元素依次是X预测为各个类别的概率的对数值。

    • predict_proba(X):返回一个数组,数组的元素依次是X预测为各个类别的概率值 。

    • score(X, y[, sample_weight]):返回模型的预测性能得分。

鸢尾花分类

(用于多分类,3类: Iris Setosa,Iris Versicolour,Iris Virginica)

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import classification_report

# 加载iris数据
iris = load_iris()

# 将数据分为训练集和测试集,一般test_size设为0.25
X_train,X_test,y_train,y_test = train_test_split(iris.data,iris.target,test_size=0.25,random_state=1) 

# 进行标准化
std = StandardScaler()
X_train = std.fit_transform(X_train)
X_test = std.transform(X_test)
Gnb = GaussianNB()
Gnb.fit(X_train,y_train)
y_predict = Gnb.predict(X_test) # 对测试验本进行类别预测,结果存储在变量y_predict中
y_predict_proba = Gnb.predict_proba(X_test)
print('测试集分类预测结果概率:\n{}'.format(y_predict_proba[0])) # 查看测试集中第一个数据对iris类别的各自概率
#print('测试集分类预测结果名称:{}'.format(iris.target_names[y_predict]))
#print('测试集目标值名称:{}'.format(iris.target_names[y_test]))
print('测试集分类预测结果:\n{}'.format(y_predict[:20]))
print('测试集分类结果:\n{}'.format(y_test[:20]))
score = Gnb.score(X_test,y_test)
print('测试集精度:{:.2f}'.format(score))
cfr = classification_report(y_test, y_predict, target_names= iris.target_names)
print('每类的精确率和召回率:\n{}'.format(cfr))
测试集分类预测结果概率:
[1.00000000e+00 1.45222469e-17 8.89383662e-24]
测试集分类预测结果:
[0 1 1 0 2 1 2 0 0 2 1 0 2 1 1 0 1 1 0 0]
测试集分类结果:
[0 1 1 0 2 1 2 0 0 2 1 0 2 1 1 0 1 1 0 0]
测试集精度:0.97
每类的精确率和召回率:
              precision    recall  f1-score   support

      setosa       1.00      1.00      1.00        13
  versicolor       1.00      0.94      0.97        16
   virginica       0.90      1.00      0.95         9

   micro avg       0.97      0.97      0.97        38
   macro avg       0.97      0.98      0.97        38
weighted avg       0.98      0.97      0.97        38
  • sklearn.naive_bayes.MultinomialNB

  • 主要参数:

    • alpha:一个浮点数,平滑系数,当alpha=1,称为拉普拉斯平滑。

    • fit_prior:一个布尔值。

      • 如果为True,则不去学习 ,替代以均匀分布。
      • 如果为False ,则去学习 。
    • class_prior:一个数组。它指定了每个分类的先验概率 。

      如果指定了该参数,则每个分类的先验概率不再从数据集中学得

  • 模型方法:

    参考 GaussianNB .

互联网新闻分类

(用于多分类,20类)

from sklearn.datasets import fetch_20newsgroups
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import classification_report

# 读取20类新闻文本的数据
news = fetch_20newsgroups(subset='all')
#print(news.data[0])

# 20类新闻文本数据分割
X_train,X_test,y_train,y_test = train_test_split(news.data,news.target,
                                                 test_size=0.25,random_state=0)

# 文本转换特征向量进行TF特征抽取
vec = CountVectorizer()
X_train = vec.fit_transform(X_train) # 将训练数据输入,并转换为特征向量
#print(X_train[0])
X_test = vec.transform(X_test)
#print('*'*80)
#print(X_test)

# 利用朴素贝叶斯分类器对文本数据进行类别预测
mnb = MultinomialNB(alpha=1.0) # 使用平滑处理初始化的朴素贝叶斯模型
mnb.fit(X_train,y_train) # 利用训练数据对模型参数进行估计
y_predict = mnb.predict(X_test) # 对测试验本进行类别预测,结果存储在变量y_predict中
y_predict_proba = mnb.predict_proba(X_test)
print('测试集分类预测结果概率:\n{}'.format(y_predict_proba[0])) # 查看测试集中第一个数据对20组新闻类别的各自概率
print('测试集分类预测结果:\n{}'.format(y_predict[:20]))
print('测试集分类结果:\n{}'.format(y_test[:20]))
score = mnb.score(X_test,y_test)
print('测试集精度:{:.2f}'.format(score))
cfr = classification_report(y_test, y_predict, target_names=news.target_names)
print('每类的精确率和召回率:\n{}'.format(cfr))
测试集分类预测结果概率:
[4.98739447e-31 1.00925077e-05 1.11033466e-09 3.85132805e-05
 1.89998388e-06 1.41381428e-10 1.12837261e-14 1.22367542e-15
 4.05916326e-17 7.94659918e-26 1.04745472e-19 7.09362276e-21
 9.99949493e-01 3.97520708e-22 8.49755237e-24 1.41131047e-31
 1.06587045e-26 3.52339335e-28 1.12665056e-23 9.64847933e-28]
测试集分类预测结果:
[12  6 10 12 11  3  1 11 15 15  4  3 10  7 14 12 11 18 15 10]
测试集分类结果:
[ 2  6 10 12  2  3 18 11 15 15  4  3 10  7 14 12  1 14 15 10]
测试集精度:0.86
每类的精确率和召回率:
                          precision    recall  f1-score   support

             alt.atheism       0.88      0.91      0.89       205
           comp.graphics       0.72      0.87      0.79       245
 comp.os.ms-windows.misc       0.98      0.22      0.36       250
comp.sys.ibm.pc.hardware       0.62      0.87      0.72       243
   comp.sys.mac.hardware       0.89      0.88      0.88       255
          comp.windows.x       0.76      0.90      0.82       240
            misc.forsale       0.93      0.74      0.83       249
               rec.autos       0.87      0.91      0.89       219
         rec.motorcycles       0.99      0.92      0.95       246
      rec.sport.baseball       0.93      0.96      0.94       227
        rec.sport.hockey       0.97      0.96      0.96       287
               sci.crypt       0.80      0.97      0.88       234
         sci.electronics       0.87      0.78      0.82       247
                 sci.med       0.95      0.92      0.94       250
               sci.space       0.90      0.96      0.93       240
  soc.religion.christian       0.82      0.95      0.88       250
      talk.politics.guns       0.88      0.96      0.92       211
   talk.politics.mideast       0.92      0.99      0.95       246
      talk.politics.misc       0.87      0.89      0.88       209
      talk.religion.misc       0.93      0.53      0.67       159

               micro avg       0.86      0.86      0.86      4712
               macro avg       0.87      0.86      0.85      4712
            weighted avg       0.87      0.86      0.85      4712

性能测试分析

多项式朴素贝叶斯分类器被广泛应用于海量互联网文本分类任务。由于其较强的特征条件独立假设,使得模型预测所需要估计的参数规模从幂指数量级想线性量级减少,极大的节约了内存消耗和计算时间。到那时,也正是受这种强假设的限制,模型训练时无法将各个特征之间的联系考量在内,使得该模型在其他数据特征关联性较强的分类任务上的性能表现不佳.

  • sklearn.naive_bayes.BernoulliNB

  • 主要参数:

    • binarize :一个浮点数或者None

    ​ 如果为None,那么会假定原始数据已经是二元化的。

    • 如果是浮点数,则执行二元化策略:以该数值为界:

      • 特征取值大于它的作为 1 。
      • 特征取值小于它的作为 0 。
    • 其它参数参考MultinomialNB

  • 模型方法:参考MultinomialNB

乳腺癌分类

(用于二分类,良性和恶性)

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.naive_bayes import BernoulliNB
from sklearn.metrics import classification_report

# 加载breast_cancer数据
bc = load_breast_cancer()
print('乳腺癌分类:{}'.format(bc.target_names))

# 将数据分为训练集和测试集,一般test_size设为0.25
X_train,X_test,y_train,y_test = train_test_split(bc.data,bc.target,test_size=0.25,random_state=1) 

# 进行标准化
std = StandardScaler()
X_train = std.fit_transform(X_train)
X_test = std.transform(X_test)
Bnb = BernoulliNB()
Bnb.fit(X_train,y_train)
y_predict = Bnb.predict(X_test) # 对测试验本进行类别预测,结果存储在变量y_predict中
y_predict_proba = Bnb.predict_proba(X_test)
#print('测试集预测结果名称:{}'.format(iris.target_names[y_predict]))
#print('测试集目标值名称:{}'.format(iris.target_names[y_test]))
print('测试集分类预测结果概率:\n{}'.format(y_predict_proba[0])) # 查看测试集中第一个数据的各自类别概率
print('测试集分类预测结果:\n{}'.format(y_predict[:20]))
print('测试集分类结果:\n{}'.format(y_test[:20]))
score = Bnb.score(X_test,y_test)
print('测试集精度:{:.2f}'.format(score))
cfr = classification_report(y_test, y_predict, target_names= bc.target_names)
print('每类的精确率和召回率:\n{}'.format(cfr))
乳腺癌分类:['malignant' 'benign']
测试集分类预测结果概率:
[9.99999992e-01 7.75162892e-09]
测试集分类预测结果:
[0 1 1 0 0 0 0 0 1 1 1 0 0 1 1 1 1 1 1 0]
测试集分类结果:
[1 0 1 0 0 0 0 0 1 1 1 0 0 1 1 1 1 1 1 0]
测试集精度:0.91
每类的精确率和召回率:
              precision    recall  f1-score   support

   malignant       0.89      0.87      0.88        55
      benign       0.92      0.93      0.93        88

   micro avg       0.91      0.91      0.91       143
   macro avg       0.91      0.90      0.90       143
weighted avg       0.91      0.91      0.91       143

参考资料:
《python机器学习基础教程》《python机器学习应用》《黑马程序员之机器学习》《Python 大战机器学习》《sklearn官方文档》《AI工程师手册》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容