朴素贝叶斯
一、直观理解:用“条件独立”把贝叶斯公式算到底
朴素贝叶斯(Naive Bayes)先问:在看到特征 之后,样本更像哪一类?贝叶斯公式给出
难点是 在高维下难以估计。朴素假设是:给定类别后,各特征相互独立,于是
联合分布拆成一堆一维分布,统计上粗糙,但在文本分类、垃圾邮件、简单传感器组合等问题上往往出奇地好用——偏差大,方差小,校准有时还不错。
可以把它想成:每位“特征证人”独立作证,法官按先验与各证人的似然连乘更新信念。
二、适用场景与优缺点
| 类型 | 说明 |
|---|---|
| 适用场景 | 文本词频/TF-IDF;高维稀疏计数特征;需要快速基线与概率输出;特征近似条件独立;在线/流式更新。 |
| 核心优点 | 训练极快(只需计频率或高斯参数);对高维友好;实现简单;小样本也可估;天然多分类。 |
| 局限与缺点 | 条件独立常不成立,概率可能过尖;特征相关时决策仍可能准但概率失真;高斯版对非正态敏感;零概率需要平滑。 |
使用前:选择合适的事件模型(高斯/多项式/伯努利);做拉普拉斯平滑;标准化对高斯 NB 有时有用,对多项式 NB 通常保持计数。
三、核心原理
1. 决策规则
取对数把连乘变求和,数值更稳。
2. 常见事件模型
| 模型 | 特征假设 | 典型数据 |
|---|---|---|
| 高斯 NB | 连续测量 | |
| 多项式 NB | 词频多项分布 | 文本计数 |
| 伯努利 NB | 特征是否出现 | 二值词袋 |
3. 拉普拉斯平滑(多项式)
即加一平滑,避免某词在某类未出现导致整个后验为 0。
尽管独立假设很强,分类只关心后验的排序,因此即使概率估计有偏,argmax 仍可能正确。
四、关键决策
| 决策点 | 建议 |
|---|---|
| 分布族 | 连续 → 高斯;文本计数 → 多项式;0/1 → 伯努利 |
| 平滑 | 文本默认 1,可用 CV 微调 |
| 先验 | 默认用训练频率;可按业务设类先验 |
| 特征 | 去掉近乎恒定的列;文本去停用词、可 IDF |
| 相关特征 | 强相关可合并或降维,减轻“重复计票” |
| 评价 | 看校准与 Brier;不只看准确率 |
五、MATLAB 示例
% 连续特征 + 高斯朴素贝叶斯
X = [
5.1 3.5 1.4;
4.9 3.0 1.4;
6.2 3.4 5.4;
5.9 3.0 5.1;
5.5 2.3 4.0;
6.5 3.0 5.5;
4.8 3.4 1.6;
5.7 2.8 4.5
];
y = [1;1;3;3;2;3;1;2]; % 三类
Mdl = fitcnb(X, y, ...
"DistributionNames", "normal", ...
"Prior", "empirical");
% 查看各类各特征均值
for c = 1:numel(Mdl.ClassNames)
fprintf("类 %s 的均值:\n", string(Mdl.ClassNames(c)));
disp(Mdl.DistributionParameters{c,1}); % 结构因版本而异,可检查文档
end
[label, posterior, cost] = predict(Mdl, X);
disp("混淆矩阵:");
disp(confusionmat(y, label));
disp("后验概率(前 5 行):");
disp(posterior(1:5, :));
% 交叉验证
cv = crossval(Mdl, "KFold", 4);
fprintf("CV loss = %.3f\n", kfoldLoss(cv));
% 若特征是计数型文本,可设置
% Mdl = fitcnb(Xcount, y, "DistributionNames", "mvmn"); % 或按文档使用 multinomial
% 对高斯 NB 也可指定不同特征不同分布:
% Mdl = fitcnb(X, y, "DistributionNames", {"normal","normal","kernel"});
简单手写高斯 NB(便于论文公式对照):
classes = unique(y);
[n, p] = size(X);
mu = zeros(numel(classes), p);
sg = zeros(numel(classes), p);
pri = zeros(numel(classes), 1);
for i = 1:numel(classes)
Xi = X(y == classes(i), :);
mu(i, :) = mean(Xi);
sg(i, :) = std(Xi, 0); % 可用平滑避免 0 方差
sg(i, sg(i,:) < 1e-6) = 1e-6;
pri(i) = size(Xi, 1) / n;
end
x = X(1, :);
logPost = log(pri);
for i = 1:numel(classes)
logPost(i) = logPost(i) + sum( ...
-log(sqrt(2*pi)*sg(i,:)) - 0.5*((x - mu(i,:))./sg(i,:)).^2 );
end
[~, idx] = max(logPost);
fprintf("手写 NB 预测类 = %d\n", classes(idx));
六、如何解释结果
- 类条件均值/方差(高斯):某类在哪些特征上整体偏高;
- 似然比:某特征值使哪一类的 显著更大;
- 后验概率:给出“有多有把握”,但若特征相关,概率值可能过度自信;
- 先验影响:小样本下先验会拉动结果;
- 报告:事件模型、平滑、类先验、CV 指标、与 Logistic 对比。
七、常见误区
1. 条件独立当真理
它是计算假设,不是世界规律;相关特征会重复放大证据。
2. 零概率“一票否决”
不加平滑时,未见过的词会把整类后验打成 0。
3. 把后验当成精确风险
需要可靠概率时做校准或换模型。
4. 连续特征硬套多项式,或文本硬套高斯
事件模型与数据类型匹配比调参更重要。
5. 忽略类先验与采样偏差
训练类比例若与部署不同,应调整先验。
八、小结
朴素贝叶斯在特征条件独立假设下,用先验乘类条件似然做分类,是最快、最干净的概率基线之一。
它特别适合高维稀疏与文本类问题,也适合作为复杂模型的对照。写论文时诚实说明独立假设,用混淆矩阵与校准检查“准”和“信”是否同步。