基于C#的机器学习--垃圾邮件过滤

  在这一章,我们将建立一个垃圾邮件过滤分类模型。我们将使用一个包含垃圾邮件和非垃圾邮件的原始电子邮件数据集,并使用它来训练我们的ML模型。我们将开始遵循上一章讨论的开发ML模型的步骤。这将帮助我们理解工作流程。

       在本章中,我们将讨论以下主题:

    l  定义问题

    l  准备数据

    l  数据分析

    l  构建数据的特征

    l  逻辑回归与朴素贝叶斯的Email垃圾邮件过滤

    l  验证分类模型

定义问题

       让我们从定义本章要解决的问题开始。我们可能已经对垃圾邮件很熟悉了;垃圾邮件过滤是众电子邮件服务的基本功能。垃圾邮件对用户来说可能是恼人的,但它们除此之外,也会带来更多的问题和风险。例如,可以设计垃圾邮件来获取信用卡号或银行帐户信息,这些信息可用于信用卡欺诈或洗钱。垃圾邮件也可以用来获取个人数据,然后可以用于身份盗窃和各种其他犯罪。垃圾邮件过滤技术是电子邮件服务避免用户遭受此类犯罪的重要一步。然而,有正确的垃圾邮件过滤解决方案是困难的。我们想过滤掉可疑的邮件,但同时,我们又不想过滤太多,以至于非垃圾邮件进入垃圾邮件文件夹,永远不会被用户看到。为了解决这个问题,我们将让我们的ML模型从原始电子邮件数据集中学习,并使用主题行将可疑电子邮件归类为垃圾邮件。我们将着眼于两个性能指标来衡量我们的成功:准确度和召回率。我们将在以下几节中详细讨论这些指标。

       总结我们的问题定义:

需要解决的问题时什么?我们需要一个垃圾邮件过滤解决方案,以防止我们的用户成为欺诈活动的受害者,同时改善用户体验。

为什么这是个问题?在过滤可疑邮件和不过滤太多邮件之间取得适当的平衡是很困难的,这样垃圾邮件仍然会进入收件箱。我们将依靠ML模型来学习如何对这些可疑邮件进行统计分类。

解决这个问题的方法有哪些?我们将建立一个分类模型,根据邮件的主题行,标记潜在的垃圾邮件。我们将使用准确性和召回率来平衡被过滤的邮件数量。

成功的标准是什么?我们想要高回复率(实际垃圾邮件检索的百分比占垃圾邮件的总数),而不牺牲太多的精确率(正确分类的垃圾邮件的百分比中预测为垃圾邮件)。

准备数据

       现在,我们已经清楚地描述和定义了将要用ML解决的问题,接下来我们需要准备数据。通常,我们需要在数据准备步骤之前采取额外的步骤来收集我们需要的数据,但是现在,我们将使用一个预先编译并标记为公共可用的数据集。在本章中,我们将使用CSDMC2010垃圾数据集来训练和测试我们的模型。我们将看到一个名为SPAMTrain.label的文本文件。SPAMTrain.label文件对训练文件夹中的每封邮件都进行了编码,0代表垃圾邮件,1代表非垃圾邮件。我们将使用此文本文件和训练文件夹中的电子邮件数据来构建垃圾邮件分类模型。

       我们现在拥有的是一个原始数据集,其中包含许多EML文件,其中包含关于单个电子邮件的信息,以及一个包含标记信息的文本文件。为了使这个原始数据集可用来构建垃圾邮件分类模型,我们需要做以下工作:

  1. EML文件中提取主题行:为将来的任务准备数据的第一步是从各个EML文件中提取主题和正文。我们将使用一个名为EAGetMail的包来加载和提取EML文件中的信息。使用EAGetMail包,我们可以轻松地从EML文件中加载和提取主题和正文内容。一旦从电子邮件中提取了主题和正文,就需要将每行数据作为一行附加到Deedle数据框架中。
  2. 将提取的数据与标签结合起来:在从各个EML文件中提取主题和正文内容之后,我们还需要做一件事。我们需要将经过编码的标签(垃圾邮件为0,而非垃圾邮件为1)映射到我们在前一步中创建的数据帧的每一行。如果我们打开垃圾邮件。标签文件与任何文本编辑器,您可以看到编码的标签在第一列和相应的电子邮件文件名在第二列,由一个空格分隔。使用Deedle frame的ReadCsv函数,我们可以通过指定一个空格作为分隔符来轻松地将这个标签数据加载到数据框架中。一旦我们将这个标记的数据加载到一个数据框架中,我们就可以简单地将这个数据框架的第一列添加到前面步骤中使用Deedle框架的AddColumn函数创建的其他数据框架中。
  3. 将合并后的数据导出为CSV文件:现在我们已经有了一个包含电子邮件和标签数据的数据框架,现在可以将该数据框架导出为CSV文件,以供将来使用。使用Deedle frame的SaveCsv函数,您可以轻松地将数据帧保存为CSV文件。

  这个准备数据步骤的代码如下:

 1 using Deedle;
 2 using EAGetMail;
 3 using System;
 4 using System.IO;
 5 using System.Linq;
 6 
 7 namespace 准备数据
 8 {
 9     internal class Program
10     {
11         private static void Main(string[] args)
12         {
13             // 获取所有原始的电子邮件格式的文件
14             // TODO: 更改指向数据目录的路径
15             string rawDataDirPath = @"D:\工作\代码库\AI\垃圾邮件过滤\raw-data";
16             string[] emailFiles = Directory.GetFiles(rawDataDirPath, "*.eml");
17 
18             // 从电子邮件文件中解析出主题和正文
19             var emailDF = ParseEmails(emailFiles);
20             // 获取每个电子邮件的标签(spam vs. ham)
21             var labelDF = Frame.ReadCsv(rawDataDirPath + "\\SPAMTrain.label", hasHeaders: false, separators: " ", schema: "int,string");
22             // 将这些标签添加到电子邮件数据框架中
23             emailDF.AddColumn("is_ham", labelDF.GetColumnAt<String>(0));
24             // 将解析后的电子邮件和标签保存为CSV文件
25             emailDF.SaveCsv("transformed.csv");
26 
27             Console.WriteLine("准备数据步骤完成!");
28             Console.ReadKey();
29         }
30 
31         private static Frame<int, string> ParseEmails(string[] files)
32         {
33             // 我们将解析每个电子邮件的主题和正文,并将每个记录存储到键值对中
34             var rows = files.AsEnumerable().Select((x, i) =>
35             {
36                 // 将每个电子邮件文件加载到邮件对象中
37                 Mail email = new Mail("TryIt");
38                 email.Load(x, false);
39 
40                 // 提取主题和正文
41                 string EATrialVersionRemark = "(Trial Version)"; // EAGetMail在试用版本中附加主题“(试用版本)”
42                 string emailSubject = email.Subject.EndsWith(EATrialVersionRemark) ?
43                     email.Subject.Substring(0, email.Subject.Length - EATrialVersionRemark.Length) : email.Subject;
44                 string textBody = email.TextBody;
45 
46                 // 使用电子邮件id (emailNum)、主题和正文创建键-值对
47                 return new { emailNum = i, subject = emailSubject, body = textBody };
48             });
49 
50             // 根据上面创建的行创建一个数据帧
51             return Frame.FromRecords(rows);
52         }
53     }
54 }

        运行这段代码后,程序将会创建一个名为transformed.csv的文件,它将包含四列(emailNum、subject、body和is_ham)。我们将使用此输出数据作为后面步骤的输入,以构建垃圾邮件过滤项目的ML模型。但是,我们也可以尝试使用Deedle框架和EAGetMail包,以不同的方式调整和准备这些数据。我在这里提供的代码是准备这些原始电子邮件数据以供将来使用的一种方法,以及我们可以从原始电子邮件数据中提取的一些信息。使用EAGetMail包,我们也可以提取其他特征,比如发件人的电子邮件地址和电子邮件中的附件,这些额外的特征可能有助于改进垃圾邮件分类模型。

数据分析

       在准备数据步骤中,我们将原始数据集转换为更具可读性和可用性的数据集。我们现在有一个文件可以查看,以找出哪些邮件是垃圾邮件,哪些不是。此外,我们可以很容易地找到垃圾邮件和非垃圾邮件的主题行。有了这些转换后的数据,让

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山信大大懒虫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值