Sklearn 朴素贝叶斯

sklearn.naive_bayes 提供高斯、多项式、伯努利、补集、分类朴素贝叶斯分类器。


📊 高斯朴素贝叶斯

GaussianNB

适用于连续特征,假设每个类别的每个特征服从高斯分布。

from sklearn.naive_bayes import GaussianNB

model = GaussianNB(
    priors=None,               # 先验概率(None=从数据中学习)
    var_smoothing=1e-9        # 方差平滑(防止零方差)
)

model.fit(X, y)

# 关键属性
print(model.class_count_)      # 每类的样本数
print(model.class_prior_)      # 每类的先验概率
print(model.classes_)          # 类别标签
print(model.epsilon_)          # 方差平滑值
print(model.n_features_in_)    # 特征数
print(model.feature_names_in_) # 特征名(DataFrame 输入时)
print(model.theta_)            # 每类每个特征的均值 (n_classes, n_features)
print(model.var_)              # 每类每个特征的方差 (n_classes, n_features)
print(model.sigma_)            # 每类每个特征的方差(已平滑)

# 预测
y_pred = model.predict(X)
y_prob = model.predict_proba(X)       # 各类别概率
y_log_prob = model.predict_log_proba(X)

# 更新模型(部分拟合)
model.partial_fit(X_batch, y_batch, classes=np.unique(y))

📝 多项式朴素贝叶斯

MultinomialNB

适用于离散特征(如文本的词频/TF-IDF),经典应用是文档分类。

from sklearn.naive_bayes import MultinomialNB

model = MultinomialNB(
    alpha=1.0,                 # 拉普拉斯/利德斯通平滑参数
    # alpha=0  → 不平滑
    # alpha=1  → 拉普拉斯平滑
    # alpha<1  → 利德斯通平滑
    force_alpha=True,          # 1.2+: 强制 alpha 参数为真
    fit_prior=True,            # 是否学习先验概率
    class_prior=None           # 固定先验概率
)

model.fit(X, y)

# 关键属性
print(model.class_count_)      # 每类样本数
print(model.class_log_prior_)  # 每类的对数先验概率
print(model.classes_)          # 类别
print(model.feature_count_)    # 每类每个特征的计数 (n_classes, n_features)
print(model.feature_log_prob_) # 经验对数概率 P(x_i|y)
print(model.n_features_in_)   # 特征数
print(model.n_iter_)           # 达到精度所需的迭代次数(在线学习)

# 预测
y_pred = model.predict(X)
y_prob = model.predict_proba(X)
y_log_prob = model.predict_log_proba(X)

# 部分拟合(在线学习)
model.partial_fit(X_batch, y_batch, classes=np.unique(y))

文本分类示例:

from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.pipeline import Pipeline

pipeline = Pipeline([
    ('vect', CountVectorizer()),
    ('tfidf', TfidfTransformer()),
    ('clf', MultinomialNB())
])

pipeline.fit(texts, labels)
predicted = pipeline.predict(new_texts)

🎲 伯努利朴素贝叶斯

BernoulliNB

适用于二值/布尔特征,每个特征只有 0/1 两种取值。

from sklearn.naive_bayes import BernoulliNB

model = BernoulliNB(
    alpha=1.0,                 # 平滑参数
    force_alpha=True,
    binarize=0.0,             # 二值化阈值(小于等于=0,大于=1)
    # None=假设数据已二值化
    fit_prior=True,
    class_prior=None
)

model.fit(X, y)

# 关键属性
print(model.class_count_)
print(model.class_log_prior_)
print(model.feature_count_)    # 每类每个特征计数
print(model.feature_log_prob_) # log P(x_i|y)(含负值,不出现时的概率补项)

# 预测
y_pred = model.predict(X)
y_prob = model.predict_proba(X)

🔧 补集朴素贝叶斯

ComplementNB

多项式 NB 的改进版,对不平衡数据集效果更好。

from sklearn.naive_bayes import ComplementNB

model = ComplementNB(
    alpha=1.0,
    force_alpha=True,
    fit_prior=True,
    class_prior=None,
    norm=False               # 是否对权重做 L2 归一化
)

model.fit(X, y)

# 关键属性(与 MultinomialNB 类似但权重计算方式不同)
print(model.class_count_)
print(model.class_log_prior_)
print(model.feature_count_)
print(model.feature_log_prob_)  # 补集特征权重
print(model.feature_all_)       # 全部特征计数

# 预测
y_pred = model.predict(X)
y_prob = model.predict_proba(X)

🗂️ 分类朴素贝叶斯

CategoricalNB

适用于分类(非数值)特征,每个特征有有限个离散取值类别。

from sklearn.naive_bayes import CategoricalNB

model = CategoricalNB(
    alpha=1.0,
    force_alpha=True,
    fit_prior=True,
    class_prior=None,
    min_categories=None       # 每个特征的最小类别数
    # 或 array-like: 指定每个特征的最小类别数
)

model.fit(X, y)

# 关键属性
print(model.class_count_)
print(model.class_log_prior_)
print(model.category_count_)    # 每类每个特征每类别的计数
# 形状: (n_classes, n_features, max_category_per_feature)
print(model.feature_log_prob_)  # 对数概率
print(model.n_categories_)      # 每个特征的类别数

# 预测
y_pred = model.predict(X)
y_prob = model.predict_proba(X)

使用示例:

import numpy as np
from sklearn.naive_bayes import CategoricalNB

# 每个特征取值为 0 到 max_val 的整数
rng = np.random.RandomState(42)
X = rng.randint(5, size=(100, 3))  # 3 个特征,每个取值 0~4
y = rng.randint(2, size=100)       # 二分类

model = CategoricalNB(min_categories=[5, 5, 5])
model.fit(X, y)

📊 模型对比

模型 特征类型 典型应用 概率公式
GaussianNB 连续值 通用分类、鸢尾花 高斯似然
MultinomialNB 计数/频率 文本分类、文档 多项式似然
BernoulliNB 二值 (0/1) 短文本、出现/不出现 伯努利似然
ComplementNB 计数/频率 不平衡文本分类 补集权重
CategoricalNB 离散类别 调查数据、评级 类别概率

📝 实践指导

文本分类完整流程

from sklearn.naive_bayes import MultinomialNB, ComplementNB
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report

# 1. 文本向量化
vectorizer = TfidfVectorizer(
    max_features=5000,
    stop_words='english',
    ngram_range=(1, 2)
)
X = vectorizer.fit_transform(texts)

# 2. 分割
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# 3. 训练(比较两种 NB)
for name, model in [
    ('MultinomialNB', MultinomialNB(alpha=0.1)),
    ('ComplementNB', ComplementNB(alpha=0.1))
]:
    model.fit(X_train, y_train)
    y_pred = model.predict(X_test)
    acc = model.score(X_test, y_test)
    print(f"{name}: accuracy = {acc:.3f}")
    print(classification_report(y_test, y_pred))

增量学习(大数据/流式数据)

from sklearn.naive_bayes import GaussianNB

model = GaussianNB()
classes = np.unique(y)  # 需要提前知道所有类别

# 分批训练
batch_size = 100
for i in range(0, len(X), batch_size):
    X_batch = X[i:i+batch_size]
    y_batch = y[i:i+batch_size]

    # 第一批用 fit,后续用 partial_fit
    if i == 0:
        model.fit(X_batch, y_batch)
    else:
        model.partial_fit(X_batch, y_batch, classes=classes)

    print(f"Processed {i + len(X_batch)} / {len(X)} samples")

特征概率检查

import pandas as pd

# 查看每类最显著的特征
feature_probs = pd.DataFrame(
    model.feature_log_prob_,
    columns=feature_names  # 或 range(n_features)
)

# 对于 BernoulliNB/MultinomialNB
# 找出每类最"决定性"的特征
for i, class_name in enumerate(model.classes_):
    top_features = np.argsort(model.feature_log_prob_[i])[::-1][:10]
    print(f"\nClass {class_name}:")
    for feat_idx in top_features:
        prob = np.exp(model.feature_log_prob_[i][feat_idx])
        print(f"  P({feat_idx}|class) = {prob:.4f}")

📝 优点与局限

优点 局限
极快的训练和预测 条件独立假设(实践中常不成立)
少量训练数据也有效 概率估计通常不校准
天然处理高维数据 GaussianNB 对分布假设敏感
对无关特征鲁棒 特征尺度需合理处理
支持增量学习(partial_fit) 无法学习特征交互

[[sklearn-总览|← 返回总览]]

更多推荐