《Arduino家居安全系统构建实战》——2.1 挑战:构建一个垃圾邮件检测引擎

在线体验各类最新模型,更有模型 免费Token 额度领取!
立即体验
简介:

本节书摘来异步社区《机器学习项目开发实战》一书中的第2章,第2.1节,作者:【美】Mathias Brandewinder(马蒂亚斯·布兰德温德尔),更多章节内容可以访问云栖社区“异步社区”公众号查看

2.1 挑战:构建一个垃圾邮件检测引擎

我们将要处理的文档不是电子邮件,而是文本消息。我们的目标是使用来自英国的真实SMS(短消息服务)数据集发现垃圾短信,这些消息是我们从加州大学欧文分校机器学习知识库中找到的。

■ 附注:

UCI机器学习知识库由加州大学欧文分校的机器学习与智能系统中心于1987年启动。你可以在http://archive.ics.uci.edu/ml/中找到这个知识库,它包含将近300个干净、文档齐备的数据集,可以按照大小、特征类型等条件搜索和组织。这是一个很有趣的机器学习资源,包含了许多常常用作算法性能评估基准的“经典”数据集。

2.1.1 了解我们的数据集

在讨论使用哪个模型之前,首先来观察一下数据。数据集可以从http://1drv.ms/1uzMplL下载(这就是UCI知识库中原始文件的复制品,原始文件可以在http://archive.ics.uci.edu/ml/ datasets/SMS+Spam+Collection上找到)。它作为单个文本文件保存,名为SMSSpamCollection(没有文件扩展名),包含5574条真实的文本消息。每行是一个SMS,标记为“ham”(非垃圾短信)或者“spam”(垃圾短信)。下面是前面几行:

  ham      Go until jurong point, crazy.. Available only in bugis n great world la e buffet...Cine there got amore wat...
  ham     Ok lar... Joking wif u oni...
  spam    Free entry in 2 a wkly comp to win FA Cup final tkts 21st May 2005. Text FA to 87121 to receive entry question(std txt rate)T&C's apply 08452810075over18's
  ham     U dun say so early hor... U c already then say...
  ham     Nah I don't think he goes to usf, he lives around here though
  spam    FreeMsg Hey there darling it's been 3 week's now and no word back! I'd like some fun you up for it still? Tb ok! XxX std chgs to send, £1.50 to rcv```
第一眼的印象是,人们在文本消息中使用的语言明显不同于“标准英语”!例如“U c”这样的片段是“You see”的简写,在普通的词典中可能找不到。

考虑到这一点,我的第一步是尝试获得两组文本之间差别的“直觉”。有没有一些词语在垃圾短信或者非垃圾短信中出现得更频繁?这能够指导我们构建一个智能引擎,自动区分非垃圾短信和垃圾短信。我们首先按照类别(“ham”和“spam”)分解数据集,计算各自的词语出现频率。鉴于这一活动的探索特性,似乎很适合使用F#脚本。

■ 提示:


花点时间研究一下数据!盲目对数据集应用算法可能工作得不错,但是走不了太远。就像开发应用程序时应该花时间学习领域模型那样,对数据的更深入理解能够帮助你构建更智能的预测模型。
####2.1.2 使用可区分联合建立标签模型
数据是首要的,我们将采取和第1章相同的方式,但是有一些变化。数字识别数据集是由数字组成的(像素编码和标签都是如此),而这里的数据有一个特征(文本消息本身)和一个标签(“ham”或者“spam”)。我们应该如何表现它们?

可能的方法之一是将标签编码为布尔值,如非垃圾短信表示为“真”(true),垃圾短信表示为“假”(false)。这种标签工作得很完美,但是也有一些缺点:它不能自动说明字段的含义。例如,如果展示这样编码的一个数据记录:

True Ok lar... Joking wif u oni... ,`
你怎么可能猜出这里的“True”代表什么?另一个潜在的问题是,如果我们需要增加更多的类别(如非垃圾短信、垃圾短信和有歧义的信息),布尔值无法扩展。

机器学习的难点在于不能增加额外、不必要的复杂性。因此,我们将用F#的可区分联合(有时我也将它称作DU)表示标签。如果你之前从未见过可区分联合,可以近似地将其看作C#枚举类型。可区分联合和枚举一样,都定义一组独特的情况,但是功能强大得多。这种类比对DU不公平,但是足以帮助我们起步。

我们先使用可以在FSI中运行的例子,简单地说明DU的工作方式。定义DU和定义其他类型一样简单:

type DocType =
    | Ham
    | Spam```
在F# Interactive窗口运行上述语句(在最后添加;;触发求值),应该看到如下结果:

type DocType =

| Ham
| Spam```

上述语句定义了一个简单类型DocType,它只能取两个值:Spam或者Ham。我喜欢可区分联合的主要原因之一是它们和模式匹配配合得很好,可编写以非常清晰的风格描述业务领域的代码。例如,在我们的例子中,训练集中的每个示例都是非垃圾短信或者垃圾短信,并包含真实消息的内容。我们可以将其表示为一个元组,每个示例是一个DocType和一个字符串,按照这一路线处理消息示例,可以在F# Interactive窗口中尝试:

let identify (example:DocType*string) =
    let docType,content = example
    match docType with
    | Ham -> printfn "'%s' is ham" content
    | Spam -> printfn "'%s' is spam" content```
这个例子只是为了示意目的,但是指出了以后将要遵循的模式。在这个例子中,我们创建了一个小函数,取得一个消息示例并打印其内容以及所属类别。我们首先通过元组模式匹配将消息示例分为两部分(DocType和内容),然后在DocType的两种可能情况上使用模式匹配,在单独“分支”中处理两种情况。在FSI中输入:

identify (Ham,"good message");;`
你应该看到如下结果:

'good message' is ham```
在能够更好地决定如何处理真实SMS内容之前,这就是我们的数据模型。下面从加载数据集入手!

####2.1.3 读取数据集
和第1章一样,我们将把大部分时间花在探究数据集,从脚本环境中积极构建和改进模型上。打开Visual Studio创建一个新的F#库项目,将其命名为HamOrSpam。为了方便起见,我们还从Visual Studio之外使用文件系统,在解决方案中添加一个名为Data的文件夹,将数据文件SMSSpamCollection拖入其中(从前面提到的链接中下载,没有文件扩展名)。参见图2-1。

<div style="text-align: center"><img src="https://yqfile.alicdn.com/3d808bd20e5c9608fd298713670641641f250c8d.png" width="" height="">
</div>

这就使我们可以使用一个小技巧,用比第1章更清晰的方式访问数据文件。F#有两个方便的内建常量__SOURCE_DIRECTORY__和__SOURCE_FILE__,大大简化了脚本中文件的处理,我们可以引用数据文件位置,而无须硬编码一个取决于本地机器的路径。从这些常量的名称你可能已经猜到,第一个常量求得包含文件本身的目录完整路径,第二个返回到文件本身的完整路径,包括文件名。

现在可以进行脚本的编写了。和数字识别器使用的数据集之间主要的差别是,这个数据集没有文件头,只有两列,不使用逗号而使用制表符分隔。其他方面大部分相同:我们有一个包含示例的文件,希望将其提取到一个数组中。果不其然,解决方案看起来非常相似:读取文件并向每一行应用一个函数,将其解析为标签和内容,根据制表符“\t”拆分。

我们直接进入项目中的Script.fsx文件,删除默认的代码并粘贴如下代码:

程序清单2-1 从文件中读取SMS数据集

open System.IO

type DocType =

| Ham
| Spam

let parseDocType (label:string) =

match label with
| "ham" -> Ham
| "spam" -> Spam
| _ -> failwith "Unknown label"

let parseLine (line:string) =

let split = line.Split('\t')
let label = split.[0] |> parseDocType
let message = split.[1]
(label, message)

let fileName = "SMSSpamCollection"
let path = SOURCE_DIRECTORY + @"....Data" + fileName

let dataset =

File.ReadAllLines path
|> Array.map parseLine```

此时,你应该可以选择脚本中刚刚编写的所有代码,在F# Interactive窗口中执行,产生如下结果:

val dataset : (DocType * string) [] =
  [|(Ham,
     "Go until jurong point, crazy.. Available only in bugis n grea"+[50 chars]);
  (Ham, "Ok lar... Joking wif u oni...");
  (Spam,
   "Free entry in 2 a wkly comp to win FA Cup final tkts 21st May"+[94 chars]);
  // Snipped for brevity
  (Ham,
   "Hi. Wk been ok - on hols now! Yes on for a bit of a run. Forg"+[117 chars]);
  (Ham, "I see a cup of coffee animation"); ...|]```
现在我们有了一个示例数据集,每个都标记为垃圾短信或者非垃圾短信。我们可以开始解决真正感兴趣的问题了:可使用哪些特征区分垃圾短信和非垃圾短信?

■ 提示:

相关文章
|
存储 人工智能 安全
AI驱动的幼儿跌倒检测——视频安全系统的技术解析
幼儿跌倒检测系统基于AI视频技术,融合人体姿态识别与实时报警功能,为幼儿园安全管理提供智能化解决方案。系统通过YOLOv9、OpenPose等算法实现高精度跌倒检测(准确率达98%),结合LSTM时间序列分析减少误报,支持目标分类区分幼儿与成人,并具备事件存储、实时通知及开源部署优势。其高效、灵活、隐私合规的特点显著提升安全管理效率,助力优化园所运营。
756 0
AI驱动的幼儿跌倒检测——视频安全系统的技术解析
|
安全 Linux 网络安全
【分享】非常全面的CentOS7系统安全检测和加固脚本
【分享】非常全面的CentOS7系统安全检测和加固脚本
2102 0
【分享】非常全面的CentOS7系统安全检测和加固脚本
|
安全 Linux
Linux系统安全之Rootkit原理解析与检测实践
本章将首先介绍Linux Rootkit的分类和原理,然后介绍用于检测Rootkit的工具和方法。
9181 0
|
安全 Java 编解码
网络信息系统安全检测方案设计(上)
当前网络攻击日益猖獗,各种入侵手段层出不穷。众多信息系统因为只重视业务逻辑和敏捷开发的缘故,没有在安全检测这一块给予足够的关注和一定分析,从而往往成为黑客或不法分子眼中的目标。当前信息系统多为基于 Web 的 B/S 结构系统,故本文尝试提供一种基于 Web 服务安全检测和防御的设计,并给出代码实现,务求能够防御 Web 常见的 XSS 攻击、CSRF 攻击、CRLF 注入和 SQL 注入攻击,另外包括提供 POST 白名单检测和 Cookies 加密等。
1372 0
|
SQL 移动开发 安全
网络信息系统安全检测方案设计(下)
接上一篇文章《网络信息系统安全检测方案设计(上)》。 HTTP 响应头拆分 CRLF 检测 CRLF 代表回车 (CR, ASCII 13, \r) 以及换行 (LF, ASCII 10, \n),也就是”回车 + 换行”(\r\n)的意思。
822 0
|
监控 安全 Linux
Linux系统的防御从多个方面来保护系统安全
防火墙:使用防火墙软件如iptables或Firewalld来限制网络流量,保护系统免受恶意网络攻击。
|
网络协议 安全 Linux
linux系统安全及应用——端口扫描
linux系统安全及应用——端口扫描
277 0
|
安全 Linux
Linux 系统安全 - 近期发现的 polkit pkexec 本地提权漏洞(CVE-2021-4034)修复方案
Linux 系统安全 - 近期发现的 polkit pkexec 本地提权漏洞(CVE-2021-4034)修复方案
1979 2

热门文章

最新文章