统计学习第四章-贝叶斯分类器
李航的统计学习方法写的很少,结合西瓜书,说一下自己的理解。
条件概率和全概率公式
由已知的数据集去估计关于
(
x
,
y
)
(x,y)
(x,y)的联合分布
f
(
x
,
y
)
f(x,y)
f(x,y)或
P
(
x
,
y
)
P(x,y)
P(x,y),在已知x的情况下,求y。对于连续型,条件分布函数如下,概率密度为对其积分
∫
−
∞
y
f
(
x
,
u
)
d
u
\int_{-\infty}^{y} f(x,u){du}
∫−∞yf(x,u)du
f
(
y
∣
x
)
=
f
(
x
,
y
)
∫
−
∞
∞
f
(
x
,
y
)
d
y
f(y|x) = \frac{f(x,y)}{\int_{-\infty}^{\infty}f(x,y){dy}}
f(y∣x)=∫−∞∞f(x,y)dyf(x,y)
对于离散型有
P
(
Y
∣
X
)
=
P
(
X
,
Y
)
P
(
X
)
=
P
(
X
∣
Y
)
P
(
Y
)
P
(
X
)
P(Y|X) = \frac{P(X,Y)}{P(X)} = \frac{P(X|Y)P(Y)}{P(X)}
P(Y∣X)=P(X)P(X,Y)=P(X)P(X∣Y)P(Y)
全概率公式
P
(
X
∣
Y
)
=
P
(
X
(
1
)
=
x
(
1
)
,
X
(
2
)
=
x
(
2
)
,
…
X
(
n
)
=
x
(
n
)
∣
Y
)
P
(
X
)
=
∑
i
=
1
n
P
(
X
∣
Y
i
)
P(X|Y) = P(X^{(1)}=x^{(1)},X^{(2)}=x^{(2)},\dots X^{(n)}=x^{(n)}|Y)\\ P(X) = \sum_{i=1}^n P(X|Y_i)
P(X∣Y)=P(X(1)=x(1),X(2)=x(2),…X(n)=x(n)∣Y)P(X)=i=1∑nP(X∣Yi)
假设独立性,
X
(
1
)
,
X
(
2
)
…
,
X
(
n
)
X^{(1)},X^{(2)}\dots ,X^{(n)}
X(1),X(2)…,X(n)相互独立则计算变得简洁。
P
(
X
∣
Y
)
=
∏
i
=
1
n
P
(
X
(
i
)
=
x
(
i
)
∣
Y
)
P
(
X
)
=
∑
j
=
1
n
∏
i
=
1
n
P
(
X
(
i
)
=
x
(
i
)
∣
Y
j
)
P(X|Y) = \prod_{i=1}^n P(X^{(i)}=x^{(i)}|Y)\\ P(X) = \sum_{j=1}^n \prod_{i=1}^n P(X^{(i)}=x^{(i)}|Y_j)
P(X∣Y)=i=1∏nP(X(i)=x(i)∣Y)P(X)=j=1∑ni=1∏nP(X(i)=x(i)∣Yj)
分类问题,对于所有的y,
P
(
X
)
P(X)
P(X)相同,所以唯一的判断便是
P
(
X
∣
Y
)
P(X|Y)
P(X∣Y)
根据已有样本去估计先验概率。
似然估计
估计的方法为似然估计,这个估计极大的依赖了样本数据是否真的存在合乎真实分布的潜在假设。如果没有,则在预测上会表现得非常差。
对于某个样本其条件概率的极大似然估计为
P
(
X
1
∣
Y
1
)
=
∑
I
(
X
=
X
1
,
Y
=
Y
1
)
∑
I
(
Y
=
Y
1
)
P(X_1|Y_1) = \frac{\sum I(X=X_1,Y=Y_1)}{\sum I(Y=Y_1)}
P(X1∣Y1)=∑I(Y=Y1)∑I(X=X1,Y=Y1)
对于某类样本
Y
1
Y_1
Y1,根据已知统计
Y
1
Y_1
Y1出现的次数
I
(
Y
1
)
{I(Y_1)}
I(Y1),
P
=
I
(
Y
1
)
/
I
(
Y
)
P = {I(Y_1)}/{I(Y)}
P=I(Y1)/I(Y)在
Y
1
Y_1
Y1的样本中,统计
X
1
X_1
X1出现的次数
I
(
X
1
)
I(X_1)
I(X1)则
P
(
X
1
∣
Y
1
)
=
I
(
X
1
)
I
(
Y
1
)
P(X_1|Y_1) = \frac{I(X_1)}{I(Y_1)}
P(X1∣Y1)=I(Y1)I(X1)。对于连续型可以用正态分布去估计
p
(
x
i
,
y
)
=
1
2
π
σ
y
,
i
e
x
p
(
−
(
x
i
−
u
c
,
i
)
2
2
σ
c
,
i
2
)
u
^
=
平
均
值
(
x
i
)
σ
^
c
,
i
2
=
∑
x
i
∈
I
(
Y
)
(
x
−
u
^
y
)
2
p(x_i,y) = \frac{1}{\sqrt{2\pi}\sigma _{y,i}}exp(-\frac{(x_i-u_{c,i})^2}{2\sigma _{c,i}^2}) \\ \hat u = 平均值(x_i) \\ \hat \sigma_{c,i}^2 = \sum_{x_i \in I(Y)}(x-\hat u_y)^2
p(xi,y)=2πσy,i1exp(−2σc,i2(xi−uc,i)2)u^=平均值(xi)σ^c,i2=xi∈I(Y)∑(x−u^y)2
对于某些特殊情况,,可能出现概率为0的情况,这样会导致概率被影响,引入平滑
P
=
I
(
Y
1
)
+
λ
I
(
Y
)
+
λ
N
(
Y
的
可
能
取
值
种
类
)
P
(
X
1
∣
Y
1
)
=
I
(
X
1
)
+
λ
I
(
Y
1
)
+
λ
N
(
X
1
的
可
能
取
值
种
类
)
(
1
)
P = \frac{I(Y_1)+\lambda}{I(Y)+\lambda N(Y的可能取值种类)} \\ P(X_1|Y_1)= \frac{I(X_1)+\lambda}{I(Y_1)+\lambda N(X_1的可能取值种类)} \qquad(1)
P=I(Y)+λN(Y的可能取值种类)I(Y1)+λP(X1∣Y1)=I(Y1)+λN(X1的可能取值种类)I(X1)+λ(1)
λ
\lambda
λ越大则说明测试集的影响越小,
λ
→
∞
\lambda \rightarrow \infty
λ→∞时,测试集失去意义。
半朴素贝叶斯
朴素贝叶斯认为
X
(
1
)
,
X
(
2
)
…
,
X
(
n
)
X^{(1)},X^{(2)}\dots ,X^{(n)}
X(1),X(2)…,X(n)相互独立,在半朴素贝叶斯当中,认为某些元素与其他元素有关系,即
P
(
c
∣
x
)
=
a
P
(
c
)
∏
P
(
x
i
∣
c
,
p
a
i
)
P(c|x) = a P(c)\prod P(x_i|c,pa_i)
P(c∣x)=aP(c)∏P(xi∣c,pai)
其中
p
a
i
pa_i
pai为父属性,假设已知,可以采用(1)计算(即统计父属性与子属性相同的样本),如何确定父属性是难点。
SPODE:初始属性为所有点的父属性
TAN:计算每个信息点的信息度,选择强信息度的链接保留。构建加权信息树。
AODE:将所有的属性作为父属性,将数据集足够多的样本作为结果。
提升高阶依赖性可以提高,但是容易陷入高阶依赖性的泥潭。
#我的看法
如果不能改变依赖性,可以采用设定第一个属性为父属性,
将第二个属性中第一个属性的依赖性减去,
则得到第二个属性中不依赖第一个属性的属性2
以此类推得到n个独立属性,再将样本集分为独立属性分量。
,,,不知道对不对,,,
贝叶斯网的内容为确定超父点,得到联合概率分布。
EM算法
对于存在未观测变量Z
L
L
(
Θ
∣
X
,
Z
)
=
l
n
P
(
X
,
Z
∣
Θ
)
=
l
n
∑
Z
P
(
X
,
Z
∣
Θ
)
LL(\Theta |X,Z) = lnP(X,Z|\Theta)=ln\sum_{Z} P(X,Z|\Theta)
LL(Θ∣X,Z)=lnP(X,Z∣Θ)=ln∑ZP(X,Z∣Θ)
若参数Θ已知,则通过Θ可以估计最佳变量Z,如果Z已知则可以估计Θ,通过这种方法,进行迭代优化,计算出Z,Θ。
python实现
贝叶斯分类的python代码,预测花的种类,采用numpy以及pandas操作。iris数据集结构如下所示。
0 1 2 3 4
0 5.1 3.5 1.4 0.2 Iris-setosa
1 4.9 3.0 1.4 0.2 Iris-setosa
2 4.7 3.2 1.3 0.2 Iris-setosa
3 4.6 3.1 1.5 0.2 Iris-setosa
4 5.0 3.6 1.4 0.2 Iris-setosa
…
145 6.7 3.0 5.2 2.3 Iris-virginica
146 6.3 2.5 5.0 1.9 Iris-virginica
147 6.5 3.0 5.2 2.0 Iris-virginica
148 6.2 3.4 5.4 2.3 Iris-virginica
149 5.9 3.0 5.1 1.8 Iris-virginica
总共是150行数据集,按照columns第五列存放花的种类,其余存放其他特征。
def read_data(路径 = 'c:\'):
花 = pandas.读入txt(路径)
#pandas读入数据后默认numpy数据
return 花
#切分数据
def split_data(数据集,切分标准 = 0.8):
存放集 = list(数据集.行索引)
random.shulffle(存放集)
#打乱标签集,并将其赋值给行索引,此时行索引为乱序。
#行.索引 应该= range(存放集)
#数据集.shape[0]表示行数量
#数据集.shape[1]表示列数量
测试集含量 = int(切分标准*数据集.shape[0])
#可能不为0,int取整
训练集 = 数据集.切片(0:[测试集含量],:)
#对行进行切片操作
测试集 = 数据集.切片([测试集含量]:,:)
#更新数据集标签,其实更不更新都无所谓
数据集.行索引= range(数据集.shape[0])
#更新测试集标签,测试集标签不是0开始
测试集.行索引 = range(测试集.shape(0))
return 训练集, 测试集
#通过训练集训练,预测测试集结果
#默认正态分布
def gnb_class(训练集,测试集):
标签 = 训练集.iloc[:,-1].vlaue_counts().index
#用于返回标签的内容,是一个集合,存放所有可能的值
均值 = []
方差 = []
预测结果 = []
#对于每一个标签都进行计算
for y in 标签:
#删除最后一列,提取出相同的y,从新构造数据集
集合 = 训练集[训练集.最后一列 == 标签].iloc[:,-1]
#.iloc操作用于切片,本操作为连环操作
标签平均值 = 集合.mean()
#.mean()为对行进行平均值计算,返回一个1×n的列向量
标签方差 = 集合.方差()
# 没有这个函数,自己用平均值写吧,返回一个1×n的列向量
均值.append(标签平均值)
方差.append(标签方差)
#将均值和方差保存为pandas数据结构
'''
0 均值1 均值2 均值3 均值4 ---y1
1 均值1 均值2 均值3 均值4 ---y2
2 均值1 均值2 均值3 均值4 ---y3
'''
均值组 = pandas.Dataframe(均值,index = 标签)
方差组 = pandas.Dataframe(方差,index = 标签)
#对测试集数据操作
for j in range(测试集.行数):
测试数据 = 测试集.iloc[j,:-1].tolist()
#将测试数据和方差均值调整为同种数据格式,并去掉最后一行。
#计算概率
概率 = exp(-1*(测试数据-均值组)**2/(方差组*2))/(sqrt(2*pai*方差组))
初始化概率 = 1
#对每个特征的概率相乘
for k in range(测试集.列数-1)
初始化概率 = 初始化概率*概率[k]
#将每一列的概率相乘得到一个y行一列的数组
#找到概率最大的哪个标签,即为返回的预测结果
最大值标签 = 初始化概率.标签[找最大值(初始化概率的值)]
结果.append(最大值标签)
#计算结果等于测试集的数目的平均值
准确率 = (结果 == 测试集.iloc[:,-1]).mean()
return 准确率
对于正常的词义预测分类与此类似,不做赘述。