16、朴素贝叶斯算法(高斯、伯努力、多项式)

一、朴素贝叶斯

(一)、什么是贝叶斯

公式.png
导入贝叶斯:
from sklearn.naive_bayes import *
案例.png

案例.png

(二)、多条件的贝叶斯

  • 公式:


    公式.png
  • 案例:


    去自习室的概率.png

    比较去与不去.png
  • 多个参数得预测:


    多个属性.png

  • 独立性假设,每个属性参数时独立的,互不影响。
  • 真实情况中,不存在绝对的不相互影响的情况
  • 我们为了减少计算的复杂的程度,我们假设他们之间是相互独立的
  • 这种方式就叫做----(朴素贝叶斯 )
  • 朴素贝叶斯与贝叶斯公式对比:


    贝叶斯与朴素贝叶斯.png

(三)、朴素贝叶斯代码

  • 案例:


    image.png
  • 如果一个未婚男士具有以上的特点,请问女生会不会嫁给他?

  • 计算:


    贝叶斯公式--- 嫁.png
  • 上面多个属性使用贝叶斯来计算概率是不好计算的。

  • 所以我们使用朴素贝叶斯--假设属性之间是相互独立的。

  • 多个特征集于一身本身就是小概率的事件。


    朴树贝叶斯公式---计算嫁.png
  • 单独提取特征,进行概率的计算,再进行累成、

  • 前提是所有的属性都是相互独立的。

  • 我们在进行判断的时候,算出嫁与不嫁的概率比较其大小---得出结果。

  • 不嫁的计算方式与上面是类似的,下面的额代码会做展示。

(四、)朴素贝叶斯常用的三种模型

  • 朴素贝叶斯基础上+独立性的假设

  • 朴树贝叶斯分三种:

  • (1)高斯分布朴素贝叶斯--》正太分布--GaussianNB


    高斯分布朴素贝叶斯.png

    高斯分布贝叶斯公式.png
  • 如果我们的特征数据,服从正太分布,我们就是用高斯分布的朴素贝叶斯,效果就很好。

  • (2)多项式分布朴素贝叶斯--MultinomialNB。


    多项分布.png
  • 多项分布是二项分布的推广。

  • 多项分布--密度函数


    公式的详解.png
  • (3 )伯努力分布朴素贝叶斯--BernoulliNB。


    伯努力分布.png

    二项分布公式.png
  • 伯努力分布也叫做二项分布(即0-1分布)

  • 实验的结果只有两个--比如抛硬币(结果只有两个)

(五、垃圾短息的分类--如何将文本数量化

  • 量化导包:
from sklearn.feature_extraction.text import CountVectorizer

(一、稀松矩阵)

  • 只保留非零数据的索引信息
  • 用处---减少内存的存储量
  • 稀松矩阵如何转换回去:


    toarray.png
image.png

(二、稠密矩阵)

  • 就是常规的矩阵

(三、两种矩阵的对比)

对比.png

  • 上面讲解这两种矩阵的对比,主要是文本数据使用feature_extraction.text 量化后,为什么转换成稀松矩阵?
  • 就一个作用----减少内存的占用量

import warnings
warnings.filterwarnings("ignore")
import numpy as np
from sklearn import datasets
from sklearn.naive_bayes import GaussianNB,BaseDiscreteNB,MultinomialNB
# 朴素贝叶斯
# 朴素贝叶斯---就是假设属性之间是相互独立的
# 相互不影响的
import matplotlib.pyplot as plt
# 朴素贝叶斯实现垃圾短信的识别
x,y=datasets.load_iris(True)
# 数据x中,花萼的长宽的属性,自然属性都是正太分布的。
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=1028)
plt.hist(x[:,0],bins=20)
# 画出第一个属性的图形--可以看出他们像正态分布
(array([ 4.,  5.,  7., 16.,  9.,  5., 13., 14., 10.,  6., 10., 16.,  7.,
        11.,  4.,  2.,  4.,  1.,  5.,  1.]),
 array([4.3 , 4.48, 4.66, 4.84, 5.02, 5.2 , 5.38, 5.56, 5.74, 5.92, 6.1 ,
        6.28, 6.46, 6.64, 6.82, 7.  , 7.18, 7.36, 7.54, 7.72, 7.9 ]),
 )
output_5_1.png
plt.hist(x[:,1],bins=20)
# 画出第二个属性的图形--可以看出他们像正态分布
(array([ 1.,  3.,  4.,  3.,  8., 14., 14., 10., 26., 11., 19., 12.,  6.,
         4.,  9.,  2.,  1.,  1.,  1.,  1.]),
 array([2.  , 2.12, 2.24, 2.36, 2.48, 2.6 , 2.72, 2.84, 2.96, 3.08, 3.2 ,
        3.32, 3.44, 3.56, 3.68, 3.8 , 3.92, 4.04, 4.16, 4.28, 4.4 ]),
 )
output_6_1.png
plt.hist(x[:,2],bins=20)
# 画出第三个属性的图形--可以看出他们像正态分布
(array([ 4., 33., 11.,  2.,  0.,  0.,  1.,  2.,  3.,  5., 12., 14., 12.,
        17.,  6., 12.,  7.,  4.,  2.,  3.]),
 array([1.   , 1.295, 1.59 , 1.885, 2.18 , 2.475, 2.77 , 3.065, 3.36 ,
        3.655, 3.95 , 4.245, 4.54 , 4.835, 5.13 , 5.425, 5.72 , 6.015,
        6.31 , 6.605, 6.9  ]),
 )
output_7_1.png
plt.hist(x[:,3],bins=20)
# 画出第四个属性的图形--这个不是很像正态分布,但是这个数据中三个都像所有,
# 用高斯分布是最好的。
(array([34.,  7.,  7.,  1.,  1.,  0.,  0.,  7.,  3.,  5., 21., 12.,  4.,
         2., 12., 11.,  6.,  3.,  8.,  6.]),
 array([0.1 , 0.22, 0.34, 0.46, 0.58, 0.7 , 0.82, 0.94, 1.06, 1.18, 1.3 ,
        1.42, 1.54, 1.66, 1.78, 1.9 , 2.02, 2.14, 2.26, 2.38, 2.5 ]),
 )
output_8_1.png

高斯分布

# 使用到的高斯分布
gNB=GaussianNB(priors=[1.0,0,0])
# priors=[1.0,0,0] priors指定预测类别的权重
# priors如果不指定,默认是根据样本的权重来的。
gNB.fit(x_train,y_train)
gNB.score(x_test,y_test)
0.23333333333333334
gNB.class_prior_
array([0.35833333, 0.29166667, 0.35      ])
len(y_train)
120
count=[]
for i in range(3):
    count.append((y_train==i).sum())
count=np.asarray(count)
count/count.sum()
array([0.35833333, 0.29166667, 0.35      ])

伯努力分布

bNB=BernoulliNB()
bNB.fit(x_train,y_train)
bNB.score(x_test,y_test)
0.23333333333333334
np.e**(bNB.class_log_prior_)
array([0.35833333, 0.29166667, 0.35      ])

数据是正泰分布的,使用二项分布是不好的额。

多项分布

mNB=MultinomialNB()
mNB.fit(x_train,y_train)
mNB.score(x_test,y_test)
0.5

正泰分布的数据使用多项分布也是不好的。


(四、短信处理--文本数量化)

转换后的数据分析.png
import numpy as np
import pandas as pd

from sklearn.naive_bayes import GaussianNB,BernoulliNB,MultinomialNB

from sklearn.model_selection import train_test_split

from scipy import sparse

# feature_selection 特征选择!
# feature_extraction 特征提取,萃取
# 土壤中,炼铁,这个过程类比 萃取
# 统计词频!通过词频,判断类别,判断短信是否是垃圾短信
# free、phone、获奖、优惠
from sklearn.feature_extraction.text import CountVectorizer
# 短信数据
sms = pd.read_csv('./SMSSpamCollection.csv',sep = '\t',header= None)
sms.rename({0:'label',1:'message'},axis = 1,inplace = True)
display(sms.shape,sms.head())
(5572, 2)
X = sms[['message']]# 机器学习,要求数据必须是二维的!!!
y = sms['label']
display(type(X),type(y))
display(X.head(),y.head())
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.2)
pandas.core.frame.DataFrame



pandas.core.series.Series
# 我们的短信内容是文本,数据
# 文本数据,计算机,可以进行计算吗?概率计算吗?
gNB = GaussianNB()
gNB.fit(X_train,y_train)
# 计算机中的计算,都是数字化的计算,KNN,LR,决策树,贝叶斯……
# 现在的数据是str,不能计算,不能计算距离,不能计算概率,不能构造决策
# 进行量化
# 将str类型的数据,数量化,数值化
-------------------------------------------------------

ValueError            Traceback (most recent call last)

 in 
      2 # 文本数据,计算机,可以进行计算吗?概率计算吗?
      3 gNB = GaussianNB()
----> 4 gNB.fit(X_train,y_train)


d:\python3.7.4\lib\site-packages\sklearn\naive_bayes.py in fit(self, X, y, sample_weight)
    207         y = column_or_1d(y, warn=True)
    208         return self._partial_fit(X, y, np.unique(y), _refit=True,
--> 209                                  sample_weight=sample_weight)
    210 
    211     def _check_X(self, X):


d:\python3.7.4\lib\site-packages\sklearn\naive_bayes.py in _partial_fit(self, X, y, classes, _refit, sample_weight)
    358         self : object
    359         """
--> 360         X, y = check_X_y(X, y)
    361         if sample_weight is not None:
    362             sample_weight = _check_sample_weight(sample_weight, X)


d:\python3.7.4\lib\site-packages\sklearn\utils\validation.py in check_X_y(X, y, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, multi_output, ensure_min_samples, ensure_min_features, y_numeric, warn_on_dtype, estimator)
    737                     ensure_min_features=ensure_min_features,
    738                     warn_on_dtype=warn_on_dtype,
--> 739                     estimator=estimator)
    740     if multi_output:
    741         y = check_array(y, 'csr', force_all_finite=True, ensure_2d=False,


d:\python3.7.4\lib\site-packages\sklearn\utils\validation.py in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, warn_on_dtype, estimator)
    513                     array = array.astype(dtype, casting="unsafe", copy=False)
    514                 else:
--> 515                     array = np.asarray(array, order=order, dtype=dtype)
    516             except ComplexWarning:
    517                 raise ValueError("Complex data not supported\n"


d:\python3.7.4\lib\site-packages\numpy\core\_asarray.py in asarray(a, dtype, order)
     83 
     84     """
---> 85     return array(a, dtype, copy=False, order=order)
     86 
     87 


ValueError: could not convert string to float: 'Lol no. Just trying to make your day a little more interesting'

文本数据的量化

cv = CountVectorizer()#stop-words 停用词
# 主要目的,节省内存空间
# 量化
X = cv.fit_transform(sms['message'])
display(X)
print(X)
# 保存文件大小是147kb
sparse.save_npz('./sms.npz',X)
# 保存文件大小388M
# 普通numpy矩阵,稠密矩阵
np.savez('./sms2.npz',X.toarray())
<5572x8713 sparse matrix of type ''
    with 74169 stored elements in Compressed Sparse Row format>


  (0, 3571) 1
  (0, 8084) 1
  (0, 4374) 1
  (0, 5958) 1
  (0, 2338) 1
  (0, 1316) 1
  (0, 5571) 1
  (0, 4114) 1
  (0, 1767) 1
  (0, 3655) 1
  (0, 8548) 1
  (0, 4501) 1
  (0, 1765) 1
  (0, 2061) 1
  (0, 7694) 1
  (0, 3615) 1
  (0, 1082) 1
  (0, 8324) 1
  (1, 5538) 1
  (1, 4537) 1
  (1, 4342) 1
  (1, 8450) 1
  (1, 5567) 1
  (2, 4114) 1
  (2, 3373) 1
  : :
  (5570, 4245)  1
  (5570, 8371)  1
  (5570, 1097)  1
  (5570, 4642)  1
  (5570, 7089)  1
  (5570, 3323)  1
  (5570, 7674)  1
  (5570, 1451)  1
  (5570, 5367)  1
  (5570, 2606)  1
  (5570, 8120)  1
  (5570, 1794)  1
  (5570, 7099)  1
  (5570, 2905)  1
  (5570, 3489)  1
  (5570, 1802)  1
  (5570, 3709)  1
  (5570, 4188)  1
  (5570, 914)   1
  (5570, 1561)  1
  (5571, 7806)  1
  (5571, 5276)  1
  (5571, 4253)  2
  (5571, 7938)  1
  (5571, 6548)  1
# 第一条短信的量化数据
'''Go until jurong point, crazy.. Available only in bugis n great world la e buffet... 
Cine there got amore wat...'''
print(X[:1])
  (0, 3571) 1
  (0, 8084) 1
  (0, 4374) 1
  (0, 5958) 1
  (0, 2338) 1
  (0, 1316) 1
  (0, 5571) 1
  (0, 4114) 1
  (0, 1767) 1
  (0, 3655) 1
  (0, 8548) 1
  (0, 4501) 1
  (0, 1765) 1
  (0, 2061) 1
  (0, 7694) 1
  (0, 3615) 1
  (0, 1082) 1
  (0, 8324) 1
'''Rofl. Its true to its name'''
print(X[-1])
  (0, 7806) 1
  (0, 5276) 1
  (0, 4253) 2
  (0, 7938) 1
  (0, 6548) 1
vc = cv.vocabulary_
vc['its']
4253
vc['to']
7806
# scipy中提供了方法
# 稀松矩阵、稠密矩阵 对比
a = np.random.randint(0,10,size = (10,5))
a[a >=3] = 0
s = sparse.csc_matrix(a)
display(a,s)
print(s)
array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 1, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 1, 2, 0, 0],
       [1, 0, 0, 0, 2],
       [2, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]])
# 此时X是稀松矩阵
# 稀松矩阵也可以进行拆分
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.2,random_state = 1187)
X_train
<4457x8713 sparse matrix of type ''
    with 59438 stored elements in Compressed Sparse Row format>
%%time
gNB = GaussianNB() # 高斯分布,是正太分布,数据属性必须是稠密矩阵

gNB.fit(X_train.toarray(),y_train)

print('高斯分布',gNB.score(X_test.toarray(),y_test))
高斯分布 0.8914798206278027
Wall time: 2.03 s
%%time
# 稀松矩阵,计算优势,内存中占有量很小
bNB = BernoulliNB() # 二项分布,数据可以稀松的,准确率提升了很多,计算时间大大缩短
bNB.fit(X_train,y_train)
print('伯努利:',bNB.score(X_test,y_test))
伯努利: 0.9730941704035875
Wall time: 56.1 ms
%%time
mNB = MultinomialNB()
mNB.fit(X_train,y_train)
print('多项式分布:',mNB.score(X_test,y_test))
多项式分布: 0.979372197309417
Wall time: 23.6 ms
# 自然语言处理,用词分布,不是正太分布
import matplotlib.pyplot as plt
dX = X.toarray()
# dX是稠密矩阵, 第一列属性一(单词),第二列属性二(单词),……
dX
array([[0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       ...,
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0]], dtype=int64)
# 不是正太分布了,二项分布
_ = plt.hist(dX[:,1024])
output_18_0.png

你可能感兴趣的:(16、朴素贝叶斯算法(高斯、伯努力、多项式))