从“朴素”到“半朴素”:贝叶斯分类器的进阶之路

在机器学习分类任务中,朴素贝叶斯Naive Bayes)因其简单高效而广受欢迎,但它的**"朴素"**之名也暗示了其局限性。

为了突破这一局限,半朴素贝叶斯Semi-Naive Bayes) 应运而生。

本文将详细介绍朴素贝叶斯和半朴素贝叶斯的原理、应用场景以及如何使用scikit-learn库实现它们。

1. 朴素贝叶斯:简单但"天真"

朴素贝叶斯 是一种基于贝叶斯定理的简单概率分类器,它的核心思想是利用特征之间的独立性假设来简化计算。

具体来说,朴素贝叶斯假设每个特征之间是相互独立的,即给定一个类别标签,所有特征的联合概率可以分解为各个特征的条件概率的乘积。

用数学公式表示为: P(X\|Y)=P(x_1\|Y)\\times P(x_2\|Y)\\times\\cdots\\times P(x_n\|Y)

其中, X \\(是特征向量,\\) Y \\(是类别标签,\\) x_1,x_2,\\ldots,x_n 是各个特征。

朴素贝叶斯的优势在于计算高效,适合高维数据(如新闻分类)。

2. 半朴素贝叶斯:放松独立性假设

尽管朴素贝叶斯 在许多场景下表现出色,但它的一个关键假设:特征独立性,在实际应用中往往难以满足。

在现实世界中,特征之间通常存在一定的相关性。

例如,在文本分类中,某些词汇的出现可能与其他词汇的出现密切相关。

这种情况下,朴素贝叶斯的独立性假设会导致分类器的性能下降。

为了解决这一问题,半朴素贝叶斯应运而生。

半朴素贝叶斯在一定程度上放宽了特征独立性的假设,允许特征之间存在一定的相关性,从而提高分类器的性能。

半朴素贝叶斯的核心改进在于允许部分特征之间存在依赖关系,通过捕捉关键特征间的依赖,提升分类精度,同时保持计算复杂度可控。

3. 实战对比

下面构造一个简单的示例,用来对比朴素半朴素贝叶斯的在属性存在依赖关系时的准确率。

首先,生成测试数据:

  1. 类别Y有两种值,01
  2. 类别Y决定X1的分布(Y=0时均值为0Y=1时均值为1
  3. X2依赖于X1X2 = X1 + 噪声),模拟属性间的依赖关系
python 复制代码
import numpy as np
from sklearn.model_selection import train_test_split

# 生成模拟数据:Y影响X1和X2,且X2依赖X1
np.random.seed(42)
n_samples = 1000
Y = np.random.randint(0, 2, n_samples)
X1 = np.zeros(n_samples)
X2 = np.zeros(n_samples)
 
for i in range(n_samples):
    if Y[i] == 0:
        x1 = np.random.normal(0, 1)
        x2 = x1 + np.random.normal(0, 0.5)  # X2依赖X1
    else:
        x1 = np.random.normal(1, 1)
        x2 = x1 + np.random.normal(0, 0.5)  # X2依赖X1
    X1[i] = x1
    X2[i] = x2
 
X = np.vstack((X1, X2)).T
X_train, X_test, y_train, y_test = train_test_split(
    X,
    Y,
    test_size=0.3,
    random_state=42,
)

然后分别使用朴素和半朴素贝叶斯模型来训练数据,看看各自的准确率。

注意,scikit-learn没有直接提供半朴素贝叶斯的实现,下面的示例中通过手动计算特征之间的相关性来改进朴素贝叶斯模型。

python 复制代码
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LinearRegression

# 朴素贝叶斯(假设属性独立)
nb = GaussianNB()
nb.fit(X_train, y_train)
y_pred_nb = nb.predict(X_test)
acc_nb = accuracy_score(y_test, y_pred_nb)

# 半朴素贝叶斯(手动实现,假设X2依赖X1)
# 训练阶段:估计每个类别的参数
def train_semi_naive_bayes(X, y):
    params = {}
    for cls in [0, 1]:
        X_cls = X[y == cls]
        X1_cls = X_cls[:, 0]
        X2_cls = X_cls[:, 1]

        # 估计P(X1|Y)的参数(高斯分布)
        mu_X1 = np.mean(X1_cls)
        sigma_X1 = np.std(X1_cls)

        # 估计P(X2|Y,X1)的参数(线性回归)
        lr = LinearRegression().fit(X1_cls.reshape(-1, 1), X2_cls)
        a, b = lr.coef_[0], lr.intercept_
        residuals = X2_cls - lr.predict(X1_cls.reshape(-1, 1))
        sigma_X2_given_X1 = np.std(residuals)

        params[cls] = {
            "prior": np.sum(y == cls) / len(y),
            "mu_X1": mu_X1,
            "sigma_X1": sigma_X1,
            "a": a,
            "b": b,
            "sigma_X2_given_X1": sigma_X2_given_X1,
        }
    return params


# 预测阶段:计算对数概率
def predict_semi_naive_bayes(X, params):
    y_pred = []
    for x1, x2 in X:
        log_prob = {0: 0, 1: 0}
        for cls in [0, 1]:
            p = params[cls]
            # 计算P(Y)
            log_prob[cls] += np.log(p["prior"])
            # 计算P(X1|Y)
            log_prob[cls] += -0.5 * np.log(2 * np.pi * p["sigma_X1"] ** 2) - (
                x1 - p["mu_X1"]
            ) ** 2 / (2 * p["sigma_X1"] ** 2)
            # 计算P(X2|Y,X1)
            mu_x2 = p["a"] * x1 + p["b"]
            log_prob[cls] += -0.5 * np.log(2 * np.pi * p["sigma_X2_given_X1"] ** 2) - (
                x2 - mu_x2
            ) ** 2 / (2 * p["sigma_X2_given_X1"] ** 2)
        y_pred.append(0 if log_prob[0] > log_prob[1] else 1)
    return np.array(y_pred)


params = train_semi_naive_bayes(X_train, y_train)
y_pred_semi = predict_semi_naive_bayes(X_test, params)
acc_semi = accuracy_score(y_test, y_pred_semi)

# 输出结果
print(f"朴素贝叶斯准确率: {acc_nb:.4f}")
print(f"半朴素贝叶斯准确率: {acc_semi:.4f}")

## 输出结果:
'''
朴素贝叶斯准确率: 0.6333
半朴素贝叶斯准确率: 0.7000
'''

朴素贝叶斯 因假设属性独立,在X1X2存在依赖时性能略有下降。

半朴素贝叶斯 通过显式建模X2X1的依赖,更准确地估计联合概率,从而获得更高的准确率。

此示例简单展示了半朴素贝叶斯在属性存在依赖关系时的优势。

4. 总结

朴素贝叶斯半朴素贝叶斯都是基于贝叶斯定理的分类算法。

其中,朴素贝叶斯假设特征之间相互独立,适用于特征独立性较强的场景,比如:

  • 特征独立性较强:当特征之间确实相互独立时,朴素贝叶斯能够发挥其优势。例如,在垃圾邮件分类中,邮件中的词汇通常可以被视为独立的特征。
  • 数据量较少:由于朴素贝叶斯的计算复杂度较低,它在数据量较少的情况下也能快速训练模型。
  • 对分类精度要求不高:在一些对分类精度要求不高的场景中,朴素贝叶斯可以作为一种快速且有效的解决方案。

半朴素贝叶斯在一定程度上放宽了这一假设,适用于特征存在相关性的场景,比如:

  • 特征存在相关性:当特征之间存在一定的相关性时,半朴素贝叶斯可以更好地捕捉这些关系,从而提高分类性能。例如,在医学诊断中,某些症状之间可能存在关联。
  • 对分类精度要求较高:在需要高精度分类的场景中,半朴素贝叶斯可以通过考虑特征之间的相关性来提升性能。
  • 数据量较大:当有足够的数据来估计特征之间的相关性时,半朴素贝叶斯能够更好地发挥其优势。
相关推荐
结冰架构4 小时前
【AI提示词】成本效益分析师
大数据·人工智能·ai·信息可视化·提示词
ahe1689 小时前
使用DeepSeek、MCP和AKShare实现智能金融问答系统技术方案
人工智能·ai·金融·股票
奇墨 ITQM19 小时前
【QinAgent应用案例】从开发到管理,QinAgent为某智能家居企业提效50%,降本20%
人工智能·ai·云原生·智能家居
R²AIN SUITE1 天前
万物皆可执行:多功能机器人正在定义新生产力法则
人工智能·ai·机器人
wang_yb1 天前
极大似然估计:频率学派与贝叶斯学派的碰撞与融合
ai·databook
無炆_1 天前
Cline原理分析-prompt
linux·ai·prompt
豌豆花下猫2 天前
Python 潮流周刊#100:有了 f-string,为什么还要 t-string?(摘要)
后端·python·ai
智哪儿2 天前
AI重构家居营销新范式:DeepSeek如何破解行业流量与转化困局?
ai·智能家居
AI大模型学习原理2 天前
当excel接入DeepSeek后,直接自动生成PPT分析报告
人工智能·ai·云计算·powerpoint·excel·产品经理·aws