如何用Numpy高效计算朴素贝叶斯的对数似然值?
用Numpy向量化计算朴素贝叶斯对数似然值
问题背景
已知正类(+1)和负类(-1)各维度取1的概率数组:
positive = [0.07973422, 0.02657807] negative = [0.04651163, 0.02491694] # 维度均为d
测试样本与标签:
import numpy as np x = np.array([[0,1],[1,0],[1,1]]) # 维度n*d,d与上述一致 y = np.array([-1,1,-1]) # 维度n
期望计算结果:
result = [-3.73983529, -2.55599409, -6.76026018] # 维度n
计算逻辑:每个结果元素对应x的一行,根据y的标签选择对应概率数组。例如第0行[0,1]标签为-1,取negative数组,计算log(1-0.04651163)+log(0.02491694)得到对应结果(0的概率为1减1的概率)。当前使用循环实现,需要用Numpy向量化方法提速。
向量化实现方案
直接用Numpy的索引和广播机制实现,无需循环:
import numpy as np # 初始化概率数组 positive = np.array([0.07973422, 0.02657807]) negative = np.array([0.04651163, 0.02491694]) x = np.array([[0,1],[1,0],[1,1]]) y = np.array([-1,1,-1]) # 根据标签选择对应的概率矩阵:y为1选positive,-1选negative prob_matrix = np.where(y[:, None] == 1, positive, negative) # 计算每个元素的对数概率:x=1时取log(prob),x=0时取log(1-prob) log_probs = np.where(x == 1, np.log(prob_matrix), np.log(1 - prob_matrix)) # 对每行求和得到最终的对数似然值 result = log_probs.sum(axis=1) print(result) # 输出:[-3.73983529 -2.55599409 -6.76026018]
代码解释
- 概率矩阵构建:利用
np.where和广播机制,将每个样本的标签映射到对应的概率数组,生成形状为(n,d)的概率矩阵,每个样本行对应其类别的概率数组。 - 对数概率计算:再次使用
np.where,根据x中元素是0还是1,选择计算log(1-prob)或log(prob),完成逐元素的对数转换。 - 行求和:对每行的对数概率求和,得到每个样本的对数似然值,结果与期望完全一致。
这种向量化方式避免了Python循环,充分利用Numpy的C底层优化,在样本量较大时能显著提升计算速度。
内容的提问来源于stack exchange,提问作者puru
相关产品推荐
相关产品推荐

