朴素贝叶斯分类器实战:从原理到07-1.朴素贝叶斯简述头歌实现

1次阅读
没有评论

共计 2699 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

为什么选择朴素贝叶斯?

在文本分类领域,我们常常遇到两个典型场景:

朴素贝叶斯分类器实战:从原理到 07-1. 朴素贝叶斯简述头歌实现

  1. 垃圾邮件过滤:需要快速判断新邮件是否属于垃圾邮件,处理大量用户请求时要求低延迟
  2. 新闻分类:将新闻自动归类到财经、体育等板块,特征维度常高达数万维

朴素贝叶斯算法在这些场景表现出独特优势:

  • 训练速度快,适合高维特征
  • 内存占用低,便于线上部署
  • 对缺失数据有一定鲁棒性

核心原理拆解

贝叶斯定理基础

分类问题本质是求最大后验概率:
$$P(y|x_1,x_2,…,x_n) = \frac{P(y)P(x_1,x_2,…,x_n|y)}{P(x_1,x_2,…,x_n)}$$

其中:
– $P(y)$ 是先验概率
– $P(x|y)$ 是似然概率
– 分母 $P(x)$ 对所有类别相同,实践中可忽略

朴素假设的利与弊

关键假设:特征条件独立
$$P(x_1,x_2,…,x_n|y) = \prod_{i=1}^n P(x_i|y)$$

工程价值
– 将联合概率分解为乘积,避免维度灾难
– 只需存储各特征的边缘分布

现实局限
– 实际文本中词语间存在关联(如 ” 机器学习 ” 常整体出现)
– 可通过特征组合部分缓解

概率估计方法对比

  1. 最大似然估计
    $$P(w_i|c) = \frac{count(w_i,c)}{\sum_w count(w,c)}$$
  2. 问题:未登录词概率为 0 会导致连乘归零

  3. 拉普拉斯平滑
    $$P(w_i|c) = \frac{count(w_i,c)+1}{\sum_w (count(w,c)+1)}$$

  4. 保证所有词都有非零概率
  5. 超参数 α 可调整(如 α =0.1)

Python 实现详解

特征工程:TF-IDF 转换

from sklearn.feature_extraction.text import TfidfVectorizer

# 示例语料
corpus = [
    'This is the first document.',
    'This document is the second document.',
    'And this is the third one.',
    'Is this the first document?',
]

vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names_out())

分类器核心逻辑

import numpy as np
from scipy.sparse import csr_matrix

class NaiveBayesClassifier:
    def __init__(self, alpha=1.0):
        self.alpha = alpha  # Laplace smoothing factor
        self.class_prob = None
        self.feature_prob = None

    def fit(self, X: csr_matrix, y):
        n_samples, n_features = X.shape
        self.classes = np.unique(y)
        n_classes = len(self.classes)

        # Calculate class priors
        self.class_prob = np.zeros(n_classes)
        for i, c in enumerate(self.classes):
            self.class_prob[i] = np.sum(y == c) / n_samples

        # Compute feature likelihood with smoothing
        self.feature_prob = np.zeros((n_classes, n_features))
        for i, c in enumerate(self.classes):
            class_mask = (y == c)
            N_c = X[class_mask].sum(axis=0)  # Word counts per class
            total_c = N_c.sum()  # Total words in class

            # Laplace smoothing
            self.feature_prob[i] = (N_c + self.alpha) / (total_c + self.alpha * n_features)

    def predict(self, X):
        # Logarithm to avoid underflow
        log_probs = np.log(self.feature_prob) @ X.T + np.log(self.class_prob[:, np.newaxis])
        return self.classes[np.argmax(log_probs, axis=0)]

关键实现细节:
– 使用稀疏矩阵存储(csr_matrix)节约内存
– 对数运算防止概率连乘下溢
– 支持自定义平滑系数 α

生产环境优化策略

稀疏矩阵处理

  • 使用 scipy.sparse 格式存储特征矩阵
  • 零值不占存储空间
  • 矩阵运算时自动跳过零值计算

增量训练实现

def partial_fit(self, X_batch, y_batch):
    if self.class_prob is None:  # First batch
        self.fit(X_batch, y_batch)
    else:
        # Update class counts
        new_class_counts = np.array([np.sum(y_batch == c) for c in self.classes])
        total_samples = len(y_batch) + np.sum(self.class_prob * self.n_samples)

        # Update feature counts (requires storing original counts)
        for i, c in enumerate(self.classes):
            class_mask = (y_batch == c)
            self.feature_counts[i] += X_batch[class_mask].sum(axis=0)

        # Recompute probabilities
        self._update_probs(total_samples)

生产环境注意事项

类别不平衡处理

  1. 重采样技术
  2. 对少数类过采样(如 SMOTE)
  3. 对多数类欠采样

  4. 代价敏感学习

  5. 调整决策阈值
  6. 修改损失函数权重

模型监控指标

  • 实时记录预测置信度分布
  • 设置精度 / 召回率报警阈值
  • 定期检测特征分布漂移

思考与延伸

  1. 特征组合优化:如何自动发现强关联的特征对(如 bigram)来缓解朴素假设限制?
  2. 混合建模:能否结合 BERT 等深度学习模型处理长文本,同时保留朴素贝叶斯的效率优势?

在实践中,朴素贝叶斯往往能提供令人惊讶的 baseline 效果。虽然理论假设过于理想化,但正是这种简单性使其成为文本分类任务中的瑞士军刀——不一定是最强大的工具,但绝对值得首先尝试。

正文完
 0
评论(没有评论)