Python-sklearn-朴素贝叶斯
·
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-总览|← 返回总览]]
更多推荐



所有评论(0)