机器学习实战|基于随机森林的垃圾邮件识别

摘要

随着互联网通信的普及,垃圾邮件已成为网络安全与用户效率的主要威胁。本文基于UCI Spambase公开数据集,采用集成学习算法随机森林实现垃圾邮件的自动化识别。文章完整覆盖数据集解析、随机森林原理、sklearn API参数详解、代码逐行注释、模型训练评估、结果可视化、特征重要性分析、模型调参优化全流程,配套可直接运行的Python代码与详细实验结果分析。实验最终在测试集取得94%准确率,训练集准确率近100%,验证了随机森林在垃圾邮件分类任务中的优异性能。本文适合机器学习初学者、数据挖掘从业者参考学习。


前言

1.1 垃圾邮件的危害与识别需求

电子邮件作为现代通信核心工具,被广泛应用于个人、企业与政务场景。与此同时,垃圾邮件(Spam)充斥邮箱,主要包含广告推广、诈骗信息、恶意链接、病毒文件等,不仅占用存储空间、浪费用户时间,还可能引发隐私泄露、财产损失等安全问题。

传统垃圾邮件过滤方式多依赖关键词匹配、规则黑名单,难以应对垃圾邮件的变种与伪装,泛化能力极差。而机器学习分类算法可从邮件文本特征中自动学习规律,实现高效、精准、自适应的垃圾邮件识别,成为当前主流解决方案。

1.2 算法选型:为何选择随机森林?

垃圾邮件识别属于二分类任务(垃圾邮件/正常邮件),常见算法有逻辑回归、朴素贝叶斯、决策树、SVM、随机森林等。本文选择随机森林的核心原因:

  1. 抗过拟合能力强:通过集成多棵决策树+双重随机采样,有效降低单棵决策树的过拟合风险;
  2. 鲁棒性优异:对噪声数据、异常值不敏感,适配邮件特征的复杂分布;
  3. 可解释性强:可输出特征重要性,明确哪些词汇/字符是判断垃圾邮件的关键;
  4. 训练效率高:支持并行训练(n_jobs参数),适配中等规模数据集;
  5. 无需复杂特征预处理:对特征尺度无严格要求,无需标准化/归一化。

1.3 项目整体流程

本文项目流程如下:

数据集加载

数据探索与特征解析

训练集/测试集划分

随机森林模型构建

模型训练与预测

模型评估:精确率/召回率/F1/混淆矩阵

特征重要性可视化

模型调参与优化

结论与应用展望


第1章 Spambase数据集深度解析

1.1 数据集基本信息

本文使用spambase.csv数据集,是机器学习领域垃圾邮件识别的经典基准数据集,由惠普实验室收集整理,公开于UCI机器学习仓库。

  • 样本总量:4597条电子邮件记录;
  • 任务类型:二分类任务(标签1=垃圾邮件,标签0=正常邮件);
  • 特征总数:57维特征(无缺失值,全为数值型特征,无需文本预处理);
  • 数据格式:CSV格式,可直接用Pandas读取。

1.2 特征详细定义(严格对照官方说明)

数据集所有特征均为邮件内容的统计特征,无原始文本,分为三大类:

1.2.1 词频特征(48维,word_freq_前缀)

格式:word_freq_单词 = 邮件中该单词出现的百分比
计算公式:100 * (该单词出现次数) / 邮件总单词数
单词定义:由非字母数字字符分隔的字母数字字符串。
包含特征示例:word_freq_makeword_freq_addressword_freq_freeword_freq_money等。

1.2.2 字符频率特征(6维,char_freq_前缀)

格式:char_freq_字符 = 邮件中该字符出现的百分比
计算公式:100 * (该字符出现次数) / 邮件总字符数

1.2.3 大写字母序列特征(3维)
  1. Capital_run_length_average:连续大写字母序列的平均长度
  2. Capital_run_length_longest:连续大写字母序列的最大长度
  3. Capital_run_length_total:邮件中大写字母总数
1.2.4 标签列(label)
  • 1:垃圾邮件(Spam);
  • 0:正常邮件(Ham)。

1.3 数据集优势

  1. 全数值特征:无需做文本分词、向量化、停用词过滤等预处理,直接用于模型训练;
  2. 无缺失值:无需填充/删除缺失数据,降低数据预处理成本;
  3. 特征针对性强:特征均为垃圾邮件的典型标识(如free、money、大写字母滥用),符合业务逻辑。

第2章 随机森林核心原理与sklearn API全解

2.1 基础概念:决策树与集成学习

2.1.1 决策树

决策树是树形分类模型,通过特征递归划分构建决策规则,优点是可解释性强、训练快;缺点是极易过拟合,对训练数据噪声敏感。

2.1.2 集成学习(Bagging)

集成学习的核心思想:多个弱学习器组合成强学习器,提升泛化能力。
随机森林基于Bagging(自助采样法) 实现:

  1. 从训练集中有放回随机采样,生成多组不同子集;
  2. 每组子集训练一棵独立决策树;
  3. 分类任务:多数投票决定最终结果;回归任务:平均值作为输出。

2.2 随机森林的两大核心随机性(算法精髓)

随机森林通过双重随机保证模型多样性,避免过拟合:

  1. 样本随机:Bootstrap有放回采样,每棵树使用不同样本集;
  2. 特征随机:每棵树分裂时,仅随机选择部分特征寻找最优划分点。

2.3 sklearn RandomForestClassifier API 全参数详解

本文严格对照官方API文档,对核心参数做逐行解释:

class sklearn.ensemble.RandomForestClassifier(
    n_estimators='warn', 
    criterion='gini', 
    max_depth=None, 
    min_samples_split=2, 
    min_samples_leaf=1, 
    min_weight_fraction_leaf=0.0, 
    max_features='auto', 
    max_leaf_nodes=None, 
    min_impurity_decrease=0.0, 
    min_impurity_split=None, 
    bootstrap=True, 
    oob_score=False, 
    n_jobs=None, 
    random_state=None, 
    verbose=0, 
    warm_start=False, 
    class_weight=None
)
2.3.1 随机森林独有参数
  1. n_estimators:森林中决策树的数量

    • 0.20版本默认10,0.22+版本默认100;
    • 树越多,模型越稳定,但训练时间线性增加;
    • 本文设置:100(平衡性能与速度)。
  2. max_features:单棵树分裂时可用的最大特征数

    • auto/sqrt:特征数平方根;log2:log2(特征数);None:使用全部特征;
    • 本文设置:0.8(使用80%特征,保证多样性)。
  3. bootstrap:是否启用有放回采样,默认True(必须开启,保证随机性)。

  4. oob_score:是否使用袋外数据评估模型,默认False,开启可无需测试集快速评估。

2.3.2 决策树通用参数(控制过拟合)
  1. max_depth:决策树最大深度

    • 默认None(无限制);数据量大/特征多时,建议设10~100,防止过拟合。
  2. min_samples_split:节点继续分裂所需最小样本数,默认2;样本量大时建议增大。

  3. min_samples_leaf:叶子节点最小样本数,默认1;小于该值则剪枝,是防过拟合核心参数。

  4. criterion:节点分裂准则,默认gini(基尼系数),可选entropy(信息增益)。

  5. max_leaf_nodes:最大叶子节点数,限制树复杂度,防止过拟合。

2.3.3 训练效率参数
  • n_jobs:并行训练线程数;-1=使用所有CPU核心,大幅加速训练。
  • random_state:随机种子,保证实验可复现。

2.4 随机森林工作流程

  1. 对原始训练集做Bootstrap采样,生成N个样本子集;
  2. 每个子集训练一棵决策树,分裂时随机选择部分特征
  3. 预测时,所有决策树输出结果,多数投票得到最终分类结果。

第3章 实验环境搭建

3.1 开发环境

  • Python 3.7+
  • 编辑器:PyCharm/Jupyter Notebook
  • 核心依赖库:
    pip install pandas scikit-learn matplotlib
    

3.2 库功能说明

  1. pandas:数据读取、数据处理、特征重要性排序;
  2. scikit-learn:随机森林模型、数据集划分、模型评估指标;
  3. matplotlib:混淆矩阵、特征重要性可视化。

第4章 代码逐行精讲

4.1 完整代码

# 垃圾邮件识别:基于随机森林的二分类模型
import pandas as pd
# 可视化混淆矩阵
def cm_plot(y,yp):
    from sklearn.metrics import confusion_matrix
    import matplotlib.pyplot as plt
    
    cm = confusion_matrix(y, yp)
    plt.matshow(cm, cmap=plt.cm.Blues)
    plt.colorbar()
    for x in range(len(cm)):
        for y in range(len(cm)):
            plt.annotate(cm[x,y],xy=(y,x),horizontalalignment='center',
                         verticalalignment='center')
            plt.ylabel('True label')
            plt.xlabel('Predicted label')
    return plt

"""
数据读取与划分
"""
df = pd.read_csv('spambase.csv')

from sklearn.model_selection import train_test_split
# 数据划分:X=特征(删除标签列),y=标签
X = df.iloc[:,:-1]   
y = df.iloc[:,-1]   

# 划分训练集(80%)、测试集(20%),随机种子保证可复现
xtrain, xtest, ytrain, ytest = train_test_split(
    X, y, test_size=0.2, random_state=100
)

# 随机森林模型构建与训练
from sklearn.ensemble import RandomForestClassifier

rf = RandomForestClassifier(
    n_estimators=100,      # 决策树数量
    max_features=0.8,     # 每棵树使用80%特征
    random_state=0        # 随机种子
)
rf.fit(xtrain, ytrain)    # 模型训练

"""
训练集评估:自测(验证模型拟合能力)
"""
train_predicted = rf.predict(xtrain)
from sklearn import metrics
# 输出分类报告:精确率、召回率、F1、支持数
print("========== 训练集分类报告 ==========")
print(metrics.classification_report(ytrain, train_predicted,digits=9))
# 混淆矩阵可视化
cm_plot(ytrain, train_predicted).show() 

"""
测试集评估:泛化能力验证
"""
test_predicted = rf.predict(xtest)
print("========== 测试集分类报告 ==========")
print(metrics.classification_report(ytest, test_predicted))
cm_plot(ytest, test_predicted).show() 

"""
特征重要性排名与可视化
"""
import matplotlib.pyplot as plt
# 获取特征重要性
importances = rf.feature_importances_
im = pd.DataFrame(importances,columns=["importances"])
# 匹配特征名称
clos = df.columns
clos_1 = clos.values
clos_2 = clos_1.tolist()
clos = clos_2[0:-1]
im['clos'] = clos

# 按重要性降序排序,取Top10
im = im.sort_values(by=['importances'], ascending=False)[:10]

# 水平条形图可视化
index = range(len(im))
plt.yticks(index, im.clos)
plt.barh(index, im['importances'])
plt.title("Top10 特征重要性")
plt.show()

4.2 代码模块逐行解析

4.2.1 混淆矩阵可视化函数(cm_plot)
def cm_plot(y,yp):
    from sklearn.metrics import confusion_matrix
    import matplotlib.pyplot as plt
    
    cm = confusion_matrix(y, yp)  # 计算混淆矩阵
    plt.matshow(cm, cmap=plt.cm.Blues)  # 热力图绘制
    plt.colorbar()  # 颜色条
    # 标注矩阵数值
    for x in range(len(cm)):
        for y in range(len(cm)):
            plt.annotate(cm[x,y],xy=(y,x),horizontalalignment='center',
                         verticalalignment='center')
            plt.ylabel('True label')  # 真实标签
            plt.xlabel('Predicted label')  # 预测标签
    return plt
  • 功能:将混淆矩阵以热力图形式展示,直观查看分类对错分布;
  • 输入:真实标签y、预测标签yp;
  • 输出:带数值标注的混淆矩阵热力图。
4.2.2 数据读取与划分
df = pd.read_csv('spambase.csv')
X = df.iloc[:,:-1]  # 所有行,除最后一列(特征)
y = df.iloc[:,-1]   # 所有行,最后一列(标签)
xtrain, xtest, ytrain, ytest = train_test_split(
    X, y, test_size=0.2, random_state=100
)
  • iloc[:,:-1]:Pandas按位置索引,提取所有特征;
  • train_test_split:按8:2划分训练集与测试集;
  • random_state=100:固定随机划分结果,保证实验可复现。
4.2.3 随机森林模型初始化
rf = RandomForestClassifier(
    n_estimators=100,
    max_features=0.8,
    random_state=0
)
rf.fit(xtrain, ytrain)
  • n_estimators=100:100棵决策树,平衡精度与速度;
  • max_features=0.8:每棵树随机用80%特征,保证模型多样性;
  • fit():在训练集上训练模型。
4.2.4 模型评估模块
  1. 训练集评估:用训练数据自测,验证模型拟合能力
  2. 测试集评估:用 unseen 数据测试,验证泛化能力
  3. classification_report:输出四大核心指标:
    • 精确率(Precision):预测为正的样本中,真实为正的比例;
    • 召回率(Recall):真实为正的样本中,被预测为正的比例;
    • F1分数:精确率与召回率的调和平均,均衡衡量模型;
    • support:各类别样本数量。
4.2.5 特征重要性可视化
importances = rf.feature_importances_  # 提取特征重要性
im = pd.DataFrame(importances,columns=["importances"])
im['clos'] = df.columns[:-1]  # 匹配特征名
im = im.sort_values(by='importances', ascending=False)[:10]  # Top10
plt.barh(index, im['importances'])  # 水平条形图
  • feature_importances_:随机森林自带属性,衡量特征对分类的贡献度;
  • 排序后取Top10,直观展示垃圾邮件识别的关键特征

第5章 实验结果深度分析

5.1 模型输出结果(原文复现)

5.1.1 训练集评估结果
              precision    recall  f1-score   support

           0  1.000000000 0.999109528 0.999554566      2246
           1  0.998604327 1.000000000 0.999301676      1431

    accuracy                      0.999456078      3677
   macro avg  0.999302163 0.999554764 0.999428121      3677
weighted avg  0.999456837 0.999456078 0.999456147      3677
训练集混淆矩阵可视化

在这里插入图片描述

*图1 训练集混淆矩阵热力图:蓝色深浅代表样本数量,对角线为正确分类样本

5.1.2 测试集评估结果
              precision    recall  f1-score   support

           0       0.94      0.96      0.95       539
           1       0.94      0.92      0.93       381

    accuracy                           0.94       920
   macro avg       0.94      0.94      0.94       920
weighted avg       0.94      0.94      0.94       920
测试集混淆矩阵可视化

在这里插入图片描述

图2 测试集混淆矩阵热力图:少量错分样本,整体分类效果优异

5.2 结果详细解读

5.2.1 训练集结果:完美拟合
  • 准确率:99.95%,精确率、召回率、F1均接近100%;
  • 说明:模型完全学习到训练集规律,无欠拟合现象。
5.2.2 测试集结果:优异泛化能力
  • 准确率:94%,在垃圾邮件识别任务中属于优秀水平
  • 类别0(正常邮件):精确率0.94,召回率0.96,误判率极低
  • 类别1(垃圾邮件):精确率0.94,召回率0.92,有效识别绝大多数垃圾邮件;
  • 结论:模型泛化能力优秀,可直接用于实际邮件过滤场景。
5.2.3 混淆矩阵可视化解读
  1. 训练集混淆矩阵:几乎无错分样本,对角线数值极高;
  2. 测试集混淆矩阵
    • 真实0预测0:539中正确517左右,少量误判为垃圾邮件;
    • 真实1预测1:381中正确350左右,少量漏判;
    • 符合业务需求:正常邮件误判(假阳性)远少于垃圾邮件漏判(假阴性)。

5.3 特征重要性Top10 分析

Top10特征重要性可视化

在这里插入图片描述

图3 垃圾邮件识别Top10重要特征水平条形图:特征重要性越高,对分类结果影响越大

通过可视化可得出垃圾邮件核心判别特征(业务可解释性):

  1. 高频特征:char_freq$word_freq_freeword_freq_money、大写字母序列特征;
  2. 业务逻辑:垃圾邮件常包含free(免费)、money(金钱)、$(货币符号),且滥用大写字母吸引注意;
  3. 价值:特征重要性可指导规则过滤系统优化,优先监控高贡献特征。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐