美文网首页
16、朴素贝叶斯算法(高斯、伯努力、多项式)

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

作者: 羽天驿 | 来源:发表于2020-04-13 22:27 被阅读0次

    一、朴素贝叶斯

    (一)、什么是贝叶斯

    公式.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 ]),
     <a list of 20 Patch objects>)
    
    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 ]),
     <a list of 20 Patch objects>)
    
    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  ]),
     <a list of 20 Patch objects>)
    
    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 ]),
     <a list of 20 Patch objects>)
    
    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)
    
    <ipython-input-12-0f6a1b7ae1aa> in <module>
          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 '<class 'numpy.int64'>'
        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 '<class 'numpy.int64'>'
        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、朴素贝叶斯算法(高斯、伯努力、多项式)

          本文链接:https://www.haomeiwen.com/subject/sgiwmhtx.html