美文网首页
2020-05-21 第十二章 朴素贝叶斯模型(python)

2020-05-21 第十二章 朴素贝叶斯模型(python)

作者: 程凉皮儿 | 来源:发表于2020-05-21 19:25 被阅读0次

    01 朴素贝叶斯分类器的介绍

    模型介绍

    朴素贝叶斯模型同样是流行的十大挖掘算法之一,属于有监督的学习算法,专门用于解决分类问题的模型,而且该模型的数学理论并不是很复杂,只需要具备概率论与数理统计的部分知识点即可。
    该分类器的实现思想非常简单,即通过已知类别的训练数据集,计算样本的先验概率,然后利用贝叶斯概率公式测算未知类别样本属于某个类别的后验概率,最终以最大后验概率所对应的类别作为样本的预测值。

    模型的优缺点

    优点

    • 首先算法在运算过程中简单而高效;
    • 其次算法拥有古典概率的理论支撑,分类效率稳定;
    • 最后算法对缺失数据和异常数据不太敏感;

    缺点

    • 模型的判断结果依赖于先验概率,所以分类结果存在一定的错误率;
    • 对输入的自变量X要求具有相同的特征;
    • 模型的前提假设在实际应用中很难满足;

    贝叶斯理论

    image.png
    image.png
    其中,表示样本所属的某个类别。对于上面的条件概率公式而言,样本最终属于哪个类别,应该将计算所得的最大概率值对应的类别作为样本的最终分类,所以上式可以表示为:
    image.png
    image.png
    分母是一个常量,它与样本属于哪个类别没有直接关系,所以计算的最大值就转换成了计算分子的最大值,即;
    如果分子中的项未知的话,一般会假设每个类别出现的概率相等,只需计算的最大值,然而在绝大多数情况下,是已知的,它以训练数据集中类别的频率作为先验概率,可以表示为。
    假设数据集一共包含p个自变量,则X可以表示成,进而条件概率可以表示为:
    为了使分类器在计算过程中提高速度,提出了一个假设前提,即自变量是条件独立的(自变量之间不存在相关性),所以上面的计算公式可以重新改写为:

    02 几种常见的朴素贝叶斯分类器

    高斯贝叶斯分类器

    如果数据集中的自变量X均为连续的数值型,则在计算P(X|C_i)时会假设自变量X服从高斯正态分布,所以自变量X的条件概率可以表示成:

    image.png

    高斯贝叶斯分类器--手工案例

    假设某金融公司是否愿意给客户放贷会优先考虑两个因素,分别是年龄和收入。现在根据已知的数据信息考察一位新客户,他的年龄为24岁,并且收入为8500元,请问该公司是否愿意给客户放贷?

    image.png
    image.png
    image.png
    image.png
    经过上面的计算可知,当客户的年龄为24岁,并且收入为8500时,被预测为不放贷的概率是,放贷的概率为,所以根据的原则,最终该金融公司决定给客户放贷。

    多项式贝叶斯分类器

    如果数据集中的自变量X均为离散型变量,在计算概率值P(X|C_i)时,会假设自变量X的条件概率满足多项式分布,故概率值P(X|C_i)的计算公式可以表示为:

    image.png
    其中,表示自变量的取值;表示因变量为类别时自变量取的样本个数;表示数据集中类别的样本个数;为平滑系数,用于防止概率值取0可能,通常将该值取为1,表示对概率值做拉普拉斯平滑;表示因变量的类别个数。

    多项式贝叶斯分类器--手工案例

    假设影响女孩是否参加相亲活动的重要因素有三个,分别是男孩的职业、受教育水平和收入状况;如果女孩参加相亲活动,则对应的Meet变量为1,否则为0。请问在给定的信息下,对于高收入的公务员,并且其学历为硕士的男生来说,女孩是否愿意参与他的相亲?

    image.png
    image.png
    经计算发现,当男生为高收入的公务员,并且受教育水平也很高时,女生愿意见面的概率约为0.0703、不愿意见面的概率约为0.0056。
    所以根据的原则,最终女生会选择参加这位男生的相亲。
    image.png

    伯努利贝叶斯分类器

    当数据集中的自变量X均为0-1二元值时,通常会优先选择伯努利贝叶斯分类器。利用该分类器计算概率值P(X|C_i)时,会假设自变量X的条件概率满足伯努利分布,故概率值P(X|C_i)的计算公式可以表示为:P(x_j|C_i)=px_j+(1−p) (1−x_j)
    其中,x_j为第j个自变量,取值为0或1;p表示类别为C_i时自变量取1的概率,该概率值可以使用经验频率代替。

    image.png
    其中,表示类别的样本个数;表示在类别为时,变量取1的样本量;为平滑系数,同样是为了避免概率为0而设置的;为因变量中的类别个数。

    伯努利贝叶斯分类器--手工案例

    假设对10条评论数据做分词处理后,得到如表12-5所示的文档词条矩阵,矩阵中含有5个词语和1个表示情感的结果,其中类别为0表示正面情绪,1表示负面情绪。如果一个用户的评论中仅包含“还行”一词,请问该用户的评论属于哪种情绪?


    image.png
    image.png

    结果所示,当用户的评论中只含有“还行”一词时,计算该评论为正面情绪的概率约为0.015,评论为负面情绪的概率约为0.00073,故根据贝叶斯后验概率最大原则将该评论预判为正面情绪。


    image.png

    03 朴素贝叶斯分类器应用实战

    人类面部皮肤识别

    # 导入第三方包
    import pandas as pd
    # 读入数据
    skin = pd.read_excel('Skin_Segment.xlsx')
    # 设置正例和负例
    skin.y = skin.y.map({2:0,1:1})
    skin.y.value_counts()
    
    0    194198
    1     50859
    Name: y, dtype: int64
    
    # 导入第三方模块
    from sklearn import model_selection
    # 样本拆分
    X_train,X_test,y_train,y_test = model_selection.train_test_split(skin.iloc[:,:3], skin.y, 
                                                                     test_size = 0.25, random_state=1234)
    
    # 导入第三方模块
    from sklearn import naive_bayes
    
    # 调用高斯朴素贝叶斯分类器的“类”
    gnb = naive_bayes.GaussianNB()
    # 模型拟合
    gnb.fit(X_train, y_train)
    # 模型在测试数据集上的预测
    gnb_pred = gnb.predict(X_test)
    # 各类别的预测数量
    pd.Series(gnb_pred).value_counts()
    
    0    50630
    1    10635
    dtype: int64
    
    # 导入第三方包
    from sklearn import metrics
    import matplotlib.pyplot as plt
    import seaborn as sns
    # 构建混淆矩阵
    cm = pd.crosstab(gnb_pred,y_test)
    # 绘制混淆矩阵图
    sns.heatmap(cm, annot = True, cmap = 'GnBu', fmt = 'd')
    # 去除x轴和y轴标签
    plt.xlabel('Real')
    plt.ylabel('Predict')
    # 显示图形
    plt.show()
    
    print('模型的准确率为:\n',metrics.accuracy_score(y_test, gnb_pred))
    print('模型的评估报告:\n',metrics.classification_report(y_test, gnb_pred))
    

    output_4_0.png


    image
    模型的准确率为:
     0.9229576430261976
    模型的评估报告:
                   precision    recall  f1-score   support
    
               0       0.93      0.97      0.95     48522
               1       0.88      0.73      0.80     12743
    
        accuracy                           0.92     61265
       macro avg       0.90      0.85      0.88     61265
    weighted avg       0.92      0.92      0.92     61265
    
    # 计算正例的预测概率,用于生成ROC曲线的数据
    y_score = gnb.predict_proba(X_test)[:,1]
    fpr,tpr,threshold = metrics.roc_curve(y_test, y_score)
    # 计算AUC的值
    roc_auc = metrics.auc(fpr,tpr)
    
    # 绘制面积图
    plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
    # 添加边际线
    plt.plot(fpr, tpr, color='black', lw = 1)
    # 添加对角线
    plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
    # 添加文本信息
    plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
    # 添加x轴与y轴标签
    plt.xlabel('1-Specificity')
    plt.ylabel('Sensitivity')
    # 显示图形
    plt.show()
    

    output_5_0.png


    image

    多项式贝叶斯函数

    MultinomialNB(alpha = 1.0, fit_prior = True, class_prior = None)
    
    alpha:用于指定平滑系数a的值,默认为1.0
    fit_prior:bool类型参数,是否以数据集中各类别的比例作为P(C_i)的先验概率,默认为True
    class_prior:用于人工指定各类别的先验概率P(C_i),如果指定该参数,则参数fit_prior不再有效
    

    毒蘑菇识别

    # 导入第三方包
    import pandas as pd
    # 读取数据
    mushrooms = pd.read_csv('mushrooms.csv')
    # 数据的前5行
    mushrooms.head()
    
    image
    # 将字符型数据作因子化处理,将其转换为整数型数据
    columns = mushrooms.columns[1:]
    for column in columns:
        mushrooms[column] = pd.factorize(mushrooms[column])[0]
    mushrooms.head()
    
    image
    from sklearn import model_selection
    # 将数据集拆分为训练集合测试集
    Predictors = mushrooms.columns[1:]
    X_train,X_test,y_train,y_test = model_selection.train_test_split(mushrooms[Predictors], mushrooms['type'], 
                                                                     test_size = 0.25, random_state = 10)
    
    from sklearn import naive_bayes
    from sklearn import metrics
    import seaborn as sns
    import matplotlib.pyplot as plt
    # 构建多项式贝叶斯分类器的“类”
    mnb = naive_bayes.MultinomialNB()
    # 基于训练数据集的拟合
    mnb.fit(X_train, y_train)
    # 基于测试数据集的预测
    mnb_pred = mnb.predict(X_test)
    # 构建混淆矩阵
    cm = pd.crosstab(mnb_pred,y_test)
    # 绘制混淆矩阵图
    sns.heatmap(cm, annot = True, cmap = 'GnBu', fmt = 'd')
    # 去除x轴和y轴标签
    plt.xlabel('Real')
    plt.ylabel('Predict')
    # 显示图形
    plt.show()
    
    # 模型的预测准确率
    print('模型的准确率为:\n',metrics.accuracy_score(y_test, mnb_pred))
    print('模型的评估报告:\n',metrics.classification_report(y_test, mnb_pred))
    

    output_10_0.png


    image
    模型的准确率为:
     0.8700147710487445
    模型的评估报告:
                   precision    recall  f1-score   support
    
          edible       0.85      0.92      0.88      1072
       poisonous       0.90      0.82      0.86       959
    
        accuracy                           0.87      2031
       macro avg       0.87      0.87      0.87      2031
    weighted avg       0.87      0.87      0.87      2031
    
    from sklearn import metrics
    # 计算正例的预测概率,用于生成ROC曲线的数据
    y_score = mnb.predict_proba(X_test)[:,1]
    fpr,tpr,threshold = metrics.roc_curve(y_test.map({'edible':0,'poisonous':1}), y_score)
    # 计算AUC的值
    roc_auc = metrics.auc(fpr,tpr)
    
    # 绘制面积图
    plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
    # 添加边际线
    plt.plot(fpr, tpr, color='black', lw = 1)
    # 添加对角线
    plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
    # 添加文本信息
    plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
    # 添加x轴与y轴标签
    plt.xlabel('1-Specificity')
    plt.ylabel('Sensitivity')
    # 显示图形
    plt.show()
    

    output_11_0.png


    image

    伯努利贝叶斯函数

    BernoulliNB (alpha = 1.0, binarize=0.0, fit_prior = True, class_prior = None)
    
    alpha:用于指定平滑系数a的值,默认为1.0
    binarize:如果该参数为浮点型数值,则将以该值为界限,当自变量的值大于该值时,自变量的值将被转换为1,否则被转换为0;如果该参数为None时,则默认训练数据集的自变量均为0-1值
    fit_prior:bool类型参数,是否以数据集中各类别的比例作为P(C_i)的先验概率,默认为True
    class_prior:用于人工指定各类别的先验概率P(C_i),如果指定该参数,则参数fit_prior不再有效
    
    import pandas as pd
    # 读入评论数据
    evaluation = pd.read_excel('Contents.xlsx')
    # 查看数据前10行
    evaluation.head(10)
    
    image
    # 运用正则表达式,将评论中的数字和英文去除
    evaluation.Content = evaluation.Content.str.replace('[0-9a-zA-Z]','')
    evaluation.head()
    
    image
    # 导入第三方包
    import jieba
    
    # 加载自定义词库
    jieba.load_userdict('all_words.txt')
    
    # 读入停止词
    with open(r'mystopwords.txt', encoding='UTF-8') as words:
        stop_words = [i.strip() for i in words.readlines()]
    
    # 构造切词的自定义函数,并在切词过程中删除停止词
    def cut_word(sentence):
        words = [i for i in jieba.lcut(sentence) if i not in stop_words]
        # 切完的词用空格隔开
        result = ' '.join(words)
        return(result)
    # 对评论内容进行批量切词
    words = evaluation.Content.apply(cut_word)
    # 前5行内容的切词效果
    words[:5]
    
    Building prefix dict from the default dictionary ...
    Loading model from cache /var/folders/tm/q03dw2_n18v2v6nlsw81yhc80000gn/T/jieba.cache
    Loading model cost 0.740 seconds.
    Prefix dict has been built successfully.
    
    
    0                  想 卖家 给我发 错货 四个 连接 铁通 块钱 便宜 廉价 退货
    1           垃圾 \n 钳子 摄细 装 \n 管子 很软 \n 评价         垃圾
    2                       我就 无语 难弄 .. 说明书 .. 过段 差评 ..
    3    不满意 写 落地 差一截 垂度 ~ 夹子 夹 没有 超市 买 质量好 换季 卖得 价钱 便宜
    4      标的 到达 快递 四天 蚊帐 底座 太小 管壁 太薄 蚊帐 也没 宣传 垂地 购物 失败
    Name: Content, dtype: object
    
    # 导入第三方包
    from sklearn.feature_extraction.text import CountVectorizer
    # 计算每个词在各评论内容中的次数,并将稀疏度为99%以上的词删除
    counts = CountVectorizer(min_df = 0.01)
    # 文档词条矩阵
    dtm_counts = counts.fit_transform(words).toarray()
    # 矩阵的列名称
    columns = counts.get_feature_names()
    # 将矩阵转换为数据框--即X变量
    X = pd.DataFrame(dtm_counts, columns=columns)
    # 情感标签变量
    y = evaluation.Type
    X.head()
    
    image
    from sklearn import model_selection
    from sklearn import naive_bayes
    from sklearn import metrics
    import matplotlib.pyplot as plt
    import seaborn as sns
    # 将数据集拆分为训练集和测试集
    X_train,X_test,y_train,y_test = model_selection.train_test_split(X,y,test_size = 0.25, random_state=1)
    # 构建伯努利贝叶斯分类器
    bnb = naive_bayes.BernoulliNB()
    # 模型在训练数据集上的拟合
    bnb.fit(X_train,y_train)
    # 模型在测试数据集上的预测
    bnb_pred = bnb.predict(X_test)
    # 构建混淆矩阵
    cm = pd.crosstab(bnb_pred,y_test)
    # 绘制混淆矩阵图
    sns.heatmap(cm, annot = True, cmap = 'GnBu', fmt = 'd')
    # 去除x轴和y轴标签
    plt.xlabel('Real')
    plt.ylabel('Predict')
    # 显示图形
    plt.show()
    
    # 模型的预测准确率
    print('模型的准确率为:\n',metrics.accuracy_score(y_test, bnb_pred))
    print('模型的评估报告:\n',metrics.classification_report(y_test, bnb_pred))
    

    output_17_0.png


    image
    模型的准确率为:
     0.8467317806160781
    模型的评估报告:
                   precision    recall  f1-score   support
    
        Negative       0.82      0.89      0.85      1341
        Positive       0.88      0.80      0.84      1321
    
        accuracy                           0.85      2662
       macro avg       0.85      0.85      0.85      2662
    weighted avg       0.85      0.85      0.85      2662
    
    # 计算正例Positive所对应的概率,用于生成ROC曲线的数据
    y_score = bnb.predict_proba(X_test)[:,1]
    fpr,tpr,threshold = metrics.roc_curve(y_test.map({'Negative':0,'Positive':1}), y_score)
    # 计算AUC的值
    roc_auc = metrics.auc(fpr,tpr)
    
    # 绘制面积图
    plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
    # 添加边际线
    plt.plot(fpr, tpr, color='black', lw = 1)
    # 添加对角线
    plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
    # 添加文本信息
    plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
    # 添加x轴与y轴标签
    plt.xlabel('1-Specificity')
    plt.ylabel('Sensitivity')
    # 显示图形
    plt.show()
    

    output_18_0.png


    image

    相关文章

      网友评论

          本文标题:2020-05-21 第十二章 朴素贝叶斯模型(python)

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