一、题目:
二、算法思想:
输入:训练集
T
=
{
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
(
x
3
,
y
3
)
,
.
.
.
,
(
x
N
,
y
N
)
}
T=\begin{Bmatrix} (x_{1},y_{1}),(x_{2},y_{2}),(x_{3},y_{3}),...,(x_{N},y_{N}) \end{Bmatrix}
T={(x1,y1),(x2,y2),(x3,y3),...,(xN,yN)};实例
x
x
x;
输出:实例
x
x
x 的分类。
(1)计算先验概率和条件概率:
P
(
Y
=
c
k
)
=
∑
i
=
1
N
I
(
y
i
=
c
k
)
N
,
k
=
1
,
2
,
3
,
.
.
.
,
K
P(Y=c_{k})=\frac{\sum_{i=1}^{N}I(y_{i}=c_{k})}{N},\: k=1,2,3,...,K
P(Y=ck)=N∑i=1NI(yi=ck),k=1,2,3,...,K
P
(
X
(
j
)
=
a
j
l
∣
Y
=
c
k
)
=
∑
i
=
1
N
I
(
x
i
(
j
)
=
a
j
l
,
y
i
=
c
k
)
∑
i
=
1
N
I
(
y
i
=
c
k
)
,
k
=
1
,
2
,
3
,
.
.
.
,
K
;
j
=
1
,
2
,
.
.
.
,
n
;
l
=
1
,
2
,
.
.
.
,
S
j
P(X^{(j)}=a_{jl}|Y=c_{k})=\frac{\sum_{i=1}^{N}I(x_{i}^{(j)}=a_{jl},y_{i}=c_{k})}{\sum_{i=1}^{N}I(y_{i}=c_{k})},\: k=1,2,3,...,K;j=1,2,...,n;l=1,2,...,S_{j}
P(X(j)=ajl∣Y=ck)=∑i=1NI(yi=ck)∑i=1NI(xi(j)=ajl,yi=ck),k=1,2,3,...,K;j=1,2,...,n;l=1,2,...,Sj
(2)对给出的实例
x
=
{
x
(
1
)
,
x
(
2
)
,
.
.
.
,
x
(
n
)
}
x=\begin{Bmatrix} x^{(1)},x^{(2)},...,x^{(n)} \end{Bmatrix}
x={x(1),x(2),...,x(n)}计算联合概率分布:
P
(
Y
=
c
k
)
∗
∏
j
=
1
n
P
(
X
(
j
)
=
x
(
j
)
∣
Y
=
c
k
)
,
k
=
1
,
2
,
3
,
.
.
.
,
K
P(Y=c_{k})*\prod_{j=1}^{n}P(X^{(j)}=x^{(j)}|Y=c_{k}),\: k=1,2,3,...,K
P(Y=ck)∗j=1∏nP(X(j)=x(j)∣Y=ck),k=1,2,3,...,K
(3)根据最大值确定实例
x
x
x的类:
y
=
a
r
g
m
a
x
c
k
P
(
Y
=
c
k
)
∗
∏
j
P
(
X
(
j
)
=
x
(
j
)
∣
Y
=
c
k
)
.
y=arg \: max_{c_{k}}P(Y=c_{k})*\prod_{j}^{}P(X^{(j)}=x^{(j)}|Y=c_{k}) .
y=argmaxckP(Y=ck)∗j∏P(X(j)=x(j)∣Y=ck).
三、Python代码实现:
# author yuxy
#朴素贝叶斯算法实现
# 输入:训练数据集;实例x;
# 输出:实例x的分类。
# (1)计算先验概率和条件概率;
# (2)对于给定的实例x,计算后验概率(因为不同分类的后验概率的分母相同,所以可以简化为比较计算联合概率分布)
# (3)确定最大联合概率分布对应的类别即为实例x对应的类别。
import numpy as np
def prior_probability(dataSet, Y):
"""
求先验概率的函数,返回
:param dataSet: 训练数据集
:param Y: y的所有可能取值
:return: 一个容纳各个y值先验概率的数组
"""
m=len(dataSet)
n=len(dataSet[0])
k=len(Y) #类别的个数
res=[None for j in range(k)]
p=0
for ck in Y:
sum=float(0)
for i in range(m):
if dataSet[i][n - 1] == ck:
sum = sum + 1
res[p]=sum / m
p=p+1
return res
def condition_probability(dataSet, Y, A):
"""
求条件概率
:param dataSet: 训练数据集
:param Y: y所有可能的取值
:param A1: 第一个特征向量
:param A2:第二个特征向量
:return: 返回条件概率集合
"""
a,b=np.shape(dataSet) #训练数据集中的行和列(a行,b列)
p=len(A1)
q=len(A2)
n=len(Y)
m=p+q
res=[[float(0)]*m for i in range(n)] #创建存储条件概率的二维数组,n行m列
#计算各个y标记的次数
N=[0]*n
for i in range(n):
t=0
for k in range(a):
if dataSet[k][2] == Y[i]:
t=t+1
N[i] = t
#计算条件概率
for i in range(n):
for j in range(m):
sum1 = float(0)
sum2 = float(0)
sum3 = float(0)
sum4 = float(0)
for k in range(a):
# 循环判断dataSet中满足条件的实例
if dataSet[k][2] == Y[0]:
if j<3 and dataSet[k][0] == A[j]:
sum1 = sum1 + 1
res[0][j] = sum1 / N[0]
if j>=3 and dataSet[k][1] == A[j]:
sum3 = sum3 + 1
res[0][j] = sum3 / N[0]
elif dataSet[k][2] == Y[1]:
if j<3 and dataSet[k][0]==A[j]:
sum2 = sum2 + 1
res[1][j] = sum2 / N[1]
if j>=3 and dataSet[k][1]==A[j]:
sum4 = sum4 + 1
res[1][j] = sum4 / N[1]
return res
def joint_probability( Y, pri_probability, con_probability, x, A):
"""
求联合概率
:param Y: y的所有可能取值
:param pri_probability: 先验概率矩阵
:param con_probability: 联合概率矩阵
:param x: 给定的实例x
:return: 各个y值对应的联合概率
"""
length=len(Y)
res=[float(0)]*length
for i in range(length):
sum=float(1)
for j in range(len(x)):
sum = sum * con_probability[i][A.index(x[j])]
sum = sum * pri_probability[i]
res[i] =sum
return res
def get_max(j_probability):
"""
获取联合概率函数最大的类别,作为实例x的输出类别
:param pri_probability: 联合概率函数值
:param Y: 所有可能的x取值
:return: 返回最大值的类别值
"""
length=len(j_probability)
max=float(0)
index=0
for i in range(length):
if j_probability[i] > max:
index=i
return index
if __name__=='__main__':
dataSet=([1,'S',-1],[1,'M',-1],[1,'M',1],[1,'S',1],[1,'S',-1],[2,'S',-1],[2,'M',-1],[2,'M',1],
[2,'L',1],[2,'L',1],[3,'L',1],[3,'M',1],[3,'M',1],[3,'L',1],[3,'L',-1])
Y=[1,-1]
A1=[1,2,3]
A2=['S','M','L']
A = A1 + A2
x = [2, 'S']
pri_probability= prior_probability(dataSet, Y)
con_probability=condition_probability(dataSet, Y, A)
j_probability=joint_probability(Y, pri_probability, con_probability, x, A)
print('训练样本集为:')
for i in range(len(dataSet)):
print(dataSet[i])
print('实例x为:%s' % x)
print('实例x的类别为:%s' % Y[get_max(j_probability)])
实验结果: