机器学习实践之垃圾邮件分类预测
前言
本文章分别使用了逻辑回归和随机森林模型进行垃圾邮件分类预测任务,提供了解决问题的思路和完整代码,如若读者发现文章不足之处可在评论区指出,如有代码看不懂的地方可以查询相关语法或者询问ai。感谢读者阅读以及批评指正
一、题目说明
1.1题目描述
在电子邮件通信中,垃圾邮件(spam)不仅占用用户的时间和存储资源,还可能带来安全隐患。因此,准确地识别和过滤垃圾邮件对于提升用户体验和保障信息安全至关重要。本次任务旨在利用多种机器学习模型对电子邮件进行垃圾邮件分类,以评估不同模型在该任务中的表现。
1.2数据集
数据集来源于kaggle数据集,附上链接
链接: 垃圾邮件数据集
1.3任务要求
- 1.数据准备:使用公开的电子邮件垃圾邮件数据集,将数据集划分为训练集(80%)和测试集(20%)。
- 2.模型训练:选择至少两种不同的机器学习模型(例如,逻辑回归、支持向量机和随机森林)进行训练。
- 3.性能评估:在测试集上评估每个模型的性能,计算并比较以下指标:准确率(Accuracy)、精确率(Precision)、召回率(Recall)和F1分数(F1 Score),绘制每个模型的ROC曲线,并计算AUC值。
- 4.结果分析:根据模型的复杂度、训练时间和性能指标,推荐最适合该任务的模型,并说明理由。
二、代码及思路
2.1数据分析和数据处理
1.首先导入必要的数据处理相关的库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings # 导入warnings模块,用于控制Python警告信息的显示
warnings.filterwarnings('ignore') # 忽略所有警告信息,避免输出过多无关警告,使结果更清晰
2.读取数据并查看前五行
df = pd.read_csv('spambase.csv')
df.head()
运行结果如下,数据集是关于邮件中一些单词的词频,和一些符号的词频,以及最后的标签是否是垃圾邮件(1为是,0则为不是):

3.提取数据特征
查看数据集形状,是一个4601行,58列的表格
df.shape

查看数据描述,能看到所有数据特征的数量,均值,标准差,最大最小值等
df.describe()


查看数据特征值的类型,发现全是数值类型,没有字符串类型,就不用进行 one-hot 编码转换了
df.dtypes

然后我们来看看特征值是否有缺失,好在这里没有缺失,如果有缺失值,我们可以直接删去对应的行或列,或者使用均值填充,前向/后向填充,众数填充都可以的
df.isnull().sum()

接下来我们来看看spam的分布,如果分布过于不平衡会导致模型的准确率下降,可以采用过采样或者欠采样的方法,这里数据分布不算特别不平衡,就不做处理
target_distribution = df['spam'].value_counts()
target_distribution
plt.rcParams['figure.facecolor'] = 'white' # 画布背景
plt.rcParams['font.sans-serif'] = ['SimHei'] # 黑体
plt.rcParams['axes.unicode_minus'] = False # 正常显示负号
#画柱状图
sns.barplot(x=target_distribution.index,y=target_distribution.values)
plt.xlabel('是否为垃圾邮件')
plt.ylabel('数量')
plt.title('spam的分布柱形图')
for i,v in enumerate(target_distribution):
plt.text(i,v+10,str(v),ha='center')
plt.show()

由于我们这里的特征非常多有58个,所以我们来绘制一个相关系数矩阵热力图,并按照相关性从高到低排序。这里因为数据量的原因,热力图过于密集不便观察,所以主要来看输出的排序吧
f,ax = plt.subplots(1,1,figsize=(10,10))
relate_num = df.corr().round(2)
spam_relate_num = relate_num['spam'].abs().sort_values(ascending=False)
print(spam_relate_num)
ax = sns.heatmap(df.corr(),annot=True,cmap='coolwarm')
plt.show()


2.2模型构建之逻辑回归
我们先使用逻辑回归模型进行预测分类,这里我们只选取了相关性较强的前十个特征,并且计算了准确率accuracy,精确率precision,召回率recall,F1分数来评估模型。同时计算逻辑回归模型的AUC值,绘制ROC曲线,更能直观的看出模型训练效果
#逻辑回归
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from sklearn.metrics import roc_curve, auc
#选取相关性较强的前十个特征
features = spam_relate_num[1:11].index
X=df[features]
y=df['spam']
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=0)
log_reg = LogisticRegression()
log_reg.fit(X_train,y_train)
y_pred = log_reg.predict(X_test)
acc = accuracy_score(y_test,y_pred)
pre = precision_score(y_test,y_pred)
recall = recall_score(y_test,y_pred)
f1 = f1_score(y_test,y_pred)
print('逻辑回归模型评估指标:')
print(f'准确率{acc:.2f}')
print(f'精确率{pre:.2f}')
print(f'召回率{recall:.2f}')
print(f'F1分数{f1:.2f}')
# 获取逻辑回归模型在测试集上的预测正类概率
y_pred_proba_log_reg = log_reg.predict_proba(X_test)[:,1]
# 计算逻辑回归模型的 fp(假阳性率)、tp(真阳性率)和阈值
fp_logreg,tp_logreg,thresholds_logreg = roc_curve(y_test,y_pred_proba_log_reg)
# 计算逻辑回归模型的 AUC 值
auc_logreg = auc(fp_logreg,tp_logreg)
# 绘制 ROC 曲线
plt.figure(figsize=(10, 8))
plt.plot(fp_logreg,tp_logreg)
plt.xlabel('假阳性率')
plt.ylabel('真阳性率')
plt.title(f'逻辑回归AUC={auc_logreg:.2f}')
plt.show()
print(f'逻辑回归模型的 AUC 值:{auc_logreg:.2f}')

提高max_iter参数值(迭代次数)可以小幅提高模型效果,同时尝试对数据进行标准化/归一化操作,也可以优化模型
#尝试数据标准化/归一化
from sklearn.preprocessing import StandardScaler
features = spam_relate_num[1:11].index
X=df[features]
y=df['spam']
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=0)
#特征归一化,transform是缩放器
X_scaler = StandardScaler()
X_train_scaler = X_scaler.fit_transform(X_train)
X_test_scaler = X_scaler.transform(X_test)
#模型训练
log_reg = LogisticRegression(max_iter=500)
log_reg.fit(X_train_scaler,y_train)
y_pred = log_reg.predict(X_test_scaler)
acc = accuracy_score(y_test,y_pred)
pre = precision_score(y_test,y_pred)
recall = recall_score(y_test,y_pred)
f1 = f1_score(y_test,y_pred)
print('标准化后的逻辑回归模型评估指标:')
print(f'准确率{acc:.2f}')
print(f'精确率{pre:.2f}')
print(f'召回率{recall:.2f}')
print(f'F1分数{f1:.2f}')

2.3模型构建之随机森林
第二个我们使用随机森林进行模型训练,并计算一系列值进行模型评估,可以明显看出比逻辑回归的训练效果好
#使用随机森林
from sklearn.ensemble import RandomForestClassifier as rfc
features = spam_relate_num[1:11].index
X=df[features]
y=df['spam']
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=0)
rf = rfc(random_state=0)
rf.fit(X_train,y_train)
y_pred = rf.predict(X_test)
acc = accuracy_score(y_test,y_pred)
pre = precision_score(y_test,y_pred)
recall = recall_score(y_test,y_pred)
f1 = f1_score(y_test,y_pred)
print('随机森林模型评估指标:')
print(f'准确率{acc:.2f}')
print(f'精确率{pre:.2f}')
print(f'召回率{recall:.2f}')
print(f'F1分数{f1:.2f}')
# 获取随机森林模型在测试集上的预测正类概率
y_pred_proba_rf = rf.predict_proba(X_test)[:,1]
# 计算逻辑回归模型的 fp(假阳性率)、tp(真阳性率)和阈值
fp_rf,tp_rf,thresholds_rf = roc_curve(y_test,y_pred_proba_rf)
# 计算逻辑回归模型的 AUC 值
auc_rfc = auc(fp_rf,tp_rf)
# 绘制 ROC 曲线
plt.figure(figsize=(10, 8))
plt.plot(fp_rf,tp_rf)
plt.xlabel('假阳性率')
plt.ylabel('真阳性率')
plt.title(f'随机森林AUC={auc_rfc:.2f}')
plt.show()
print(f'随机森林模型的 AUC 值:{auc_rfc:.2f}')

三、总结
根据acc,pre,recall,F1,AUC值以及ROC曲线可以得出结论对比逻辑回归和随机森林模型,随机森林更适合此垃圾邮件分类预测任务。当然后续大家也可以尝试与不同的模型做对比,并对数据加以其他处理,尝试找到最优模型
更多推荐


所有评论(0)