I know nothing but my ignorance.
贝叶斯公式:
P
(
c
∣
x
)
=
P
(
c
)
P
(
x
∣
c
)
P
(
x
)
P(c|x)=\frac{P(c)P(x|c)}{P(x)}
P(c∣x)=P(x)P(c)P(x∣c)
朴素贝叶斯分类器(naive Bayes classifier) 采用了 “属性条件独立性假设”。基于这种假设,贝叶斯公式可以写成:
P ( c ∣ x ) = P ( c ) P ( x ) ∏ i = 1 d P ( x i ∣ c ) d 为 属 性 数 目 , x i 为 x 在 第 i 个 属 性 上 的 取 值 。 P(c|x) = \frac{P(c)}{P(x)}\prod_{i=1}^d P(x_i|c)\\ d 为属性数目,x_i 为 x 在第 i 个属性上的取值。 P(c∣x)=P(x)P(c)i=1∏dP(xi∣c)d为属性数目,xi为x在第i个属性上的取值。
贝叶斯判定准则为:
h
n
b
(
x
)
=
a
r
g
m
a
x
P
(
c
)
∏
i
=
1
d
P
(
x
i
∣
c
)
h_{nb}(x) = argmax P(c)\prod_{i=1}^d P(x_i|c)\\
hnb(x)=argmaxP(c)i=1∏dP(xi∣c)
D c D_c Dc 表示训练集 D 中第 c 类样本组成的集合。
先验概率: P ( c ) = ∣ D c ∣ ∣ D ∣ P(c)=\frac{|D_c|}{|D|} P(c)=∣D∣∣Dc∣
条件概率:
对离散属性: P ( x i ∣ c ) = ∣ D c , x i ∣ ∣ D c ∣ P(x_i|c)=\frac{|D_{c,x_i}|}{|D_c|} P(xi∣c)=∣Dc∣∣Dc,xi∣
对连续属性:假定 p ( x i ∣ c ) ∼ N ( μ c , x i , σ c , x i 2 ) p(x_i|c)\sim N(\mu_{c,x_i},\sigma_{c,x_i}^2) p(xi∣c)∼N(μc,xi,σc,xi2),则: P ( x i ∣ c ) = 1 2 π σ c , x i e x p ( − ( x i − σ c , x i ) 2 2 σ c , x i 2 ) P(x_i|c)=\frac{1}{\sqrt{2\pi}\sigma_{c,x_i}}exp(-\frac{(x_i-\sigma_{c,x_i})^2}{2\sigma_{c,x_i}^2}) P(xi∣c)=2πσc,xi1exp(−2σc,xi2(xi−σc,xi)2)
为了防止出现 由于
∣
D
c
∣
|D_c|
∣Dc∣ 或
∣
D
c
,
x
i
∣
|D_{c,x_i}|
∣Dc,xi∣ 为 0 造成属性值被抹去的情况,在估计概率是需要进行平滑。
P
(
c
)
=
∣
D
c
∣
+
1
∣
D
∣
+
N
N
表
示
训
练
集
D
可
能
的
分
类
数
P(c)=\frac{|D_c|+1}{|D|+N}\\ N 表示 训练集 D可能的分类数
P(c)=∣D∣+N∣Dc∣+1N表示训练集D可能的分类数
P ( x i ∣ c ) = ∣ D c , x i ∣ + 1 ∣ D c ∣ + N i N i 表 示 第 i 个 属 性 可 能 的 取 值 数 P(x_i|c)=\frac{|D_{c,x_i}|+1}{|D_c|+N_i}\\ N_i 表示 第 i 个属性可能的取值数 P(xi∣c)=∣Dc∣+Ni∣Dc,xi∣+1Ni表示第i个属性可能的取值数
# 导包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
# 对中文的支持
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 西瓜数据集 3.0
df = pd.read_csv("watermelon.data")
df
编号 | 色泽 | 根蒂 | 敲声 | 纹理 | 脐部 | 触感 | 密度 | 含糖率 | 好瓜 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 青绿 | 蜷缩 | 浊响 | 清晰 | 凹陷 | 硬滑 | 0.697 | 0.460 | 是 |
1 | 2 | 乌黑 | 蜷缩 | 沉闷 | 清晰 | 凹陷 | 硬滑 | 0.774 | 0.376 | 是 |
2 | 3 | 乌黑 | 蜷缩 | 浊响 | 清晰 | 凹陷 | 硬滑 | 0.634 | 0.264 | 是 |
3 | 4 | 青绿 | 蜷缩 | 沉闷 | 清晰 | 凹陷 | 硬滑 | 0.608 | 0.318 | 是 |
4 | 5 | 浅白 | 蜷缩 | 浊响 | 清晰 | 凹陷 | 硬滑 | 0.556 | 0.215 | 是 |
5 | 6 | 青绿 | 稍蜷 | 浊响 | 清晰 | 稍凹 | 软粘 | 0.403 | 0.237 | 是 |
6 | 7 | 乌黑 | 稍蜷 | 浊响 | 稍糊 | 稍凹 | 软粘 | 0.481 | 0.149 | 是 |
7 | 8 | 乌黑 | 稍蜷 | 浊响 | 清晰 | 稍凹 | 硬滑 | 0.437 | 0.211 | 是 |
8 | 9 | 乌黑 | 稍蜷 | 沉闷 | 稍糊 | 稍凹 | 硬滑 | 0.666 | 0.091 | 否 |
9 | 10 | 青绿 | 硬挺 | 清脆 | 清晰 | 平坦 | 软粘 | 0.243 | 0.267 | 否 |
10 | 11 | 浅白 | 硬挺 | 清脆 | 模糊 | 平坦 | 硬滑 | 0.245 | 0.057 | 否 |
11 | 12 | 浅白 | 蜷缩 | 浊响 | 模糊 | 平坦 | 软粘 | 0.343 | 0.099 | 否 |
12 | 13 | 青绿 | 稍蜷 | 浊响 | 稍糊 | 凹陷 | 硬滑 | 0.639 | 0.161 | 否 |
13 | 14 | 浅白 | 稍蜷 | 沉闷 | 稍糊 | 凹陷 | 硬滑 | 0.657 | 0.198 | 否 |
14 | 15 | 乌黑 | 稍蜷 | 浊响 | 清晰 | 稍凹 | 软粘 | 0.360 | 0.370 | 否 |
15 | 16 | 浅白 | 蜷缩 | 浊响 | 模糊 | 平坦 | 硬滑 | 0.593 | 0.042 | 否 |
16 | 17 | 青绿 | 蜷缩 | 沉闷 | 稍糊 | 稍凹 | 硬滑 | 0.719 | 0.103 | 否 |
# 获取所有属性对应的可能取值:
def get_attr(dt):
"""
return like this:
{'色泽':{'青绿','浅白','乌黑']}...}
"""
attr = {}
col = dt.columns
for c in col:
attr[c]= set(dt[c])
return attr
# 朴素贝叶斯分类
def nbcfier(dt, test):
attr = get_attr(dt.iloc[:, :-1])
ylabel = dt.iloc[:, -1:]
def getprob(label):
Pc = {}
for i in set(label.iloc[:,0]):
tmp = label.iloc[:,0].value_counts()
Pc[i] = (tmp[i]+1) / (tmp.sum()+len(set(label.iloc[:,0])))
return Pc
# 估计先验概率 P(c)
Pc = {'Pc':getprob(ylabel)}
# 为每个属性估计条件概率 P(xi | c)
Px_c = {}
for col in test.columns:
# 离散属性
p = {}
if dt[col].dtypes == object:
for y in set(ylabel.iloc[:,0]):
dt1 = dt[dt[ylabel.columns[-1]]==y]
p[y] = (len(dt1[dt1[col]==test[col][0]])+1)/(len(dt1)+len(attr[col]))
Px_c[test[col][0]] = p
# 连续属性
else:
for y in set(ylabel.iloc[:,0]):
dt1 = dt[dt[ylabel.columns[-1]]==y]
sigma = dt1.describe()[col]['std'] # 标准差
miu = dt1.describe()[col]['mean'] # 均值
p[y] = (1 / (np.sqrt(2 * np.pi) * sigma)) * np.exp(-((test[col][0] - miu)**2) / (2 * sigma**2))
Px_c[col] = p
# 判别
h = []
for y in set(ylabel.iloc[:,0]):
P = Pc['Pc'][y]
for val in Px_c.values():
P = P*val[y]
h.append([y,P])
return Pc, {'Px_c':Px_c},h
nbcfier(df.iloc[:,1:],df.iloc[0:1,1:-1])
({'Pc': {'否': 0.5263157894736842, '是': 0.47368421052631576}},
{'Px_c': {'凹陷': {'否': 0.25, '是': 0.5454545454545454},
'含糖率': {'否': 0.06622115248436898, '是': 0.7880520952044109},
'密度': {'否': 1.203303898454071, '是': 1.9590115494650353},
'浊响': {'否': 0.4166666666666667, '是': 0.6363636363636364},
'清晰': {'否': 0.25, '是': 0.7272727272727273},
'硬滑': {'否': 0.6363636363636364, '是': 0.7},
'蜷缩': {'否': 0.3333333333333333, '是': 0.5454545454545454},
'青绿': {'否': 0.3333333333333333, '是': 0.36363636363636365}}},
[['否', 7.722360621178047e-05], ['是', 0.02563102452974064]])