掘金 人工智能 05月05日 10:09
从“朴素”到“半朴素”:贝叶斯分类器的进阶之路
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文探讨了机器学习分类任务中的朴素贝叶斯和半朴素贝叶斯两种算法。朴素贝叶斯因其简单高效而广受欢迎,但“朴素”的独立性假设限制了其性能。半朴素贝叶斯通过放宽此假设,允许特征间存在依赖关系,从而在特征相关的场景下提高分类准确性。文章通过原理介绍、应用场景分析以及代码实战对比,帮助读者理解两种算法的差异与优势。

💡 朴素贝叶斯是一种基于贝叶斯定理的分类器,它假设特征之间相互独立,简化了计算。这种假设虽然简化了模型,但也限制了其在特征相关的场景下的表现。

💡 半朴素贝叶斯是朴素贝叶斯的改进,它放宽了特征独立性假设,允许部分特征之间存在依赖关系。这种改进使其能够更好地捕捉特征间的关联,从而提升分类精度。

💡 通过实战对比,文章展示了朴素贝叶斯和半朴素贝叶斯在属性存在依赖关系时的性能差异。结果表明,半朴素贝叶斯在处理相关特征时,通常能获得更高的准确率。

💡 朴素贝叶斯适用于特征独立性较强、数据量较少或对精度要求不高的场景;而半朴素贝叶斯则更适合特征存在相关性、对精度要求较高以及数据量较大的情况。

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

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

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

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

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

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

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

其中,XX是特征向量,YY是类别标签,x1,x2,,xnx_1,x_2,\ldots,x_n是各个特征。

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

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

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

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

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

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

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

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

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

3. 实战对比

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

首先,生成测试数据:

    类别Y有两种值,01类别Y决定X1的分布(Y=0时均值为0Y=1时均值为1X2依赖于X1X2 = X1 + 噪声),模拟属性间的依赖关系
import numpy as npfrom sklearn.model_selection import train_test_split# 生成模拟数据:Y影响X1和X2,且X2依赖X1np.random.seed(42)n_samples = 1000Y = 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)).TX_train, X_test, y_train, y_test = train_test_split(    X,    Y,    test_size=0.3,    random_state=42,)

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

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

from sklearn.naive_bayes import GaussianNBfrom sklearn.metrics import accuracy_scorefrom 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. 总结

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

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

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

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

朴素贝叶斯 半朴素贝叶斯 机器学习 分类算法
相关文章