数据结构与算法笔记:高级篇 - 概率统计:如何利用朴素贝叶斯算法过滤垃圾短信?

概述

上篇文章我们讲到,如何用位图、布隆过滤器,来过滤重复数据。本章,我们再讲一个跟过滤相关的问题,如果过滤垃圾短信?

垃圾短信和骚扰电话,我想每个人都收到过吧?买房、贷款、投资理财、开发票,各种垃圾短信和骚扰电话,不胜其扰。如果你是一个手机应用的开发工程师,让你实现一个简单的垃圾短信过滤功能以及骚扰电话拦截功能,该用什么样的数据结构和算法实现呢?


算法解析

实际上,解决这个问题并不会涉及很高深的算法。本章,就带你一块看下,如何利用简单的数据结构和算法,解决这种看似非常复杂的问题。

1.基于黑名单的过滤器

我们可以维护一个骚扰电话号码和垃圾短信发送号码的黑名单。这个黑名单的收集,有很多途径,比如,我们可以从一些公开的网站上下载,也可以通过类似 “260骚扰电话拦截” 的功能,通过用户自主标记骚扰电话来收集。 对于被多个用户标记,并且标记个数超过一定阈值的号码,我们就可以定义为骚扰电话,并将它将入到黑名单中。

如果黑名单中的电话号码不多,我们可以使用散列表、二叉树等动态数据结构来存储,对于内存的消耗并不会很大。如果我们把每个号码看做一个字符串,并且假设平均长度是 16 个字节,那存储 50 万个电话号码,大约需要 10MB 的内存空间。即便是对手机这样的内存有效的设备来说,这点内存消耗也是可以接收的。

但是,如果黑名单中的电话号码很多呢?比如有 500 万个。这个时候,如果再用散列表存储,那就需要大约 100MB 的存储空间。为了实现一个拦截功能,耗费用户如此多的手机内存,这显然有点儿不合理。

上篇文章,我们讲了,布隆过滤器最大的特点就是节省空间,所以,用它来解决这个问题再适合不过了。如果我们要存储 500 万个手机号,我们把位图大小设置为 10 倍数据大小,也就是 5000 万,那也只需要使用 5000 万个二进制位(5000 万bits),换算成字节,也就是不到 7MB 的存储空间,比起散列表的解决方案,内存的消耗减少了很多。

实际上,我们还有一种时间换空间的方法,可以将内存的消耗优化到极致。

我们可以把黑名单存储在服务器上,把过滤和拦截的核心工作,交给服务器端来做。手机端只负责将要检查的号码发送给服务器端,服务器端通过查黑名单,判断这个号码是否应该被拦截,并将结果返回给手机端。

用这个思路完全不需要占用手机内存。不过,有利就有弊。我们知道,网络通信是比较慢的,所以,网络延迟就会导致处理速度降低。而且,这个方案还有个硬性要求,那就是只有在联网的情况下,才能正常工作。

基于黑名单的过滤器我讲完了,不过,你可能还会说,布隆过滤器会有判错的概率呀!如果它把一个重要的电话或者短信,当成垃圾短信或者骚扰电话拦截了,对于用户来说,这是无法接受的。你说的没错,这是一个很大的问题。不过,我们现在先放一放,等三种过滤器都讲完之后,再来解答。

2.基于规则的过滤器

刚刚讲了一种基于黑名单的垃圾短信过滤方法,但是,如果某个垃圾短信发送者的号码并不在黑名单中,那这种方法就没有办法拦截了。所以,基于黑名单的过滤方式,还不够完善,我们再继续看一种基于规则的过滤方式。

对于垃圾短信来说,我们还可以通过短信内容,来判断某条短信是否是垃圾短信。我们预先设置一些规则,如果某条短信符合这些规则,我们就可以判定它为垃圾短信。实际上,规则有很多,比如下面几个:

  • 短信中包含特殊单词(或词语),比如一些非法、淫秽、反动词语等。
  • 短信发送号码是群发号码,非我们正常的手机号吗。
  • 短信中包含回拨的联系方式,比如手机号码、微信、QQ、网页链接等,因为群发短信的号码一般是无法回拨的。
  • 短信格式花哨、内容很长,比如各种表情、图片、网页链接等。
  • 符合已知垃圾短信的模板。垃圾短信一般都是重复群发,对于已经判定为垃圾短信的短信,我们可以抽象成模板,将获取到的短信与模板匹配,一旦匹配,我们就可以判定为垃圾短信。

当然,如果短信只是满足其中的一条规则,如果就判定为垃圾短信,那会存在比较大的误判的情况。我们可以综合多条规则进行判定。比如,满足 2 条以上才会被判定为垃圾短信;或者每条规则对应一个不同的得分,满足哪条规则,我们就累加对应的分数,某条短信的总得分超过某个阈值,才会被判定为垃圾短信。

不过,我只是给出了一些指定规则的思路,具体落实到执行层面,其实还有很大的距离,还有很多细节需要处理。比如,第一条规则,我们该如何定义特殊单词;第二条规则中,我们该如何定义什么样的号码是群发号码等等。限于篇幅,我就不一一详细讲解了。这里只讲一下如何定义特殊单词?

如果我们只是拍脑袋想,哪些单词属于特殊单词,那势必有比较大的主观性,也很容易遗漏掉某些单词。实际上,我们可以基于概率统计的方法,借助计算机强大的计算能力,找出哪些单词最常出现在垃圾短信中,将这些最常出现的单词,作为特殊单词,用来过滤短信。

不过这种方法的前提是,我们有大类的样本数据,也就是说,要有大类的短信(比如 1000 万条短信),并且我们还要求,每条短信都做好了标记,它是垃圾短信还是非垃圾短信。

我们对这 1000 万条短信,进行分词处理(借助中文或者英文分词法),去掉 “的、和、是” 等没有意义的停用词(Stop Words),得到 n 个不同的单词。针对每个单词,我们统计有多少个垃圾短信出现了这个单词,有多少个非垃圾短信出现 这个单词,进而求出每个单词出现在垃圾短信中的概率,以及出现在非垃圾短信中的概率。如果某个单词出现在垃圾短信中的概率,远大于出现在非垃圾短信中的概率,那我们就把这个单词作为特殊词,用来过滤垃圾短信。

文字描述不好理解,我举个例子来解释细下。

在这里插入图片描述

3.基于概率统计的过滤器

基于规则的过滤,看起来很直观,也很好理解,但是它也有一定的局限性。

  • 一方面,这些规则受人的思维方式的局限,规则未免太过简单。
  • 另一方面,垃圾短信发送至可能会针对规则,精心设计短信,绕过这些规则的拦截。

对此,我们再来看一种更加高级的过滤方式,基于概率统计的过滤方式

这种基于概率统计的过滤方式,基础理论是基于朴素贝叶斯算法。为了让你更好地理解下面的内容,我们先通过一个非常简单的例子来看下,什么是朴素贝叶斯算法?

假设事件 A 是 “小明不去上学”,事件 B 是 “下雨了”。我们现在统计一下过去 10 天的下雨情况和小明上学的情况,作为样本数据。

在这里插入图片描述

我们来分析一下,这组样本有什么规律。

  • 在这 10 天中,有 4 天下雨,所以下雨的概率 P(B)=4/10
  • 10 天中有 3 天,小明没有去上学,所以小明不去上学的概率是 P(A)=3/10
  • 在 4 个下雨天中,小明有 2 天没有去上学,所以下雨天不去上学的概率 P(A|B)=2/4
  • 在小明没有去上学的 3 天中,有 2 天下雨了,所以小明因为下雨不去上学的概率是 P(B|A)=2/3

实际上,这 4 个概率值之间,有一定的关系,这个关系就是朴素贝叶斯算法,我们用公司表示出来,就是下面这个样子。

在这里插入图片描述

朴素贝叶斯算法是不是非常简单?我们用一个公式就可以将它概况。弄懂了朴素贝叶斯算法,我们在回到垃圾短信过滤这个问题上,看看如何利用朴素贝叶斯算法,来做垃圾短信的过滤。

基于概率统计的过滤器,是基于短信内容来判断是否是垃圾短信。而计算机没有办法像人一样理解短信的含义。所以,我们需要把短信抽象成一组计算机可以理解,并且方便计算的特征项,用这一组特征项代替短信本身,来做垃圾短信过滤。

我们可以通过分词算法,把一个短信分割成 n 个单词。这 n 个单词就是一组特征项,全权代表这个短信。因此,判定一个短信是否是垃圾短信这样一个问题,就变成了,判定同时包含这几个单词的短信是否是垃圾短信。

不过,这里我们并不像基于规则的过滤器那样,非黑即白,一个短信要么被判定为垃圾短信、要么被判定为非垃圾短信。我们使用概率,来表征一个短信是垃圾短信的可信度。如果我们用公式将这个概率表示出来,就是下面这个样子:

在这里插入图片描述

尽管我们有大量的短信样本,但是我们没法通过样本数据统计得到这个概率。为什么不可以呢?你可能会说,我只需要统计同时包含 W 1 , W 2 , W 3 , . . . , W n W_{1},W_{2},W_{3},...,W_{n} W1,W2,W3,...,Wn 这 n 个单词的短信有多少个(我们假设有 x 个),然后看这里属于垃圾短信的有几个(我们假设有 y 个),那包含 W 1 , W 2 , W 3 , . . . , W n W_{1},W_{2},W_{3},...,W_{n} W1,W2,W3,...,Wn 这 n 个单词的短信是垃圾短信的概率是 y/x

理想很丰满,但现实很骨感。你忽视了非常重要的一点,那就是样本的数量再大,比较也是有限的,样本中不会有太多同时包含 W 1 , W 2 , W 3 , . . . , W n W_{1},W_{2},W_{3},...,W_{n} W1,W2,W3,...,Wn 的短信,甚至很多时候,样本中根本不存在这样的短信。没有样本,也就无法计算概率。所以这样的推理方式虽然正确,但在实践中并不好用。

这个时候,朴素贝叶斯公式就可以派上用场了。我们通过朴素贝叶斯公式,将这个概率的求解,分解为其他三个概率的求解。你可以看我话的图。那转化之后的三个概率是否可以通过样本统计得到呢?

在这里插入图片描述
P ( W 1 , W 2 , W 3 , . . . , W n 同时出现在一条短信中 ∣ 短信是垃圾短信 ) P(W_{1},W_{2},W_{3},...,W_{n}同时出现在一条短信中 | 短信是垃圾短信) P(W1,W2,W3,...,Wn同时出现在一条短信中短信是垃圾短信) 这个概率照样无法通过样本统计得到。但是我们可以基于下面这条著名的概率规则来计算。

独立事件发生的概率计算公式: P(A*B)=P(A)*P(B)

  • 如果事件 A 和事件 B 是独立事件,两者的发生没有相关性,事件 A 发生的概率 P(A) 等于 p1,事件 B 发生的概率 P(B) 等于 p2,那两个同时发生的概率 P(A*B) 就等于 P(A)*P(B)

基于这条独立事件发生概率的计算公式,我们可以把 P ( W 1 , W 2 , W 3 , . . . , W n 同时出现在一条短信中 ∣ 短信是垃圾短信 ) P(W_{1},W_{2},W_{3},...,W_{n}同时出现在一条短信中 | 短信是垃圾短信) P(W1,W2,W3,...,Wn同时出现在一条短信中短信是垃圾短信) 分解为下面这个公式:

在这里插入图片描述
其中 P ( W i 出现在短信中 ∣ 短信是垃圾短信 ) P(W_{i} 出现在短信中 | 短信是垃圾短信) P(Wi出现在短信中短信是垃圾短信) 表示垃圾短信中包含 W i W_{i} Wi 这个单词的概率有多大。这个概率值通过样本很容易就能获得。我们假设垃圾短信有 y 个,其中包含 W i W_{i} Wi 的有 x 个,那这个概率值就等于 x/y

P ( 短信是垃圾短信 ) P(短信是垃圾短信) P(短信是垃圾短信) 表示短信是垃圾短信的概率,这个很容易得到。我们把样本中垃圾短信的个数除以总样本个数,就是短信是垃圾短信的概率。

不过 P ( W 1 , W 2 , W 3 , . . . , W n 同时出现在一条短信中 ) P(W_{1},W_{2},W_{3},...,W_{n}同时出现在一条短信中) P(W1,W2,W3,...,Wn同时出现在一条短信中) 这个概率还是不好通过样本统计得到,原因前面说过了,样本空间有限。不过,我们没有必要非得计算这部分的概率值。为什么这么说呢?

实际上,我们可以分别计算同时包含 W 1 , W 2 , W 3 , . . . , W n W_{1},W_{2},W_{3},...,W_{n} W1,W2,W3,...,Wn 这 n 个单词的短信,是垃圾短信和非垃圾短信的概率。假设它们分别是 p1 和 p2。我们并不需要单纯的基于 p1 值的大小来判断是否是垃圾短信,而是通过对比 p1 和 p2 值的大小,来判断一条短信是否是垃圾短信。更细化一点讲,那就是,如果 p1 是 p2 的很多倍(比如 10 倍),我们才确信这条短信是垃圾短信。

在这里插入图片描述

基于这连个概率的倍数来判断是否是垃圾短信的方法,我们就可以不用计算 P ( W 1 , W 2 , W 3 , . . . , W n 同时出现在一条短信中 ) P(W_{1},W_{2},W_{3},...,W_{n}同时出现在一条短信中) P(W1,W2,W3,...,Wn同时出现在一条短信中) 这一部分的值了,因为计算 p1 和 p2 的时候,都会包含这个概率值的计算,所以在求解 p1 和 p2 的倍数 (p1/p2) 的时候,我们也就不需要这个值了。

总结

本章,讲解了基于黑名单、规则、概率统计三种垃圾短信的过滤方法,实际上,本章讲的这三种方法,还可以应用到很多类似过滤、拦截的领域,比如垃圾邮件的过滤等等。

在讲黑名单过滤的时,我讲到 布隆过滤器可能会存在误判,可能会导致用户投诉。实际上,我们可以结合三种不同过滤方式的结果,对同一个短信处理,如果三种都标明这个短信是垃圾短信,我们才把它当做垃圾短信拦截过滤,这样就会更精准。当然,在实际的工程中,我们还需要结合具体的场景,以及大量的实验,不断去调整策略,权衡垃圾短信判定的准确率(是否会把不是垃圾短信的短信错判为垃圾短信)和召回率(是否能把所有的垃圾短信都找到),来实现我们的需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/746612.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

带你学习PID算法2

#PID讲解 前言:本文参考华南小虎队的PID视频,视频连接放在最后 下图工人控制水阀可以满足: 1流量稳定 2随时改变流量 如果预期流量是1L/s,实际流量确实0.8L/s,工人就会调节阀门,使其达到&#xff0…

论文学习_基于导向式模糊测试的二进制程序漏洞验证方法

1. 引言 研究背景及现存问题:基于代码相似性比较的漏洞检测方法属于静态分析方法,不可避免地存在误报率高的问题,对静态检测方法得到的疑似漏洞代码进行人工分析存在工作量大, 效率低的问题。解决该问题的有效的方案之一是使用导向式模糊测试方法,生成能够执行到疑似漏洞…

【C++LeetCode】【热题100】三数之和【中等】-不同效率的题解【6】

题目&#xff1a; 暴力方法&#xff1a; class Solution { public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> res;std::unordered_set<std::string> uniqueValues;//保证结果唯一for(int i0;i<n…

【第2章】MyBatis-Plus代码生成器

文章目录 前言一、安装二、生成方式1.DefaultQuery (元数据查询)2.存在问题 三、快速生成1. 生成代码2. 目录结构 四、交互式总结 前言 全新的 MyBatis-Plus 代码生成器&#xff0c;通过 builder 模式可以快速生成你想要的代码&#xff0c;快速且优雅&#xff0c;跟随下面的代…

vue draggable

一、安装&#xff1a; npm i -S vuedraggablenext 二、代码 <draggable :list"projectOptions" item-key"name" class"w-25" ghost-class"ghost"chosen-class"chosen" update"updateSort" animation"3…

跨境独立站推广策略:有哪些方法与工具?

在出海独立站商家中&#xff0c;推广是必不可少的环节。在你完成网站的搭建&#xff0c;产品的上架&#xff0c;以及网站的运营和优化后&#xff0c;你就可以开始着手推广你的网站了。你的网站是承载你的品牌和产品的主要平台&#xff0c;因此&#xff0c;你需要根据你的品牌和…

Java实现RS485串口通信

博客链接地址 近期&#xff0c;我接到了一个任务&#xff0c;将报警器接入到Java项目中&#xff0c;而接入的方式就是通过RS485接入&#xff0c;本人之前可以说是对此毫无所知。不过要感谢现在的互联网&#xff0c;通过网络我查到了我想要知道的一切&#xff0c;这里记录下本次…

【新闻】金融专业“免进”!私募巨头招聘涌现“新剧情”

A股市场在2024年逐渐出现新的运行特征&#xff0c;这不禁让部分主动投资的私募巨头公司重新登上招聘舞台。 但这一次&#xff0c;他们的招聘方向出现了新的变动。 有些机构有意识的为公司投研团队招聘“衔接”岗&#xff0c;有些则把重点放在了投研动作的交易层。 但这都不如…

外汇的基本面分析需要关注什么?

外汇基本面分析的核心在于关注可能影响单一货币供求及国家货币价值的经济、社会和地缘政治事件与趋势。但值得注意的是&#xff0c;这些事件和因素往往具有更广泛的影响力&#xff0c;不仅限于单一国家。它们可能是影响整个地区或国家集团的重要事件&#xff0c;甚至一些事件&a…

设计师进阶指南:掌握这6条版式设计要点

布局设计是设计师的必修课。优秀的排版不是强制性的“东拼西凑”&#xff0c;而是通过设计师独特的排版获得的。这不是简单的信息列表&#xff0c;而是认真思考如何分层、有节奏地组织和安排元素。今天我将给你带来它 6 文章还附带了布局设计模板资源&#xff0c;设计师朋友一定…

【shell 学习一】shell执行方式以及变量(自定义变量、整数运算)定义

1.shell执行方式 测试脚本 vim file1 echo hello 2024 read -p 请输入 name echao hh,$name执行1 bash file1执行2 sh file1执行3 . file1执行4 source file11和2的方式&#xff0c;是子shell 3和4的方式&#xff0c;是本shell bash是进入新的命令 这时候退出edit是退出这个新…

AI办公自动化:多音频轨电影视频抽取出英语音频

很多电影视频是有中、英、粤语等多个音频轨的&#xff0c;如果直接转换成音频&#xff0c;很有可能不是自己想要的那种语音。 可以先查看音频流信息&#xff0c;确定属于哪个音频轨&#xff1a; Reading video file: E:\1-7\比得兔1.mp4 输出音频流信息 Available audio str…

学校师生都在用的电路设计神器——SmartEDA,你get到了吗?

在信息时代的浪潮下&#xff0c;电子技术的迅猛发展对人才的培养提出了更高要求。学校师生在电路设计领域&#xff0c;急需一款既方便易用又功能强大的辅助工具。今天&#xff0c;就为大家揭秘一款备受好评的电路设计工具——SmartEDA&#xff0c;看它如何助力学校师生在电路设…

【D3.js in Action 3 精译】1.2 D3 生态系统——入门须知

1.2 D3 生态系统——入门须知 D3.js 从不单打独斗&#xff0c;而是作为 D3 生态系统的一员&#xff0c;与生态内的一系列技术和工具相结合来创建丰富的 Web 界面。与其他网页一样&#xff0c;D3 项目也是充分利用 HTML5 的强大功能在 DOM 内构建出来的。尽管 D3 也可以创建并操…

LangChain结合LLM做私有化文档搜索

我们知道LLM&#xff08;大语言模型&#xff09;的底模是基于已经过期的公开数据训练出来的&#xff0c;对于新的知识或者私有化的数据LLM一般无法作答&#xff0c;此时LLM会出现“幻觉”。针对“幻觉”问题&#xff0c;一般的解决方案是采用RAG做检索增强。 但是我们不可能把…

docker in docker 在CI中应用解析

docker in docker 简介 docker里嵌套运行docker&#xff0c;本文讲解其在jenkins和gitlab-runner 种的调用流程 一、用于jenkins 容器化部署jenkins时调用docker命令集成CI功能 [rootops-demo~]# docker inspect jenkins --format"{{json .Mounts}}" [{"T…

自学网络安全,圈内大佬学习书单助你砥砺前行【网络安全书单推荐】

文章目录 [&#x1f31f;网络安全书单推荐&#x1f680;] 网络安全是保护网络系统、网络设备、通信网络和数据免受未经授权的访问、损坏或窃取的一系列措施和技术。这个领域涉及到防止网络攻击、恶意软件和其他网络威胁的发生&#xff0c;同时确保数据的机密性、完整性和可用…

CNware快照技术采用双轨服务模式,显著改善虚拟机快照执行时执行后性能下降问题|附技术原理

在数字化时代&#xff0c;虚拟化技术已成为数据中心管理与云计算领域的基石。虚拟化技术允许在单一物理服务器上运行多个独立的虚拟环境&#xff0c;即虚拟机。每个虚拟机都能拥有专属的操作系统、应用程序和配置&#xff0c;彼此隔离&#xff0c;互不影响。然而&#xff0c;如…

通用后台管理——Vue router的使用

目录 一、Vue router是什么&#xff1f; 二、下载Vue router 三、使用router 四、使用嵌套router​​​​​​​ 一、Vue router是什么&#xff1f; 官网&#xff1a;安装 | Vue Router 是Vue.js的官方路由&#xff0c;实现多页跳转到功能&#xff0c;还包括&#xff1a; …

经典小游戏(一)C实现——三子棋

switch(input){case 1:printf("三子棋\n");//这里先测试是否会执行成功break;case 0:printf("退出游戏\n");break;default :printf("选择错误&#xff0c;请重新选择!\n");break;}}while(input);//直到输入的结果为假&#xff0c;循环才会结束} …