You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

sklearn MultinomialNB仅预测类先验值,自定义朴素贝叶斯对比遇阻

解决sklearn MultinomialNB仅预测类先验值的问题
  • 核心问题分析:你遇到的MultinomialNB只输出类先验(也就是全部预测多数类)的情况,大多是因为特征不符合模型假设或者数据预处理不到位导致的——毕竟MultinomialNB原本是为离散计数型特征(比如文本词频)设计的,直接套用泰坦尼克的类别特征很容易踩坑。

  • 可能的原因及对应解决方案:

    1. 特征类型不匹配
      MultinomialNB假设特征是非负整数计数(比如某个词在文本中出现的次数),而泰坦尼克的核心特征(性别、舱位、登船港口等)是类别型。如果你直接用标签编码把它们转成0、1、2这类整数,模型会错误地把这些数值当成计数,自然学不到有效区分样本的模式。
      解决方案:要么把类别特征转换成计数型表示(比如用该类别在训练集中的出现频次作为特征值),要么改用专门适配类别特征的朴素贝叶斯变种——CategoricalNB,它能更合理地处理这类数据。

    2. 缺失值未处理
      泰坦尼克数据集存在不少缺失值(比如Age、Cabin字段),如果你的X里包含未处理的缺失值,MultinomialNB要么直接报错,要么无法正常学习特征与标签的关联,最终只能退化为预测类先验。
      解决方案:先处理缺失值——数值特征用中位数/均值填充,类别特征用众数填充,或者直接删除缺失严重的特征(比如Cabin)。

    3. 特征编码/缩放错误
      如果你对特征做了标准化(比如转成0-1之间的小数),MultinomialNB会因为特征不是非负整数而无法正确计算概率,导致模型完全失效。
      解决方案:确保输入MultinomialNB的特征都是非负整数,或者根据特征类型改用GaussianNB(适合连续特征)、CategoricalNB(适合类别特征)。

    4. 特征构造不完整或无效
      你代码里的X = np.asarray(...)可能只选取了无关特征(比如PassengerId),或者特征提取逻辑有问题,导致模型无法区分存活和死亡样本。
      解决方案:检查特征集,确保包含有区分度的特征(比如Pclass、Sex、Age、Fare等),并且转换为模型可接受的格式。

  • 修正后的示例代码:
    这里用CategoricalNB适配泰坦尼克的类别特征,对比自定义朴素贝叶斯会更合理:

    import numpy as np
    import pandas as pd
    from sklearn.naive_bayes import CategoricalNB
    from sklearn.preprocessing import OrdinalEncoder
    from sklearn.model_selection import train_test_split
    
    # 读取数据
    train = pd.read_csv('data/in/train.csv')
    
    # 处理缺失值
    train['Age'].fillna(train['Age'].median(), inplace=True)
    train['Embarked'].fillna(train['Embarked'].mode()[0], inplace=True)
    
    # 选择有效特征和目标变量
    features = ['Pclass', 'Sex', 'Age', 'Embarked']
    X = train[features]
    y = train['Survived']
    
    # 对类别特征做序数编码(CategoricalNB接受整数编码的类别特征)
    encoder = OrdinalEncoder()
    X_encoded = encoder.fit_transform(X)
    
    # 划分训练集和测试集
    X_train, X_test, y_train, y_test = train_test_split(X_encoded, y, test_size=0.2, random_state=42)
    
    # 训练模型
    model = CategoricalNB()
    model.fit(X_train, y_train)
    
    # 查看预测结果(不会全是0或全是1)
    y_pred = model.predict(X_test)
    print(y_pred[:10])
    
  • 额外提示:
    如果你坚持要用MultinomialNB,可以把类别特征转换成频次编码(统计每个类别在训练集中的出现次数,用次数作为特征值),或者用one-hot编码后将特征视为计数(但会大幅增加特征维度,效果不一定理想)。另外,调整平滑参数alpha(比如MultinomialNB(alpha=0.1))也可能减少平滑对模型的影响,提升区分能力。

内容的提问来源于stack exchange,提问作者jabberwocky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:42:48