使用Enron数据集构建Python垃圾邮件过滤器时全部分类器均报错
问题根源
- 核心问题1:未做文本向量化:所有传统机器学习/深度学习模型都只能接收数值型输入,你当前直接将原始邮件文本字符串喂入模型,是触发
ValueError: Unable to convert array of bytes/strings into decimal numbers with dtype='numeric'的根本原因,reshape仅调整数组形状不会改变数据类型。 - 核心问题2:标签格式与模型输出不匹配:神经网络使用
categorical_crossentropy损失时要求标签为独热编码格式(形状为[样本数, 2]),你当前的标签是字符串形式的ham/spam,转换为数值后形状为[样本数, 1],和输出层2维的形状不匹配,因此触发形状报错。 - 额外问题:你当前代码仅读取了前10条垃圾邮件和10条正常邮件,样本量远不足以训练有效模型。
可行解决方案
步骤1:增加文本向量化与标签编码环节
使用scikit-learn的TF-IDF工具将文本转换为数值特征,同时将字符串标签编码为0/1数值:
from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.preprocessing import LabelEncoder # 初始化TF-IDF向量化器,可根据需求调整max_features限制特征维度 tfidf = TfidfVectorizer(stop_words='english', max_features=1000) # 拟合训练集文本并转换为数值特征,测试集仅做转换 x_train_tfidf = tfidf.fit_transform(x_train).toarray() x_test_tfidf = tfidf.transform(x_test).toarray() # 标签编码:ham转0,spam转1 le = LabelEncoder() y_train_encoded = le.fit_transform(y_train) y_test_encoded = le.transform(y_test)
步骤2:修正朴素贝叶斯分类器代码
注意GaussianNB适合连续型数值特征,文本分类更推荐使用多项式朴素贝叶斯MultinomialNB,修改后代码如下:
from sklearn.naive_bayes import MultinomialNB mnb = MultinomialNB() # 直接传入转换后的TF-IDF特征和编码后的标签,无需额外reshape mnb.fit(x_train_tfidf, y_train_encoded) # 测试集预测 y_pred = mnb.predict(x_test_tfidf)
如果坚持使用GaussianNB,直接替换类名即可,上一步已经将TF-IDF转为稠密数组可直接适配。
步骤3:修正神经网络代码
调整输入层形状匹配TF-IDF特征维度,修改损失函数适配整数标签:
from keras.models import Sequential from keras.layers import Dense, Input # 获取特征维度 feature_dim = x_train_tfidf.shape[1] model = Sequential() # 输入层形状匹配特征维度 model.add(Input(shape=(feature_dim,))) model.add(Dense(16, activation='relu')) model.add(Dense(12, activation='relu')) model.add(Dense(12, activation='relu')) # 二分类也可直接用1个神经元+sigmoid激活,损失用binary_crossentropy,此处保留你的2输出配置 model.add(Dense(2, activation='softmax')) # 用sparse_categorical_crossentropy无需将标签转独热编码,直接适配整数标签 model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # 传入向量化后的特征和编码后的标签 history = model.fit(x_train_tfidf, y_train_encoded, epochs=10, batch_size=64)
注意事项
- 移除读取数据时
if counter < 10的样本量限制,使用完整数据集训练才能得到可用的模型。 - 可根据实际效果调整TF-IDF的
max_features、神经网络的隐藏层维度、迭代次数等超参数。
内容的提问来源于stack exchange,提问作者user11518995
相关产品推荐
相关产品推荐

