1 概率
样本数 | 职业 ( x 1 ) (x_1) (x1) | 体型 ( x 2 ) (x_2) (x2) | 是否喜欢 ( Y ) (Y) (Y) |
---|---|---|---|
1 | 程序员 | 超重 | 不喜欢 |
2 | 产品 | 匀称 | 喜欢 |
3 | 程序员 | 匀称 | 喜欢 |
4 | 程序员 | 超重 | 喜欢 |
5 | 美工 | 匀称 | 不喜欢 |
6 | 美工 | 超重 | 不喜欢 |
7 | 产品 | 匀称 | 喜欢 |
1.1 条件概率
表示事件A在另外一个事件B已经发生条件下的发生概率,即:
P
(
A
∣
B
)
=
P
(
A
∧
B
)
P
(
B
)
=
A
∩
B
|
B
|
P(A|B)=\frac{P(A \wedge B)}{P(B)}=\frac{A\cap B}{|B|}
P(A∣B)=P(B)P(A∧B)=|B|A∩B
- 在女神喜欢的条件下,职业是程序员的概率是:
- 女神喜欢条件下,有2,3,4,7共4个样本
- 4个样本中,有程序员3,4共2个样本
- 则P(程序员|喜欢) = 2/4=0.5
1.2 联合概率
表示多个条件同时成立的概率,即:
P
(
A
B
)
=
P
(
A
)
P
(
B
∣
A
)
=
P
(
A
∧
B
)
P(AB) = P(A) P(B|A)=P(A\wedge B)
P(AB)=P(A)P(B∣A)=P(A∧B)
- 职业是程序员并且体型匀称的概率是:
- 数据集中一共7个样本
- 职业是程序员的有1,3,4共3个样本,概率为:3/7
- 在职业是程序员,体型匀称的有3共1个样本,概率是:1/3
- 即是程序员又体型匀称的概率是: 3 / 7 × 1 / 3 = 1 / 7 3/7\times1/3=1/7 3/7×1/3=1/7
1.3 联合概率+条件概率
P ( A B ∣ C ) = P ( A B ∧ C ) P ( C ) = A ∩ B ∩ C ∣ C ∣ \begin{aligned} P(AB|C)&=\frac{P(AB\wedge C)}{P(C)}\\ &=\frac{A\cap B\cap C}{|C|} \end{aligned} P(AB∣C)=P(C)P(AB∧C)=∣C∣A∩B∩C
- 在女神喜欢的条件下,职业是程序员、体重超重的概率?
- 在女神喜欢的条件下,有 2、3、4、7 共 4 个样本
- 在这 4 个样本中,职业是程序员有 3、4 共 2 个样本,则其概率为:2/4=0.5
- 在在 2 个样本中,体型超重的有 4 共 1 个样本,则其概率为:1/2 = 0.5
- 则 P(程序员, 超重|喜欢) = 0.5 * 0.5 = 0.25
1.4 条件独立
P(AB) = P(A)*P(B)
1.5 总结
- 条件概率:在去掉部分样本的情况下,计算某些样本出现的概率,表示为: P ( A ∣ B ) P(A|B) P(A∣B)
- 联合概率:多个事件同时发生的概率,表示 P ( A B ) = P ( A ) P ( B ∣ A ) P(AB) = P(A) P(B|A) P(AB)=P(A)P(B∣A)
2 贝叶斯
根据条件概率公式可知:
P
(
A
∣
B
)
=
P
(
A
∧
B
)
P
(
B
)
P(A|B)=\frac{P(A \wedge B)}{P(B)}
P(A∣B)=P(B)P(A∧B)
P
(
B
∣
A
)
=
P
(
B
∧
A
)
P
(
A
)
P(B|A)=\frac{P(B \wedge A)}{P(A)}
P(B∣A)=P(A)P(B∧A)
可得:
P
(
A
∧
B
)
=
P
(
A
∣
B
)
P
(
B
)
P(A \wedge B)=P(A|B)P(B)
P(A∧B)=P(A∣B)P(B)
P
(
B
∧
A
)
=
P
(
B
∣
A
)
P
(
A
)
P(B \wedge A)=P(B|A)P(A)
P(B∧A)=P(B∣A)P(A)
因为
P
(
A
∧
B
)
P(A \wedge B)
P(A∧B)和
P
(
B
∧
A
)
P(B \wedge A)
P(B∧A)相等,因此:
P
(
A
∣
B
)
P
(
B
)
=
P
(
B
∣
A
)
P
(
A
)
P(A|B)P(B)=P(B|A)P(A)
P(A∣B)P(B)=P(B∣A)P(A)
最后可得:
P
(
A
∣
B
)
=
P
(
B
∣
A
)
P
(
A
)
P
(
B
)
P(A|B)=\frac{P(B|A)P(A)}{P(B)}
P(A∣B)=P(B)P(B∣A)P(A)
- P(A|B):后验概率
- P(B|A):样本B相对于类标记A的类条件概率
- P(A):类先验概率
- P(B):归一化的证据因子
以上公式就是贝叶斯公式
类先验概率P(A)表达了样本空间中各类样本所占的比例。比如上述例子中体型属性中各类别的概率:P(超重)=3/7,P(匀称)=4/7。
对于类条件概率P(B|A),由于它设计关于B所有属性的联合概率,直接根据样本出现的频率来估计将会出现困难。仍旧拿上述例子做说明:目前该例子有2个属性,假如该样本有n个属性,每个属性都是二分类的,则样本空间将有
2
n
2^n
2n个取值。现实应用中,这个值会远大于训练样本数m,所以,很多样本的取值在训练样本中没有出现。上述例子中,比如:体型超重且职业是产品经理就没有这样的样本,这就是样本空间远大于训练样本所产生的后果。因此,朴素贝叶斯就弥补了贝叶斯公式的这种不足,引用了特征条件独立假设:对已知类别,假设所有属性相互独立,通俗讲就是每一个属性独立地对分类结果产生影响,互不干预。
3 朴素贝叶斯
上述我们讲到朴素贝叶斯采用了特征条件独立假设,这也是朴素贝叶斯为什么朴素的原因,因此,朴素贝叶斯公式为:
P
(
A
∣
B
)
=
P
(
B
∣
A
)
P
(
A
)
P
(
B
)
=
P
(
A
)
P
(
B
)
∏
i
=
1
n
P
(
B
i
∣
A
)
P(A|B)=\frac{P(B|A)P(A)}{P(B)}=\frac{P(A)}{P(B)}\prod_{i=1}^nP(B_i|A)
P(A∣B)=P(B)P(B∣A)P(A)=P(B)P(A)i=1∏nP(Bi∣A)
- d是属性的数量
- B i B_i Bi为 B B B在第 i i i个属性上的取值
使用上述例子,举例说明:
计算体型均匀且职业是程序员被女神喜欢和不喜欢的概率分别是多少?
使用朴素贝叶斯公式可表达为:
P
(
程
序
员
,
匀
称
|
喜
欢
)
=
P
(
程
序
员
,
匀
称
)
P
(
喜
欢
)
⋅
P
(
喜
欢
|
程
序
员
)
⋅
P
(
喜
欢
|
匀
称
)
=
1
7
4
7
×
2
3
×
3
4
=
1
8
\begin{aligned} P(程序员,匀称|喜欢)&=\frac{P(程序员,匀称)}{P(喜欢)}\cdot P(喜欢|程序员)\cdot P(喜欢|匀称)\\ &=\frac{\frac{1}{7}}{\frac{4}{7}}\times \frac{2}{3}\times\frac{3}{4}\\ &=\frac{1}{8} \end{aligned}
P(程序员,匀称|喜欢)=P(喜欢)P(程序员,匀称)⋅P(喜欢|程序员)⋅P(喜欢|匀称)=7471×32×43=81
P
(
程
序
员
,
匀
称
|
不
喜
欢
)
=
P
(
程
序
员
,
匀
称
)
P
(
不
喜
欢
)
⋅
P
(
不
喜
欢
|
程
序
员
)
⋅
P
(
不
喜
欢
|
匀
称
)
=
1
7
3
7
×
1
3
×
1
4
=
1
36
\begin{aligned} P(程序员,匀称|不喜欢)&=\frac{P(程序员,匀称)}{P(不喜欢)}\cdot P(不喜欢|程序员)\cdot P(不喜欢|匀称)\\ &=\frac{\frac{1}{7}}{\frac{3}{7}}\times \frac{1}{3}\times\frac{1}{4}\\ &=\frac{1}{36} \end{aligned}
P(程序员,匀称|不喜欢)=P(不喜欢)P(程序员,匀称)⋅P(不喜欢|程序员)⋅P(不喜欢|匀称)=7371×31×41=361
通过以上计算,可知:女神对体型匀称而且职业是程序员喜欢的概率更大一点。以上就是朴素贝叶斯的实际应用。
4 拉普拉斯平滑系数
如果我们需要计算
P
(
美
工
,
超
重
|
喜
欢
)
P(美工,超重|喜欢)
P(美工,超重|喜欢)的概率:
P
(
美
工
,
超
重
|
喜
欢
)
=
P
(
美
工
,
超
重
)
P
(
喜
欢
)
⋅
P
(
喜
欢
|
美
工
)
⋅
P
(
喜
欢
|
超
重
)
\begin{aligned} P(美工,超重|喜欢)&=\frac{P(美工,超重)}{P(喜欢)}\cdot P(喜欢|美工)\cdot P(喜欢|超重)\\ \end{aligned}
P(美工,超重|喜欢)=P(喜欢)P(美工,超重)⋅P(喜欢|美工)⋅P(喜欢|超重)
P
(
喜
欢
)
=
4
7
P(喜欢)=\frac{4}{7}
P(喜欢)=74
P ( 美 工 , 超 重 ) = 1 7 P(美工,超重)=\frac{1}{7} P(美工,超重)=71
P ( 喜 欢 | 美 工 ) = 0 2 P(喜欢|美工)=\frac{0}{2} P(喜欢|美工)=20
P ( 喜 欢 | 超 重 ) = 1 4 P(喜欢|超重)=\frac{1}{4} P(喜欢|超重)=41
从上边可知,
P
(
喜
欢
|
美
工
)
=
0
P(喜欢|美工)=0
P(喜欢|美工)=0,导致整个式子计算下来为0,显然是不合理的,因此,通过使用拉普拉斯平滑系数解决上述问题:
P
(
F
1
|
C
)
=
N
i
+
α
N
+
α
m
P(F1|C) = \frac{N_i+\alpha}{N+\alpha m}
P(F1|C)=N+αmNi+α
- α \alpha α为指定的系数,一般设置为1
- N i N_i Ni是A中符合条件B的样本的出现次数,N是在条件B下所有样本的总数
- m表示所有独立样本的总数
因此通过拉普拉斯平滑系数转化,可得:
P ( 喜 欢 | 美 工 ) = 0 + 1 2 + 1 × 5 = 1 7 P(喜欢|美工)=\frac{0+1}{2+1\times 5}=\frac{1}{7} P(喜欢|美工)=2+1×50+1=71
P ( 喜 欢 | 超 重 ) = 1 + 1 4 + 1 × 5 = 2 9 P(喜欢|超重)=\frac{1+1}{4+1\times 5}=\frac{2}{9} P(喜欢|超重)=4+1×51+1=92
所以:
P ( 美 工 , 超 重 | 喜 欢 ) = P ( 美 工 , 超 重 ) P ( 喜 欢 ) ⋅ P ( 喜 欢 | 美 工 ) ⋅ P ( 喜 欢 | 超 重 ) = 1 7 × 1 7 × 2 9 ÷ 4 7 = 1 126 \begin{aligned} P(美工,超重|喜欢)&=\frac{P(美工,超重)}{P(喜欢)}\cdot P(喜欢|美工)\cdot P(喜欢|超重)\\ &=\frac{1}{7}\times \frac{1}{7} \times \frac{2}{9}\div\frac{4}{7}=\frac{1}{126} \end{aligned} P(美工,超重|喜欢)=P(喜欢)P(美工,超重)⋅P(喜欢|美工)⋅P(喜欢|超重)=71×71×92÷74=1261
5 案例实现
评论情感案例分析
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
# 获取评价内容
content = data['内容']
content
# 文本分割
text_list = []
for tmp in content:
tmp_data = jieba.cut(tmp,cut_all=False)
tmp_str = ','.join(tmp_data)
text_list.append(tmp_str)
text_list
# 选择停用词
stop_list = []
with open('./data/stopwords.txt', 'r') as f:
lines = f.readlines()
for tmp in lines:
line = tmp.strip()
stop_list.append(line)
stop_words = list(set(stop_list))
stop_words[:10]
这里展示前10个停用词
['', '这儿', '欢迎', '毋宁', '马上', '从未', '你的', '..', '=', '}>']
# 词频统计
CV = CountVectorizer(stop_words=stop_words)
X = CV.fit_transform(text_list)
X.toarray()[:5]
# 训练集和测试集划分
x_train = X.toarray()[:10,:]
y_train = data['评价编号'][:10]
x_test = X.toarray()[10:, :]
y_test = data['评价编号'][10:]
# 模型训练
estimator = MultinomialNB(alpha=1)
estimator.fit(x_train, y_train)
y_pre = estimator.predict(x_test)
print(y_pre)
[0. 0. 0.]
# 模型评估
score = estimator.score(x_test,y_test)
print(score)
1.0
全部代码:
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')
# 获取评价内容
content = data['内容']
# 文本分割
text_list = []
for tmp in content:
tmp_data = jieba.cut(tmp,cut_all=False)
tmp_str = ','.join(tmp_data)
text_list.append(tmp_str)
text_list
# 选择停用词
stop_list = []
with open('./data/stopwords.txt', 'r') as f:
lines = f.readlines()
for tmp in lines:
line = tmp.strip()
stop_list.append(line)
# 停用词去重(强转成集合再转成列表)
stop_words = list(set(stop_list))
# 词频统计
CV = CountVectorizer(stop_words=stop_words)
X = CV.fit_transform(text_list)
# 训练集和测试集划分
x_train = X.toarray()[:10,:]
y_train = data['评价编号'][:10]
x_test = X.toarray()[10:, :]
y_test = data['评价编号'][10:]
# 模型训练
estimator = MultinomialNB(alpha=1)
estimator.fit(x_train, y_train)
y_pre = estimator.predict(x_test)
# 模型评估
score = estimator.score(x_test,y_test)
print(score)