本文深入探讨朴素贝叶斯算法的数学理论基础,并重点分析其在处理混合数据类型中的应用。通过投票集成和堆叠集成方法,构建了一个能够有效处理包含二元、类别、多项式和高斯分布特征的综合分类框架。实验基于电信客户流失数据集,验证了该方法在多样化数据环境中的有效性。

朴素贝叶斯算法作为经典的生成式机器学习算法,在分类任务中具有重要地位。现实世界的数据集往往包含多种数据类型,如何有效整合这些异构特征进行准确分类是一个重要的研究课题。本文提出基于集成学习的解决方案,通过投票机制和堆叠方法处理混合数据类型,为实际应用提供理论指导和技术实现。

朴素贝叶斯算法的理论基础

算法概述

朴素贝叶斯是一种基于贝叶斯定理的生成式学习算法,专门用于解决分类问题。该算法的核心在于朴素贝叶斯假设,即条件独立性假设:给定类别标签的情况下,所有输入特征相互独立。

以动物分类任务为例,假设我们需要分类的动物集合为

{大象, 狗, 猫}

,输入特征包括

weight

height

。朴素贝叶斯假设认为,在预测动物类别时,体重特征和身高特征是条件独立的。具体而言,当模型计算某动物因体重为10磅而被分类为猫的条件概率 P(weight = 10 pounds | class = 'cat') = 0.9 时,这个概率值不会因身高特征(如2英尺)的变化而改变。

虽然该假设在现实中往往不成立,但它显著简化了计算复杂度,使得算法在数据稀疏的情况下仍能保持良好性能。这与需要估计协方差矩阵的二次判别分析(QDA)等算法形成鲜明对比。

数学理论框架

目标函数定义

朴素贝叶斯的核心目标是寻找具有最大后验概率的类别标签。给定输入向量 x 和候选类别集合,算法寻求最优分类决策:

贝叶斯定理的应用

为计算后验概率 P(y|x),朴素贝叶斯运用贝叶斯定理,将其分解为先验概率和似然函数的乘积:

其中,分母 P(x) 表示特征的边际概率。在二元分类场景中,该概率可表示为:

由于 P(x) 对所有候选类别而言都是常数,因此在最终的分类决策中可以忽略,这进一步简化了计算过程。

条件独立性假设的数学意义

朴素贝叶斯假设的核心价值在于显著降低计算复杂度。在没有独立性假设的情况下,条件概率 P(x|y) 需要通过乘法法则展开:

其中 n 表示输入特征的维数。

这种展开方式带来的计算复杂度是指数级的。以二元分类为例,所需计算的依赖关系数量随特征数量呈指数增长:当 n=10 时,需要计算约 2,046 个依赖关系;当 n=20 时,这个数字达到约 200 万;当 n=30 时,则超过 20 亿。

朴素贝叶斯假设通过消除特征间的条件依赖关系,将复杂的多元条件概率简化为一元条件概率的乘积:

因此,最终的目标函数可以表示为:

参数估计方法

最大似然估计

朴素贝叶斯分类器采用最大似然估计(MLE)方法确定最优参数。MLE 的目标是寻找能够最大化似然函数的参数集合 Θ。

为提高数值计算的稳定性,通常对似然函数取对数,将乘积运算转换为求和运算:

其中 Θ 表示完整的参数集合,L(Θ) 表示似然函数。

预测决策规则

在学习得到最优参数 Θ* 后,模型通过寻找最大化后验概率的类别标签进行预测:

这里需要注意几个重要的符号变化:

  • ŷ(x;Θ) 表示预测函数,它以新的输入向量 x 和学习得到的参数 Θ 为输入
  • P(y|x,Θ) 表示给定输入 x 和学习参数 Θ 时类别 y 的后验概率
  • P(y|Θ*) 表示基于学习参数的类别先验概率估计
  • P(xⱼ|y,Θ*) 表示给定类别 y 时特征 xⱼ 的条件概率估计

混合数据类型处理方法

现实世界的数据集通常包含多种数据类型,包括二元特征、类别特征、连续数值特征等。不同类型的特征具有不同的概率分布特性,需要采用相应的朴素贝叶斯变体进行处理。

本文采用来自 UC Irvine 机器学习存储库的伊朗客户流失数据集进行验证。该数据集包含 3,500 个样本和 14 个特征,是一个典型的二元分类任务(流失预测)。

数据集特征分布如下:

朴素贝叶斯算法假设条件概率 P(x|y) 遵循特定的预定义分布:

如果假设的分布不能准确反映真实的数据分布,则估计的概率将出现偏差。因此,本文采用以下系统性方法:

  1. 基于条件数据分布特性对输入特征进行分类
  2. 针对不同特征类型准备相应的数据预处理流程
  3. 构建多个专门化的朴素贝叶斯分类器
  4. 采用集成学习方法整合多个分类器
  5. 对最终结果进行综合评估

特征分类分析

分布分析方法

本文通过生成分位数-分位数(QQ)图来分析各特征在不同类别条件下的分布特性。QQ 图将实际数据分布与理论正态分布进行比较,帮助识别最适合的概率分布模型。

分析结果将特征分为四个主要类别:

二元特征

识别出的二元特征包括:

complains

tariff_plan

status

这些特征表现出明显的二元分布特性,适合使用伯努利朴素贝叶斯(BernoulliNB)处理。

类别特征

识别出的类别特征:

age_group

该特征具有有序类别的特性,适合使用类别朴素贝叶斯(CategoricalNB)处理。

多项式特征

识别出的多项式特征包括:

age

charge_amount

这些特征呈现离散计数分布特性,适合使用多项式朴素贝叶斯(MultinomialNB)处理。

高斯特征

识别出的高斯特征包括:

call_failure

subscription_length

seconds_of_use

frequency_of_use

frequency_of_sms

distinct_called_numbers

customer_value

这些特征近似服从正态分布,适合使用高斯朴素贝叶斯(GaussianNB)处理。

实验实现

数据预处理

数据加载与分割

 importos  
importpandasaspd  
fromsklearn.model_selectionimporttrain_test_split  
fromsklearn.composeimportColumnTransformer  
fromcollectionsimportCounter  
fromimblearn.over_samplingimportSMOTE  

# 数据集加载
current_dir=  os.getcwd()  
parent_dir=os.path.dirname(current_dir)  
csv_file_path=f'{parent_dir}/_datasets/{file_name}'  
df=pd.read_csv(csv_file_path)  

# 特征与目标变量分离
target_col='churn'  
X=df.drop(target_col, axis=1)  
y=df[target_col]  
X_train, X_test, y_train, y_test=train_test_split(  
  X, y, test_size=0.2, random_state=42  
)  

# 使用SMOTE处理类别不平衡问题
minority_class=y_train.value_counts().idxmin()  
minority_df=y_train[y_train==minority_class]  
majority_class=y_train.value_counts().idxmax()  
majority_df=y_train[y_train==majority_class]  

smote_target=min(len(minority_df) *3, len(majority_df))  
sampling_strategies= {   
   majority_class: max(len(majority_df), smote_target),   
   minority_class: smote_target   
}  
smote_train=SMOTE(sampling_strategy=sampling_strategies, random_state=42)   
X_train, y_train=smote_train.fit_resample(X_train, y_train)  

 print(Counter(y_train))

处理结果显示:SMOTE前类别分布为 Counter({0: 2135, 1: 385}),SMOTE后为 Counter({0: 2135, 1: 1155}),有效改善了类别不平衡问题。

专门化分类器构建

针对不同数据类型构建相应的处理流水线:

 fromsklearn.naive_bayesimportMultinomialNB, BernoulliNB, GaussianNB, CategoricalNB  
fromsklearn.preprocessingimportMinMaxScaler, OneHotEncoder, OrdinalEncoder  
fromsklearn.composeimportColumnTransformer  
fromsklearn.pipelineimportPipeline  

# 二元特征处理流水线
binary_features= ['complains', 'tariff_plan', 'status']  
bnb=Pipeline([  
    ('preprocessor', ColumnTransformer([  
        ('passthrough', 'passthrough', binary_features)], remainder='drop')  
    ),  
    ('classifier', BernoulliNB())  
])  

# 类别特征处理流水线
categorical_features= ['age_group',]  
catnb=Pipeline([  
     ('preprocessor', ColumnTransformer([  
        ('ordinal_encoder',   
        OrdinalEncoder(handle_unknown='use_encoded_value', unknown_value=-1),   
        categorical_features)],   
        remainder='drop')  
    ),  
    ('classifier', CategoricalNB())  
])  

# 多项式特征处理流水线
multinomial_features= ['age', 'charge_amount']  
mnb=Pipeline([  
    ('preprocessor', ColumnTransformer([  
        ('onehot', OneHotEncoder(handle_unknown='ignore'),   
        multinomial_features)],  
        remainder='drop')  
    ),  
    ('classifier', MultinomialNB())  
])  

# 高斯特征处理流水线
continuous_features= [  
    'call_failure',  
    'subscription_length',  
    'seconds_of_use',  
    'frequency_of_use',  
    'frequency_of_sms',  
    'distinct_called_numbers',  
    'customer_value'  
]  
gnb=Pipeline([  
    ('preprocessor', ColumnTransformer([  
        ('scaler', MinMaxScaler(), continuous_features)], remainder='drop')  
    ),  
    ('classifier', GaussianNB())  
 ])

集成学习实现

投票集成方法

 fromsklearn.ensembleimportVotingClassifier  

voting_classifier=VotingClassifier(  
    estimators=[  
        ('gnb', gnb),  
        ('bnb', bnb),  
        ('mnb', mnb),  
        ('cnb', catnb)  
    ],  
    voting='soft',  # 软投票:基于概率平均
    weights=[1, 1, 1, 1]  # 等权重设置
 ).fit(X_train, y_train)

堆叠集成方法

 importnumpyasnp  
fromsklearn.linear_modelimportLogisticRegression   

X_meta_train=np.hstack(  
  (prob_train_bnb, prob_train_catnb, prob_train_mnb, prob_train_gnb)  
)  

meta_learner=LogisticRegression(  # 逻辑回归作为元学习器
    random_state=42,  
    solver='liblinear',  
    multi_class='auto'  
 ).fit(X_meta_train, y_train)  # 基于组合特征训练元模型

模型预测与评估

 y_pred_voting=voting_classifier.predict(X_test)  
 
 X_meta_test=np.hstack((prob_test_bnb, prob_test_catnb, prob_test_mnb, prob_test_gnb))  
 y_pred_stacking=meta_learner.predict(X_meta_test)

实验结果与分析

集成模型性能

堆叠集成模型在测试集上达到了 81.6% 的准确率和 53.6% 的 F1 分数。该结果表明模型在多数类预测方面表现良好,但在少数类(类别1)的精确率方面仍有改进空间。

具体性能指标如下:

  • 训练集准确率:0.8103
  • 测试集准确率:0.8159
  • 训练集F1分数:0.7239
  • 测试集F1分数:0.5360

上图展示了ROC曲线和精确率-召回率曲线的比较结果,其中天蓝色线表示堆叠方法,深蓝色线表示投票方法。

单一模型性能对比

各个朴素贝叶斯变体的性能表现存在显著差异:

  • BernoulliNB(仅处理二元特征)表现最优,准确率达到 0.875
  • CategoricalNBMultinomialNB 的准确率均为 0.825,性能相当
  • GaussianNB(仅处理连续特征)表现不佳,准确率仅为 0.614

这一结果表明,对于当前数据集而言,二元特征蕴含了最具判别性的信息。GaussianNB 性能不佳的原因可能包括:数据集中的噪声影响、特征分布偏离高斯假设,以及多种数据类型混合带来的复杂性。

总结

本文提出了一种系统性的方法,通过专门化流水线和集成学习技术,有效解决了朴素贝叶斯算法在处理混合数据类型时面临的挑战。该方法的主要贡献包括:

  1. 建立了基于数据分布特性的特征分类框架
  2. 构建了针对不同数据类型的专门化处理流水线
  3. 验证了集成学习在提升混合数据分类性能方面的有效性

虽然本文提出的方法具有一定的有效性,但仍存在以下局限性:

  1. 特征分类过程需要领域专家的参与,自动化程度有限
  2. 集成方法增加了模型的复杂性和计算开销
  3. 在极度不平衡的数据集上,性能提升仍有限

除投票法和堆叠法外,处理混合数据类型还可以考虑以下方法:

特征工程方法:这仍然是数据科学的基础技术。通过领域专业知识,可以将原始特征转换为更加统一且信息丰富的表示形式,使单一模型能够更好地处理多样化的输入。

深度学习架构:多模态神经网络为处理异构数据提供了新的解决方案。这类网络通过设计独立的输入层来同时处理各种数据类型,能够自动学习不同模态之间的复杂关系。

基于树的集成方法:梯度提升机(GBM)、随机森林等算法天然具备处理混合数据类型的能力,无需进行独热编码或数值缩放等显式预处理步骤。对于高度复杂的数据集,图神经网络(GNN)也展现出了巨大的潜力。

每种方法都有其独特的优势和适用场景。最佳选择通常取决于具体的数据集特征、可用的计算资源以及预期的性能目标。随着机器学习技术的不断发展,混合数据类型的处理方法将更加多样化和智能化。

https://avoid.overfit.cn/post/13c6dffdab224bf9a631730f465c9c1e

作者:Kuriko IWAI


deephub
125 声望111 粉丝