前言
这篇文章来自最近做的一个小的课程实验,写完了贴出来希望对大家能有帮助。
创作不易,如果有需要引用,希望大家标明原作者。
然后是,养成先赞后看的好习惯,仓库放这里。
实验原理:
-
贝叶斯分类器的实现。
贝叶斯分类器的判决规则来自于贝叶斯决策论,原理在已知信息的基础上进行最小条件风险分类。
贝叶斯公式表明,在已知一个样本点 ω \omega ω的特征值 x x x,和训练样本的先验概率 P ( ω i ) P(\omega_i) P(ωi)和类条件概率密度函数 p ( x ∣ ω i ) p(x|\omega_i) p(x∣ωi)时,可计算出后验概率 P ( w i ∣ x ) P(w_i |x) P(wi∣x)。
P
(
ω
i
∣
x
)
=
p
(
x
∣
ω
i
)
∗
P
(
ω
i
)
p
(
x
)
P(\omega_i |x)=\cfrac{p(x|\omega_i)*P(\omega_i)}{p(x)}\\
P(ωi∣x)=p(x)p(x∣ωi)∗P(ωi)
后验概率表征的是当样本点
ω
\omega
ω的特征值为
x
x
x时,其属于
ω
i
\omega_i
ωi的可能性大小。
此时,分类行为的误差率 P ( e r r o r ) P(error) P(error)为选择另一半的概率。
对分类行为的概率
P
(
ω
i
∣
x
)
P(\omega_i|x)
P(ωi∣x)乘以选择类型的行为
α
i
\alpha_i
αi的损失函数
λ
(
α
i
∣
ω
i
)
\lambda(\alpha_i|\omega_i)
λ(αi∣ωi)并积分构成条件风险
R
(
α
i
∣
ω
i
)
R(\alpha_i|\omega_i)
R(αi∣ωi):
R
(
α
i
∣
x
)
=
Σ
j
=
1
c
λ
(
α
i
∣
ω
i
)
P
(
ω
i
∣
x
)
R(\alpha_i|x)=\Sigma_{j=1}^{c}\lambda(\alpha_i|\omega_i)P(\omega_i|x)
R(αi∣x)=Σj=1cλ(αi∣ωi)P(ωi∣x)
条件风险表征的是后验概率条件已知时,采取分类行为对应的行为损失,条件风险越小,可能性越大。
将贝叶斯分类器抽象为以下组成部分:
部分 | 组成 |
---|---|
输入 | 多个输入 |
判决函数 | 多个类别的判别函数 |
输出 | 分类结果 |
贝叶斯分类器的核心是判别函数,对应
c
c
c个类的最小损失函数,用于判决样本点的类别。
g
t
(
x
)
=
m
a
x
(
g
j
(
x
)
)
→
ω
=
ω
t
g_t(x)=max(g_j(x))\rightarrow \omega=\omega_t
gt(x)=max(gj(x))→ω=ωt
在自然环境中,样本的类条件概率密度函数的似然函数是高斯函数,判决函数为
l
n
P
(
ω
i
)
g
i
(
x
)
=
−
1
2
(
x
−
μ
i
)
T
Σ
i
−
1
(
x
−
μ
i
)
−
d
2
l
n
2
π
−
1
2
l
n
∣
Σ
i
∣
+
l
n
P
(
ω
i
)
{lnP(ωi)} g_i(x)=−\cfrac{1}{2}(x−μ_i)^TΣ^{−1}_{i}(x−μ_i)−\cfrac{d}{2}ln2π−\cfrac{1}{2}ln|Σ_i|+lnP(\omega_i)
lnP(ωi)gi(x)=−21(x−μi)TΣi−1(x−μi)−2dln2π−21ln∣Σi∣+lnP(ωi)
多项式第一项包含马氏距离,表征样本点与类别均值的相似性; d d d表示特征向量的维度,表征待分类样本的维度信息; Σ i \Sigma_i Σi表示类别 i i i的协方差矩阵,表征类别特征值的分散程度, P ( ω i ) P(\omega_i) P(ωi)表示先验概率。
-
马氏距离。
马氏距离在以上判决函数中出现,是一种用于衡量两个样本之间的相似度或差异性的指标。计算马氏距离的原理是,在特征空间中,通过计算两个样本点之间的欧氏距离,然后乘以协方差矩阵的逆矩阵,再次与欧氏距离相乘得到。
m
=
(
x
−
μ
i
)
T
Σ
i
−
1
(
x
−
μ
i
)
m = (x - \mu_i)^{T}\Sigma_i^{-1}(x-\mu_i)
m=(x−μi)TΣi−1(x−μi)
其中,
x
x
x表示该点的特征向量,
μ
i
\mu_i
μi表示该类别的均值向量,
Σ
i
\Sigma_i
Σi表示该类的协方差矩阵。
马氏距离的实际意义是,马氏距离越小,说明所计算的样本点特征向量和类别均值相似度越高。马氏距离为零时,表明样本点与类别均值重合。
在判别函数中使用马氏距离的好处是:首先,考虑了特征值之间的相关性,协方差矩阵的马氏距离通过协方差矩阵的逆矩阵进行加权,使分类器能根据训练数据自适应调整特征值的权值,其次,使用马氏距离降低特征维度,简化了计算模型。
代码实现
实验步骤
-
将已知的数据集输入对分类器进行训练,训练判决函数;
-
对新的样本点类别进行预测分类;
-
计算样本的经验训练误差;
-
调整先验概率,计算新的样本点到类别均值向量的马氏距离;
-
调整先验概率,对新的样本点进行分类。
实验代码
class BYES:
# 构造函数
# d 特征向量的维度
# prior 先验概率
# tra_data 训练数据
# tar_lab 训练标签
def __init__(self,d , prior, tra_data, tra_lab):
self.d = d # 特征值维度
self.prior = prior # 先验概率
self.means = [] # 均值
self.covariances = [] # 协方差矩阵
self.cal_cov(tra_data, tra_lab)
# 均值 and 协方差
# tra_data 训练数据
# tar_lab 训练标签
def cal_cov(self, tra_data, tra_lab):
for i in range(len(self.prior)): # 遍历所有类别
samples = [data for label, data in zip(tra_lab, tra_data) if label == i]
samples = np.array(samples) # 将样本转换成 numpy 数组
mean = np.mean(samples, axis=0) # 计算样本点的均值
cov = np.dot((samples - mean).T, (samples - mean)) / (samples.shape[0] - 1) # 计算样本点的协方差
self.means.append(mean)
self.covariances.append(cov)
# 计算马氏距离
def m_distance(self, x):
m_dits = []
for i in range(len(self.means)):
mean = self.means[i]
cov = self.covariances[i]
diff = np.array(x) - mean # 计算样本点与均值点的差异
if len(diff.shape) == 1:
diff = diff[:, np.newaxis] # 将一维数据转换成列向量
m_dit = np.dot(np.dot(diff.T, np.linalg.inv(cov)), diff) # 马氏距离
m_dit = m_dit.item()
m_dits.append(m_dit)
return m_dits
# 判别函数
def judge(self, x): # x 样本点
gs = [] # 存储判别函数的值
m_dits = self.m_distance(x) # 马氏距离
for mean, m_dit, cov, prior in zip(self.means, m_dits, self.covariances, self.prior): # 遍历
det = np.linalg.det(cov)
g = - 0.5 * m_dit - 0.5 * self.d * math.log(np.pi) - 0.5 * math.log(det) + math.log(prior) # 计算判别函数的值
gs.append(g)
result = gs.index(max(gs)) # 获取最大值的索引
return result
# 预测函数
def predict(self, test_data): # test_data 测试样本
pre_results = []
for x in test_data: # 遍历测试样本
pre_result = self.judge(x) # 获取判别结果
pre_results.append(pre_result)
print("预测结果", pre_results)
return pre_results
# 计算误差率
def cal_error(self,test_data,test_lab):
pre_results = self.predict(test_data) # 获取预测结果
count = 0
for i, j in zip(pre_results, test_lab):
if i != j:
count += 1 # 比较预测结果与测试标签
error = float(count / len(test_lab)) # 计算误差率
print(error)
return error
实验结论
结果太多,这里就浅贴几张,多的不放上来了,大家可以自己尝试一下。
下面部分是分析总结的实验结论:
-
贝叶斯分类器对特征向量的选择是敏感的,为了获得更有效的分类结果,可以对训练样本进行的特征向量进行适当选择和预处理,这可以明显提高贝叶斯分类器的性能,得到更小的分类误差,降低分类偏差带来的损失。
-
贝叶斯分类器并不是特征向量维度越高越有效。在实际训练时,应该通过测试进行验证,而不是依靠直觉推测。
-
先验概率的估计对贝叶斯分类器非常重要的,在实际训练过程中应当通过技术手段,尽可能获得精确的先验概率估计,有效提高贝叶斯分类结果的正确性。
-
马氏距离对贝叶斯分类器的贡献,是考虑了特征向量之间的相关性,通过权值调整,有效降低了预测结果的误差率。因此选择更有效的数据处理方式,可以降低分类的误差率,提高分类性能。