朴素贝叶斯垃圾邮件分类词频统计报KeyError如何解决
报错根因
触发KeyError的核心原因是词汇表构建阶段的类型转换逻辑写错了:你遍历邮件收集词汇时,给每个单词套了tuple()做转换。
对字符串类型的单词调用tuple(),不会把整个单词包装成单元素元组,而是会把字符串按单个字符拆成字符元组——比如你报错里提到的单词hafta,执行tuple("hafta")得到的结果是('h', 'a', 'f', 't', 'a'),和原字符串"hafta"是完全不同的对象。
这就导致你生成的word_counts_per_email字典,所有键都是这类拆碎的字符元组,根本没有字符串形式的单词键。等到词频统计环节,你拿遍历得到的字符串类型单词去字典里查值,当然找不到对应键,直接抛出KeyError。
修复方法
删掉多余的tuple转换逻辑就行,修正后的可运行代码:
training_set['E_Mail'] = training_set['E_Mail'].str.split() vocabulary = [] for email in training_set['E_Mail']: for word in email: vocabulary.append(word) # 直接存字符串单词,不要转tuple vocabulary = list(set(vocabulary)) word_counts_per_email = {unique_word: [0] * len(training_set['E_Mail']) for unique_word in vocabulary} for index, email in enumerate(training_set['E_Mail']): for word in email: word_counts_per_email[word][index] += 1
后续排查提示
- 如果改完仍偶发键错误,先检查
training_set['E_Mail']列是否存在空值(NaN):pandas的str.split()遇到空值会返回NaN而不是单词列表,遍历到这类条目时会出现非预期的对象类型 - 做词频统计前建议加一步文本预处理:统一把单词转成小写、去除单词首尾附着的标点,避免
Hafta、hafta!和hafta被识别成三个独立单词,拉低朴素贝叶斯分类的准确率
内容的提问来源于stack exchange,提问作者Aksoy
相关产品推荐
相关产品推荐

