编程知识 cdmana.com

Naive Bayes Algorithm (1)

1.1 A Brief Introduction to Naive Bayes

朴素贝叶斯算法(Naive Bayes, NB) 是应用最为广泛的分类算法之一.Can be used for binary classification,也可以用于多分类.当年的垃圾邮件分类都是基于朴素贝叶斯分类器识别的.

朴素贝叶斯假设(conditional independence assumption):即,在给定y的条件下,属性之间相互独立.

hypothetical purpose:简化运算.

虽然这个简化方式在一定程度上降低了贝叶斯分类算法的分类效果,但是在实际的应用场景中,极大地简化了贝叶斯方法的复杂性.

1.2 概率基础复习


1.概率定义

  • 概率定义为一件事情发生的可能性
    • 扔出一个硬币,结果头像朝上
  • P(X) : 取值在[0, 1]

2.案例:判断女神对你的喜欢情况

在讲这两个概率之前我们通过一个例子,来计算一些结果:

è¡ç—概率

问题如下:

  1. 女神喜欢的概率?
  2. 职业是程序员并且体型匀称的概率?
  3. 在女神喜欢的条件下,职业是程序员的概率?
  4. 在女神喜欢的条件下,职业是程序员、体重超重的概率?

计算结果为:

P(喜欢) = 4/7
P(程序员, 匀称) = 1/7(联合概率)
P(程序员|喜欢) = 2/4 = 1/2(条件概率)
P(程序员, 超重|喜欢) = 1/4

3.联合概率、条件概率与相互独立

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

4.贝叶斯公式

4.1 公式介绍

img

换个表达形式就会明朗很多,如下:

img

我们最终求的p(类别|特征)即可!就相当于完成了我们的任务.

根据朴素贝叶斯假设:p(特征/类别) = p(特征1/类别)* p(特征2/类别)… *p(特征n/类别)

4.2 例题分析

Let me give example questions first.

The given data is as follows:

img

现在给我们的问题是,如果一对男女朋友,男生想女生求婚,男生的四个特点分别是不帅,性格不好,身高矮,不上进,请你判断一下女生是嫁还is not married?

这是一个典型的分类问题,转为数学问题就是比较p(嫁|(不帅、性格不好、身高矮、不上进))与p(不嫁|(不帅、性格不好、身高矮、不上进))的概率,谁的概率大,我就能给出嫁或者不嫁的答案!

这里我们联系到朴素贝叶斯公式:

img

我们需要求p(嫁|(不帅、性格不好、身高矮、不上进),这是我们不知道的,但是通过朴素贝叶斯公式可以转化为好求的三个量,p(不帅、性格不好、身高矮、不上进|嫁)、p(不帅、性格不好、身高矮、不上进)、p(嫁)(As for why you can ask,后面会讲,那么就太好了,Convert the quantity to be requested into other values ​​that can be obtained,This is equivalent to solving our problem!)

嫁的概率为:

p ( 嫁 / 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) = p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 / 嫁 ) ∗ p ( 嫁 ) p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) p(嫁/不帅、性格不好、身高矮、不上进)=\frac {p(不帅、性格不好、身高矮、不上进/嫁)*p(嫁)}{p(不帅、性格不好、身高矮、不上进)} p(/)=p()p(/)p()

= p ( 不 帅 / 嫁 ) p ( 性 格 不 好 / 嫁 ) p ( 身 高 矮 / 嫁 ) p ( 不 上 进 / 嫁 ) ∗ p ( 嫁 ) p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) \frac {p(不帅/嫁)p(性格不好/嫁)p(身高矮/嫁)p(不上进/嫁)*p(嫁)}{p(不帅、性格不好、身高矮、不上进)} p()p(/)p(/)p(/)p(/)p()

不嫁的概率为:

p ( 不 嫁 / 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) = p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 / 不 嫁 ) ∗ p ( 不 嫁 ) p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) p(不嫁/不帅、性格不好、身高矮、不上进)=\frac {p(不帅、性格不好、身高矮、不上进/不嫁)*p(不嫁)}{p(不帅、性格不好、身高矮、不上进)} p(/)=p()p(/)p()

= p ( 不 帅 / 不 嫁 ) p ( 性 格 不 好 / 不 嫁 ) p ( 身 高 矮 / 不 嫁 ) p ( 不 上 进 / 不 嫁 ) ∗ p ( 不 嫁 ) p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) \frac {p(不帅/不嫁)p(性格不好/不嫁)p(身高矮/不嫁)p(不上进/不嫁)*p(不嫁)}{p(不帅、性格不好、身高矮、不上进)} p()p(/)p(/)p(/)p(/)p()

We find that the denominators are the same:p(嫁)>p(不嫁),Just need the numerator to be greater than

Explanation of the word Naive for the Naive Bayes Algorithm

So how are these three quantities obtained??

It is based on known training data statistics,The solution process of this example is given in detail below.

Recall that the formula we require is as follows:

img

So I just obtainedp(不帅、性格不好、身高矮、不上进|嫁)、p(嫁)即可,好的,Let me calculate these probabilities separately,last match,就得到最终结果.

p(不帅、性格不好、身高矮、不上进|嫁) = p(不帅|嫁)*p(性格不好|嫁)*p(身高矮|嫁)*p(不上进|嫁),Then I will count the following probabilities separately.,This gives the probability on the left!

We organize the above formula as follows:

p ( 嫁 / 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) = p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 / 嫁 ) ∗ p ( 嫁 ) p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) p(嫁/不帅、性格不好、身高矮、不上进)=\frac {p(不帅、性格不好、身高矮、不上进/嫁)*p(嫁)}{p(不帅、性格不好、身高矮、不上进)} p(/)=p()p(/)p()

= p ( 不 帅 / 嫁 ) p ( 性 格 不 好 / 嫁 ) p ( 身 高 矮 / 嫁 ) p ( 不 上 进 / 嫁 ) ∗ p ( 嫁 ) p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) \frac {p(不帅/嫁)p(性格不好/嫁)p(身高矮/嫁)p(不上进/嫁)*p(嫁)}{p(不帅、性格不好、身高矮、不上进)} p()p(/)p(/)p(/)p(/)p()

Below I will perform statistical calculations one by one(在数据量很大的时候,根据中心极限定理,frequency is equal to probability,这里只是一个例子,So I just do the statistics).

p(嫁)=?

First, we organize the training data,The number of samples married is as follows:

img

则 p(嫁) = 6/12(总样本数) = 1/2

p(不帅|嫁)=?The number of statistically satisfied samples is as follows:

img

则p(不帅|嫁) = 3/6 = 1/2

p(性格不好|嫁)= ?The number of statistically satisfied samples is as follows:

img

**则p(性格不好|嫁)= 1/6
**

p(矮|嫁) = ?The number of statistically satisfied samples is as follows:

img

则p(矮|嫁) = 1/6

p(不上进|嫁) = ?The number of statistically satisfied samples is as follows:

img

则p(不上进|嫁) = 1/6

到这里,要求p(不帅、性格不好、身高矮、不上进|嫁)All the required items are found,I'll just bring it in,

p ( 嫁 / 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) = p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 / 嫁 ) ∗ p ( 嫁 ) p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) p(嫁/不帅、性格不好、身高矮、不上进)=\frac {p(不帅、性格不好、身高矮、不上进/嫁)*p(嫁)}{p(不帅、性格不好、身高矮、不上进)} p(/)=p()p(/)p()

= p ( 不 帅 / 嫁 ) p ( 性 格 不 好 / 嫁 ) p ( 身 高 矮 / 嫁 ) p ( 不 上 进 / 嫁 ) ∗ p ( 嫁 ) p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) \frac {p(不帅/嫁)p(性格不好/嫁)p(身高矮/嫁)p(不上进/嫁)*p(嫁)}{p(不帅、性格不好、身高矮、不上进)} p()p(/)p(/)p(/)p(/)p()

∝p(不帅、性格不好、身高矮、不上进|嫁)*p(嫁)

=p(不帅|嫁)* p(性格不好|嫁)*p(身高矮|嫁)*p(不上进|嫁)*p(嫁)
= 1/2*1/6*1/6*1/6*1/2 = 1/864

下面我们根据同样的方法来求p(不嫁|不帅,性格不好,身高矮,不上进),exactly the same way,为了方便理解,Here I go again to help understanding.The first formula is as follows:

p ( 不 嫁 / 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) = p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 / 不 嫁 ) ∗ p ( 不 嫁 ) p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) p(不嫁/不帅、性格不好、身高矮、不上进)=\frac {p(不帅、性格不好、身高矮、不上进/不嫁)*p(不嫁)}{p(不帅、性格不好、身高矮、不上进)} p(/)=p()p(/)p()

= p ( 不 帅 / 不 嫁 ) p ( 性 格 不 好 / 不 嫁 ) p ( 身 高 矮 / 不 嫁 ) p ( 不 上 进 / 不 嫁 ) ∗ p ( 不 嫁 ) p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) \frac {p(不帅/不嫁)p(性格不好/不嫁)p(身高矮/不嫁)p(不上进/不嫁)*p(不嫁)}{p(不帅、性格不好、身高矮、不上进)} p()p(/)p(/)p(/)p(/)p()

Next, I will also perform statistical calculations one by one.

p(不嫁)=?Calculated according to statistics as follows(Red is the condition):

img

则p(不嫁)=6/12 = 1/2

p(不帅|不嫁) = ?The samples that meet the statistical conditions are as follows(Red is the condition):

img

则p(不帅|不嫁) = 1/6

p(性格不好|不嫁) = ?According to statistics, the calculation is as follows(Red is the condition):

img

则p(性格不好|不嫁) =3/6 = 1/2

p(矮|不嫁) = ?According to statistics, the calculation is as follows(Red is the condition):

img

则p(矮|不嫁) = 6/6 = 1

p(不上进|不嫁) = ?According to statistics, the calculation is as follows(Red is the condition):

img

则p(不上进|不嫁) = 3/6 = 1/2

那么根据公式:

p ( 不 嫁 / 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) = p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 / 不 嫁 ) ∗ p ( 不 嫁 ) p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) p(不嫁/不帅、性格不好、身高矮、不上进)=\frac {p(不帅、性格不好、身高矮、不上进/不嫁)*p(不嫁)}{p(不帅、性格不好、身高矮、不上进)} p(/)=p()p(/)p()

= p ( 不 帅 / 不 嫁 ) p ( 性 格 不 好 / 不 嫁 ) p ( 身 高 矮 / 不 嫁 ) p ( 不 上 进 / 不 嫁 ) ∗ p ( 不 嫁 ) p ( 不 帅 、 性 格 不 好 、 身 高 矮 、 不 上 进 ) \frac {p(不帅/不嫁)p(性格不好/不嫁)p(身高矮/不嫁)p(不上进/不嫁)*p(不嫁)}{p(不帅、性格不好、身高矮、不上进)} p()p(/)p(/)p(/)p(/)p()

∝p(不帅、性格不好、身高矮、不上进|不嫁)*p(不嫁)

=p(不帅|不嫁)* p(性格不好|不嫁)*p(身高矮|不嫁)*p(不上进|不嫁)*p(不嫁)
= 1/6*1/2*1*1/2*1/2 = 1/48

很显然1/48> 1/864

于是有p (不嫁|不帅、性格不好、身高矮、不上进)>p (嫁|不帅、性格不好、身高矮、不上进)

So we can give this girl the answer based on the Naive Bayes algorithm,is not married!!!!

4.3 文章分类计算

需求:通过前四个训练样本(文章),判断第五篇文章,是否属于China类

分类è¡ç—例子

  • 计算结果
P(C|Chinese, Chinese, Chinese, Tokyo, Japan) -->
P(Chinese, Chinese, Chinese, Tokyo, Japan|C) * P(C) / P(Chinese, Chinese, Chinese, Tokyo, Japan) 
∝
P(Chinese|C)^3 * P(Tokyo|C) * P(Japan|C) * P(C) 

# The denominator values ​​are all the same without calculation:

# 首先计算是China类的概率: 
P(Chinese|C=china) = 5/8
P(Tokyo|C) = 0/8
P(Japan|C) = 0/8

# 接着计算不是China类的概率:
P(Chinese|C) = 1/3
P(Tokyo|C) = 1/3
P(Japan|C) = 1/3

img

在这个例子中,m为6,The training focus in total6个不同的词.把这6个词作为词表,If there are words in the test set that are not in the vocabulary,不计算.(If there are words appear in the test set,but not in the vocabulary,we ignore the word)

# 这个文章是需要计算是不是China类:

首先计算是China类的概率:  
    P(Chinese|C) = 5/8 --> 6/14
    P(Tokyo|C) = 0/8 --> 1/14
    P(Japan|C) = 0/8 --> 1/14

接着计算不是China类的概率: 
    P(Chinese|C) = 1/3 -->(经过拉普拉斯平滑系数处理) 2/9
    P(Tokyo|C) = 1/3 --> 2/9
    P(Japan|C) = 1/3 --> 2/9

1.2 案例:商品评论情感分析

学习目标

  • Applied Naive BayesAPIRealize product review sentiment analysis

1.api介绍

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

2.商品评论情感分析

image-20200106233750808

2.1 步骤分析

  • 1)获取数据
  • 2)数据基本处理
    • 2.1) 取出内容列,对数据进行分析
    • 2.2) 判定评判标准
    • 2.3) 选择停用词
    • 2.4) 把内容处理,转化成标准格式
    • 2.5) 统计词的个数
    • 2.6)准备训练集和测试集
  • 3)模型训练
  • 4)模型评估

2.2 代码实现

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
  • 1)获取数据
# 加载数据
data = pd.read_csv("./data/书籍评价.csv", encoding="gbk",index_col=0)
data
  • 2)数据基本处理
# 2.1) 取出内容列,对数据进行分析
content = data["内容"]
content.head()

# 2.2) 判定评判标准 -- 1好评;0差评
data.loc[data.loc[:, '评价'] == "好评", "评论标号"] = 1  # 把好评修改为1
data.loc[data.loc[:, '评价'] == '差评', '评论标号'] = 0

# data.head()


# 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.lcut(tmp)
    print(seg_list)  
    seg_str = ' '.join(i for i in seg_list if i !=' ')  # 拼接字符串
    print(seg_str)
    comment_list.append(seg_str)  # 目的是转化成列表形式
# print(comment_list) # 查看comment_list列表.

# 2.5) 统计词的个数
# 进行统计词个数
# 实例化对象
# CountVectorizer 类会将文本中的词语转换为词频矩阵
con = CountVectorizer(stop_words=stopwords)#Only count the frequency of two words or more
# 进行词数统计
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行当做测试集
labels = data['评论标号'].values
x_train = X.toarray()[:10, :]
y_train = labels[:10]
# 准备测试集
x_text = X.toarray()[10:, :]
y_text = labels[10:]
  • 3)模型训练
# 构建贝叶斯算法分类器
mb = MultinomialNB(alpha = 1.0)  # alpha 为可选项,默认 1.0,添加拉普拉修/Lidstone 平滑参数
# 训练数据
mb.fit(x_train, y_train)
# 预测数据
y_predict = mb.predict(x_text)
#预测值与真实值展示
print('预测值:',y_predict)
print('真实值:',y_text)
  • 4)模型评估
mb.score(x_text, y_text)

测试集
labels = data[‘评论标号’].values
x_train = X.toarray()[:10, :]
y_train = labels[:10]

准备测试集

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


- 3)模型训练

```python
# 构建贝叶斯算法分类器
mb = MultinomialNB(alpha = 1.0)  # alpha 为可选项,默认 1.0,添加拉普拉修/Lidstone 平滑参数
# 训练数据
mb.fit(x_train, y_train)
# 预测数据
y_predict = mb.predict(x_text)
#预测值与真实值展示
print('预测值:',y_predict)
print('真实值:',y_text)
  • 4)模型评估
mb.score(x_text, y_text)

版权声明
本文为[Her han rain Chen]所创,转载请带上原文链接,感谢
https://cdmana.com/2022/328/202211242127010172.html

Scroll to Top