一、贝叶斯决策论
对于一个多分类任务,假设有标签
y
=
{
y
1
,
y
2
,
.
.
.
,
y
n
}
y=\{y_1,y_2,...,y_n\}
y={y1,y2,...,yn},记
λ
i
j
\lambda_{ij}
λij为将真实标签为
y
j
y_j
yj的样本误分类为
y
i
y_i
yi的代价,则可以得到将样本
x
x
x分类为
y
i
y_i
yi的期望代价:
l
o
s
s
(
y
i
∣
x
)
=
∑
j
=
1
n
λ
i
j
P
(
y
j
∣
x
)
loss(y_i|x)=\sum_{j=1}^{n}{\lambda_{ij}P(y_j|x)}
loss(yi∣x)=j=1∑nλijP(yj∣x)
在贝叶斯分类模型中,想要尽可能准确地预测出类标,则只需选择一个期望代价最小的样本。
设损失函数:
λ
i
j
=
{
0
,
i
=
j
1
,
i
≠
j
\lambda_{ij}= \begin{cases} 0,\qquad i=j\\ 1,\qquad i≠j \end{cases}
λij={0,i=j1,i=j
则有:
l
o
s
s
(
y
i
∣
x
)
=
1
−
P
(
y
i
∣
x
)
loss(y_i|x)=1-P(y_i|x)
loss(yi∣x)=1−P(yi∣x)
那么,最小化
l
o
s
s
loss
loss函数就变成了最大化
P
(
y
i
∣
x
)
P(y_i|x)
P(yi∣x),贝叶斯分类模型的分类依据变为:
h
(
x
)
=
arg max
y
i
∈
y
P
(
y
i
∣
x
)
=
arg max
y
i
∈
y
P
(
y
i
)
P
(
x
∣
y
i
)
P
(
x
)
=
arg max
y
i
∈
y
P
(
y
i
)
P
(
x
∣
y
i
)
h(x)=\argmax_{y_i\in y} P(y_i|x)=\argmax_{y_i\in y}{\frac{P(y_i)P(x|y_i)}{P(x)}}=\argmax_{y_i\in y}{P(y_i)P(x|y_i)}
h(x)=yi∈yargmaxP(yi∣x)=yi∈yargmaxP(x)P(yi)P(x∣yi)=yi∈yargmaxP(yi)P(x∣yi)
二、朴素贝叶斯
根据上面给出的分类依据,可以知道建立模型的关键在于估计
P
(
x
∣
y
i
)
P(x|y_i)
P(x∣yi)。这是一个在样本所有属性上的联合分布,难以估计,所以朴素贝叶斯模型提出了一个前提假设:所有的样本属性相互独立。
在上述前提假设下,分类依据可以改写为:
h
(
x
)
=
arg max
y
i
∈
y
P
(
y
i
)
P
(
x
∣
y
i
)
=
arg max
y
i
∈
y
P
(
y
i
)
∏
i
=
0
m
P
(
x
i
∣
y
i
)
h(x)=\argmax_{y_i\in y}{P(y_i)P(x|y_i)}=\argmax_{y_i\in y}{P(y_i)\prod_{i=0}^m{P(x_i|y_i)}}
h(x)=yi∈yargmaxP(yi)P(x∣yi)=yi∈yargmaxP(yi)i=0∏mP(xi∣yi)
此处的
x
i
x_i
xi表示样本的每个属性值,
m
m
m为属性数量。
设
D
D
D是所有的样本,
D
y
i
D_{y_i}
Dyi是类标为
y
i
y_i
yi的样本,则可估计:
P
(
y
i
)
=
∣
D
y
i
∣
∣
D
∣
P(y_i)=\frac{|D_{y_i}|}{|D|}
P(yi)=∣D∣∣Dyi∣
如果
x
i
x_i
xi为离散属性,设
D
y
i
,
x
i
D_{y_i,x_i}
Dyi,xi是类标为
y
i
y_i
yi且第
i
i
i个属性值为
x
i
x_i
xi的样本数量,则可估计:
P
(
x
i
∣
y
i
)
=
∣
D
y
i
,
x
i
∣
∣
D
∣
P(x_i|y_i)=\frac{|D_{y_i,x_i}|}{|D|}
P(xi∣yi)=∣D∣∣Dyi,xi∣
如果
x
i
x_i
xi为连续属性,设概率函数
p
(
x
i
∣
y
i
)
=
N
(
μ
,
σ
2
)
p(x_i|y_i)=N(\mu,\sigma^2)
p(xi∣yi)=N(μ,σ2),其中
μ
\mu
μ和
σ
\sigma
σ为第
i
i
i个属性取值的均值和标准差,则可估计:
P
(
x
i
∣
y
i
)
=
1
2
π
σ
exp
(
−
(
x
−
μ
)
2
2
σ
2
)
P(x_i|y_i)=\frac{1}{\sqrt{2\pi}\sigma}\exp{(-\frac{(x-\mu)^2}{2\sigma^2})}
P(xi∣yi)=2πσ1exp(−2σ2(x−μ)2)
三、Python实现
import numpy as np
class NaiveBayesClassifier(object):
def __init__(self):
self.fit_X = None
self.fit_y = None
def _gauss_func(self, feature, xi, yi):
sample = self.fit_X[self.fit_y == yi, feature]
sigma = np.std(sample)
u = np.mean(sample)
return 1 / (np.sqrt(2 * np.pi) * sigma) * np.exp(-(xi - u)**2 / (2 * sigma**2))
def fit(self, X, y):
self.fit_X = X
self.fit_y = y
return self
def _predict(self, x):
N = len(np.unique(self.fit_y))
score = []
for i in range(N):
P_c = (len(self.fit_y[self.fit_y == i]) + 1) / (len(self.fit_y) + N)
log_P_xc = []
features = list(range(self.fit_X.shape[1]))
for f in features:
log_P_xc.append(np.log(self._gauss_func(f, x[f], i)))
score.append(np.log(P_c) + sum(log_P_xc))
return np.argmax(score)
def predict(self, X):
y = []
for x in X:
y.append(self._predict(x))
return np.array(y)