数据结构与算法笔记:高级篇 - 概率统计:如何利用朴素贝叶斯算法过滤垃圾短信?
概述
上篇文章我们讲到,如何用位图、布隆过滤器,来过滤重复数据。本章,我们再讲一个跟过滤相关的问题,如果过滤垃圾短信?
垃圾短信和骚扰电话,我想每个人都收到过吧?买房、贷款、投资理财、开发票,各种垃圾短信和骚扰电话,不胜其扰。如果你是一个手机应用的开发工程师,让你实现一个简单的垃圾短信过滤功能以及骚扰电话拦截功能,该用什么样的数据结构和算法实现呢?
算法解析
实际上,解决这个问题并不会涉及很高深的算法。本章,就带你一块看下,如何利用简单的数据结构和算法,解决这种看似非常复杂的问题。
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
) 的时候,我们也就不需要这个值了。
总结
本章,讲解了基于黑名单、规则、概率统计三种垃圾短信的过滤方法,实际上,本章讲的这三种方法,还可以应用到很多类似过滤、拦截的领域,比如垃圾邮件的过滤等等。
在讲黑名单过滤的时,我讲到 布隆过滤器可能会存在误判,可能会导致用户投诉。实际上,我们可以结合三种不同过滤方式的结果,对同一个短信处理,如果三种都标明这个短信是垃圾短信,我们才把它当做垃圾短信拦截过滤,这样就会更精准。当然,在实际的工程中,我们还需要结合具体的场景,以及大量的实验,不断去调整策略,权衡垃圾短信判定的准确率(是否会把不是垃圾短信的短信错判为垃圾短信)和召回率(是否能把所有的垃圾短信都找到),来实现我们的需求。
相关文章:

数据结构与算法笔记:高级篇 - 概率统计:如何利用朴素贝叶斯算法过滤垃圾短信?
概述 上篇文章我们讲到,如何用位图、布隆过滤器,来过滤重复数据。本章,我们再讲一个跟过滤相关的问题,如果过滤垃圾短信? 垃圾短信和骚扰电话,我想每个人都收到过吧?买房、贷款、投资理财、开…...

vue3中通过vditor插件实现自定义上传图片、录入echarts、脑图、markdown语法的编辑器
1、下载Vditor插件 npm i vditor 我的vditor版本是3.10.2,大家可以自行选择下载最新版本 官网:Vditor 一款浏览器端的 Markdown 编辑器,支持所见即所得(富文本)、即时渲染(类似 Typora)和分屏 …...

揭示数据库内核的奥秘--手写数据库toadb开源项目
揭示数据库内核的奥秘–手写数据库toadb 数据为王的时代 在信息化时代,数据已成为企业和应用不可或缺的核心,而数据库不仅是数据的仓库,更是支撑业务决策、系统运行的基石。对于求职者而言,掌握数据库知识已成为求职市场上的必考…...

Grafana调整等待时间,避免Gateway timeout报错
使用Grafana的HTTP时,有些即时数据需要运算量与时间,而grafana的默认timeout是30秒,因此需要通过修改配置文件,避免grafana提前中断连接 修改原始配置文件: 删除;调整timeout30为timeout60 # This setting also applies to cor…...

MetaGPT全面指南:多代理协作框架的深入解析与应用
文章目录 理解MetaGPT1.1 MetaGPT的基础1.2 MetaGPT的独特之处1.3 MetaGPT在AI领域的应用 MetaGPT的工作原理2.1 训练2.2 微调2.3 推理2.4 多代理协作的概念2.5 如何分配角色给GPTs2.6 复杂任务的完成过程 实际应用3.1 客户支持3.2 内容创作3.3 教育3.4 医疗保健3.5 在企业中的…...

图的关键路径算法
关键路径算法(Critical Path Method, CPM)是一种用于项目管理和调度的技术,通过分析项目任务的最早开始时间、最晚完成时间和总时差,找出项目中关键的任务路径。这条关键路径决定了项目的最短完成时间,因为关键路径上的…...

模型情景制作-冰镇啤酒
夏日炎炎,当我们在真实世界中开一瓶冰镇啤酒的时候,我们也可以为模型世界中的人物添加一些冰镇啤酒。 下面介绍一种快速酒瓶制造方法,您只需要很少工具: 截取尽量直的流道(传说中的板件零件架),将其夹在您的…...

网页实现黑暗模式的几种方式
## 实现暗黑模式的最佳方式 在现代网页设计中,暗黑模式已成为提高用户体验的重要功能。实现暗黑模式不仅可以减少用户眼睛的疲劳,还能在某些情况下节省设备电量。本文将介绍实现暗黑模式的几种最佳方式。 ### 使用 CSS 变量 (CSS Custom Properties) …...

VMware Workstation环境下,邮件(E-Mail)服务的安装配置,并用Windows7来验证测试
需求说明: 某企业信息中心计划使用IP地址17216.11.0用于虚拟网络测试,注册域名为xyz.net.cn.并将172.16.11.2作为主域名的服务器(DNS服务器)的IP地址,将172.16.11.3分配给虚拟网络测试的DHCP服务器,将172.16.11.4分配给虚拟网络测试的web服务器,将172.16.11.5分配给FTP服务器…...

《信号与系统》复试建议
目录 第一章 绪论 第二章 连续时间系统的时域分析 第三章 傅立叶变换(重点) 第四章 拉普拉斯变换(重点) 第五章 傅立叶变换在通信系统中的应用 第六章 信号的矢量空间分析 第七章 离散时间系统的时域分析 第八章 Z变换与离…...

代码随想录训练营Day45
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、打家劫舍二、打家劫舍2三、打家劫舍3 前言 提示:这里可以添加本文要记录的大概内容: 今天是跟着代码随想录刷题的第45天ÿ…...

NAT和内网穿透
NAT(Network Address Translation,网络地址转换)是一种广泛应用于计算机网络的技术,其主要目的是为了解决IPv4地址空间的短缺问题,并且增强网络安全。NAT技术允许一个私有网络内的多个设备共享一个或几个全局唯一的公共…...

android | 声明式编程!(笔记)
https://www.jianshu.com/p/c133cb7cac21 讲的不错 命令式UI (how to do) 声明式UI (what to do) what to do 也许有人会说Data Binding不是可以让XML自己"动"起来吗?没有错,Data Binding其实就是Compose诞生之前的一种声明式U方案,谷歌曾…...

友力科技IDC机房搬迁方案流程分享
机房搬迁流程 系统搬迁实施流程包括:准备、拆卸、装运、安装、调试等五个流程,具体如下: 准备:包括相关人员和设备准备、新机房环境准备、网络环境、备份、现场所有设备打标签、模块、设备准备等准备工作。拆卸:主要只核心设备下…...

仿迪恩城市门户分类信息网discuz模板
Discuz x3.3模板 仿迪恩城市门户分类信息网 (GBK) Discuz模板 仿迪恩城市门户分类信息网(GBK)...

Windows 注册表是什么?如何备份注册表?
Windows注册表(Windows Registry)是微软Windows操作系统中的一个重要组件,用于存储系统和应用程序的配置信息和选项。下面就给大家详细讲解一下什么是注册表。 注册表的概念 Windows 注册表是一个集中管理的数据库,存储了系统、…...

B+树与索引解析
文章目录 B树与索引简介几个关键点应用案例场景描述索引创建查询操作更新操作并发处理 Python代码示例 B树与索引简介 B树是一种在计算机科学中广泛使用的自平衡的树数据结构,它能保持数据排序,并且搜索、插入和删除操作的时间复杂度都是O(log n)。B树被…...

华为认证hcna题库背诵技巧有哪些?hcna和hcia有什么区别?
大家都知道华为认证hcna是有题库供考生刷题备考的,但题库中海量的题目想要在短时间背诵下来可并不是一件容易的事情,这就需要我们掌握一定的技巧才行。华为认证hcna题库背诵技巧有哪些? hcna和hcna这二者又有什么区别呢?今天的文章将为大家进行详细解…...

【常用报文状态码】
常见的报文状态码如下 200 OK:客户端请求成功。 301 Moved Permanently:表示请求的资源已经被永久移动到了新的URL上; 302 Found:表示请求的资源已经被临时移动到了新的URL上; 304 Not Modified:表示客户…...

Linux命令详解
1.目录结构 2.history游览历史 3.命令行中的ctrl组合键 4.列出目录的内容 5.修改文件权限chmod 6.文件内容查看 文件管理 7.输出重定向:> 8.管道:| 9.清屏:clear 10.显示当前路径:pwd 11.创建目录:mkdir…...

在阿里云使用Docker部署MySQL服务,并且通过IDEA进行连接
阿里云使用Docker部署MySQL服务,并且通过IDEA进行连接 这里演示如何使用阿里云来进行MySQL的部署,系统使用的是Linux系统 (Ubuntu)。 为什么使用Docker? 首先是因为它的可移植性可以在任何有Docker环境的系统上运行应用,避免了在不通操作系…...

Spring Boot中的国际化(i18n)实现技巧
Spring Boot中的国际化(i18n)实现技巧 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!在开发多语言支持的应用程序时,国际化…...

vite-ts-cesium项目集成mars3d修改相关的包和配置参考
如果vite技术栈下使用原生cesium,请参考下面文件的包和配置修改,想用原生创建的viewer结合我们mars3d的功能的话。 1. package.json文件 "dependencies": {"cesium": "^1.103.0","mars3d": "^3.7.18&quo…...

「树莓派入门」树莓派基础04-VNC连接与配置静态IP
一、VNC连接配置 1. 启用VNC服务 在树莓派上,通过 raspi-config 工具启用VNC服务: sudo raspi-config在配置界面中选择 “Interfacing Options”,然后选择 “VNC” 并启用它。 2. 连接到VNC服务器 在电脑端安装VNC客户端,如V…...

JAVA编程题期末题库【中】
8.计算邮资 程序代码: public static void main(String[] args) {// 计算邮资//if多分支语句//创建对象java.util.Scanner inputnew java.util.Scanner(System.in); //提示输入用户,输入邮件的重量System.out.println("邮件的重量:");int wei…...

【十年JAVA搬砖路】——MYSQL备份使用mysqldump
使用mysqldump 备份 1.创建备份脚本 cat <<EOF > sqlback.sh source ~/.bashrc NLS_DATE_FORMAT"yyyy-mm-dd HH24:MI:SS"; export NLS_DATE_FORMAT NLS_LANGAMERICAN_AMERICA.ZHS16GBK;export NLS_LANGbackuptimedate %Y%m%d%H%M%S /usr/bin/mysqldump -u…...

MetaGPT全面安装与配置指南
文章目录 MetaGPT环境配置1.1 检查Python版本1.2 拉取MetaGPT仓库1.3 拉取源码本地安装1.4 MetaGPT安装成果全流程展示1.5 尝试简单使用 MetaGPT的API调用2.1 本地部署大模型尝试安装必要的依赖下载并配置大模型配置API服务 2.2 讯飞星火API调用获取API密钥安装讯飞星火SDK调用…...

云计算期末综合测试题
云计算综合测试题 单选题填空题判断题简答题 单选题 这里选择题,直接以填空题展示,并给出解析 Bigtable是(Google)开发的分布式存储系统 解析:分布式结构化数据表Bigtable是Google基于GFS和Chubby开发的分布式存储系统…...

vue3-cropperjs图片裁剪工具-用户上传图片截取-(含预览视频)
效果图 上传图片弹窗预览 对于这个上传图片样式可以参考 官方原代码 官网传送入口 Upload 上传 | Element Plus (element-plus.org) <template><el-uploadclass"upload-demo"dragaction"https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6…...

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第48课-可视化控制机器人
【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第48课-可视化控制机器人 使用dtns.network德塔世界(开源的智体世界引擎),策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引…...