朴素贝叶斯

贝叶斯公式、概率计算、生成/判别模型

Posted by 新宇 on February 24, 2020

一、算法简介

1. 条件概率、联合概率

  • 联合概率:包含多个条件,且所有条件同时成立的概率
    • 记作:P(A,B)
  • 条件概率:就是事件A在另外一个事件B已经发生条件下的发生概率
    • 记作:P(A|B)
  • 相互独立:如果P(A, B) = P(A)P(B),则称事件A与事件B相互独立。

2. 贝叶斯公式

3. Navie Bayes的原理

  • 朴素贝叶斯法是基于贝叶斯定理特征条件独立假设的分类方法。
    • 对于给定的待分类项 x ,通过学习到的模型计算后验概率分布,
    • 即:在此项出现的条件下各个目标类别出现的概率,将后验概率最大的类作为 x 所属的类别。
    • 为什么引入条件独立性假设
      • 为了避免贝叶斯定理求解时面临的组合爆炸、样本稀疏问题

4. 拉普拉斯平滑系数

为了预防在估计条件概率 P (X ∣Y) 时出现概率为0的情况

5. API介绍

  • sklearn.naive_bayes.MultinomialNB(alpha = 1.0) 朴素贝叶斯分类
    • alpha:拉普拉斯平滑系数

二、案例

import pandas as pd
import numpy as np
import jieba
import matplotlib.pyplot as plt
from sklearn.feature_extraction.text import CountVectorizer from sklearn.naive_bayes import MultinomialNB

# 加载数据

data = pd.read_csv("./data/书籍评价.csv", encoding="gbk") 
data

# 2.1) 取出内容列,对数据进行分析 

content = data["内容"] content.head()
# 2.2) 判定评判标准 -- 1好评;0差评

data.loc[data.loc[:, '评价'] == "好评", "评论标号"] = 1 
# 把好评修改为1 

data.loc[data.loc[:, '评价'] == '差评', '评论标号'] = 0
# data.head()

good_or_bad = data['评价'].values 

# 获取数据
print(good_or_bad)
# ['好评' '好评' '好评' '好评' '差评' '差评' '差评' '差评' '差评' '好评' '差评' '差评' '差评']
# 2.3) 选择停用词
# 加载停用词
stopwords=[]
with open('./data/stopwords.txt','r',encoding='utf-8') as f:
	lines=f.readlines() 
	print(lines)
	for tmp in lines:
		line=tmp.strip() 
		print(line) 
		stopwords.append(line)
# stopwords # 查看新产生列表
# 对停用词表进行去重 

stopwords=list(set(stopwords)) #去重 列表形式 
print(stopwords)
# 2.4) 把“内容”处理,转化成标准格式 

comment_list = []
for tmp in content:
	print(tmp)
# 对文本数据进行切割
# cut_all 参数默认为 False,所有使用 cut 方法时默认为精确模式
	seg_list = jieba.cut(tmp, cut_all=False)
	print(seg_list) 
	# <generator object Tokenizer.cut at 0x0000000007CF7DB0> 
	seg_str = ','.join(seg_list) # 拼接字符串
	print(seg_str)
	comment_list.append(seg_str) # 目的是转化成列表形式
# print(comment_list) # 查看comment_list列表。
# 2.5) 统计词的个数
# 进行统计词个数
# 实例化对象
# CountVectorizer 类会将文本中的词语转换为词频矩阵 

con = CountVectorizer(stop_words=stopwords)
# 进行词数统计

X = con.fit_transform(comment_list) # 它通过 fit_transform 函数计算各个词语出现的次数 
name = con.get_feature_names() # 通过 get_feature_names()可获取词袋中所有文本的关键字 
print(X.toarray()) # 通过 toarray()可看到词频矩阵的结果
print(name)
# 2.6)准备训练集和测试集
# 准备训练集 这里将文本前10行当做训练集 后3行当做测试集 

x_train = X.toarray()[:10, :]
y_train = good_or_bad[:10]
# 准备测试集

x_text = X.toarray()[10:, :]
y_text = good_or_bad[10:]

# 3)模型训练

# 构建贝叶斯算法分类器

mb = MultinomialNB(alpha=1) # alpha 为可选项,默认 1.0,添加拉普拉修/Lidstone 平滑参数 # 训练数据
mb.fit(x_train, y_train)
# 预测数据

y_predict = mb.predict(x_text)
#预测值与真实值展示

print('预测值:',y_predict)
print('真实值:',y_text)

三、知识拓展

1. 朴素贝叶斯与LR(逻辑回归)的区别?

  • 区别一:
    • 朴素贝叶斯是生成模型,
      • 根据已有样本进行贝叶斯估计学习出先验概率 P (Y ) 和条件概率 P (X ∣Y ) ,
      • 进而求出联合分布概率P(XY) ,
      • 最后利用贝叶斯定理求解 P (Y ∣X ) ,
    • 而LR是判别模型,
      • 根据极大化对数似然函数直接求出条件概率 P (Y ∣X ) ;
  • 区别二:
    • 朴素贝叶斯是基于很强的条件独立假设(在已知分类 Y 的条件下,各个特征变量取值是相互独立的),
    • 而LR则对此没有要求;
  • 区别三:
    • 朴素贝叶斯适用于数据集少的情景,
    • 而LR适用于大规模数据集。

2. 生成模型和判别模型

  • 二者目的都是在使后验概率最大化,主要区别是:
    • 判别式是直接对后验概率建模,
    • 生成模型通过贝叶斯定理这一“桥梁”使问题转化为求联合概率
  • 判别式模型举例:
    • 要确定一个羊是山羊还是绵羊,用判别模型的方法是从历史数据中学习到模型,然后通过提取这只羊的特征来预测出这只羊是山羊的概率,是绵羊的概率。
  • 生成式模型举例:
    • 利用生成模型是根据山羊的特征首先学习出一个山羊的模型,然后根据绵羊的特征学习出一个绵羊的模型,然后从这只羊中提取特征,放到山羊模型中看概率是多少,在放到绵羊模型中看概率是多少,哪个大就是哪个。