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

基于PSO与ABC优化朴素贝叶斯实现垃圾邮件分类遇TypeError求助

解决PSO/ABC优化朴素贝叶斯时的TypeError问题

我帮你排查了这个报错的原因,其实问题出在对Hive库的返回值理解有误,还有几个小细节需要调整,具体如下:

错误原因分析

从报错回溯能清晰看到,问题出在Utilities.ConvergencePlot(cost)这一行:

  • 你把model.run()返回的单个成本值传给了这个函数,但ConvergencePlot需要的是包含每一轮迭代中best和mean成本序列的字典,而不是单个数值/字符串。当函数尝试用cost["best"]访问字典键时,自然就触发了TypeError: string indices must be integers。
  • 另外你的TF-IDF处理还有个小bug:email_test_tf = tf.fit_transform(email_test_dtm)是错误的,这种写法会在测试集上重新拟合TF-IDF,引入数据泄露,严重影响模型的泛化能力。

解决方法与修正代码

1. 修正ConvergencePlot的输入参数

把Utilities.ConvergencePlot(cost)改成Utilities.ConvergencePlot(model.history["cost"]),因为model.history["cost"]才是Hive库记录的、包含每轮迭代best和mean成本的字典数据。

2. 修正TF-IDF的处理流程

正确的TF-IDF处理应该先在训练集上拟合,再转换训练集和测试集:

from sklearn.feature_extraction.text import TfidfVectorizer
tf = TfidfVectorizer()
# 先在训练集上拟合,再转换训练集
email_train_tf = tf.fit_transform(email_train)
# 测试集只做转换,不拟合
email_test_tf = tf.transform(email_test)

3. 完整修正后的代码

# 数据拆分(先确保这一步是正确的)
from sklearn.model_selection import train_test_split
email_train, email_test, spam_train, spam_test = train_test_split(dfTotal.Email, dfTotal.Spam, test_size=0.3, random_state=0)

# 修正TF-IDF处理
from sklearn.feature_extraction.text import TfidfVectorizer
tf = TfidfVectorizer()
email_train_tf = tf.fit_transform(email_train)
email_test_tf = tf.transform(email_test)

# ABC算法相关代码
from Hive import Hive
from Hive import Utilities
from sklearn.metrics import log_loss
from sklearn.naive_bayes import MultinomialNB

def run(lowBounds, upBounds, evaluator):
    model = Hive.BeeHive(lower=lowBounds,
                         upper=upBounds,
                         fun=evaluator,
                         numb_bees=100,
                         max_itrs=2,)
    # run()返回的是最优成本值和最优解数组
    best_cost, sol = model.run()
    # 传入模型的历史成本数据,而不是单个best_cost
    Utilities.ConvergencePlot(model.history["cost"])
    print("Fitness Value ABC: {0}".format(best_cost))
    # 用最优解创建朴素贝叶斯模型
    ABC_model = MultinomialNB(alpha=10**sol[0]).fit(email_train_tf, spam_train)
    result = ABC_model.predict(email_test_tf)
    return sol, result

# 定义适应度函数
def evaluator(params):
    nBayes = MultinomialNB(alpha=10**params[0]).fit(email_train_tf, spam_train)
    pred_proba = nBayes.predict_proba(email_test_tf)
    return log_loss(spam_test, pred_proba)

# 调用run函数
sol, result3 = run([-2], [1], evaluator)

额外注意事项

  • 如果调整后还是有问题,可以打印model.history查看具体的键结构,不同版本的Hive库可能略有差异。
  • 确保spam_train和spam_test是数值型标签(比如0表示正常邮件,1表示垃圾邮件),log_loss要求标签必须是数值型,否则会触发其他错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 10:07:47