原理简述

自贝叶斯定理诞生起,其广泛应用于概率推理领域。贝叶斯定理揭示出自然界一个普遍规律,即两个概率事件之间的联系不是单向的,贝叶斯定理及其公式提出一种处理这种联系的方法论,以至于我们在各个应用领域都可以实践。贝叶斯公式如下所示:

1
P(A|B)=P(B|A)P(A)/P(B)

现分别有 A,B 两个容器:
在容器 A 里分别有 7 个红球和 3 个白球,
在容器 B 里有 1 个红球和 9 个白球,
现已知从这两个容器里任意抽出了一个球,且是红球,
问这个红球是来自容器 A 的概率是多少?   

假设已经抽出红球为事件 B,从容器 A 里抽出球为事件 A,则有:
P(B)=8/20,P(A)=1/2,P(B|A)=7/10,
按照公式,则有:P(A|B)=P(B|A)*P(A)/P(B)=(7/10)*(1/2)*(20/8)=7/8

上述为单一结果集的情况,利用先验概率和条件概率,我们能够反推出在结果集确定的情况下,导致结果集的可能的多个起因的概率,以确定最可能的起因。

要处理的问题

您的账户9572于2013-01-24 16:35:26跨行支付人民币280000.00元,当前余额1023800.40元【中国银行】

上述这条短信内容大家手机里类似的很多,我们有没有可能把他们抓出来分析一下,给自己做个银行交易记录的流水账呢?比如哪张银行卡,什么时间,收入或支出多少,目前余额多少等。

好吧,这个简单。正则匹配吧,建立一个个正则式模板,分段提取出需要的信息,这不失为一个有效办法,但其不足有二:

  • 建立大规模的正则式库,逐一匹配,匹配效率低
  • 正则式需要人工添加,维护成本高

好吧,我承认下文的处理方案任然脱离不了正则式,但可以极大减小维护成本。

正则式能解决什么

经过对大量此类短信的分析,我们可以发现,银行名称,交易时间、交易金额等格式种类有限,可以提供几个比较通用的正则式来提取。目前困难的是怎么区分出交易的类型呢,是收入还是支出?不要忘了,手机里收到的银行短信可不都是这种交易短信,还有大量广告、验证码等短信,如何把这些干扰(或称垃圾)短信区分出来。继续用正则式,那我们需要维护多个词组,确定各自对应的类型。汉语词汇万千,即使此类短信词汇集合大小有限,但多个词的组合数可就是天文数字了,靠纯人工恐怕是玩不转了。

我的解决方案

关键正则提取关键信息–>分词过滤–>贝叶斯分类器

关键正则提取关键信息

利用正则式提取出时间、金额等信息,并从短信中剔除

分词过滤

分词技术由来已久,中文分词也是自然语言处理中一个核心领域。中文由字构成,字成词,字数虽然有限,但字的组合数十分庞大。再加上汉字书写中词间不留空格的习惯,在分词领域,汉字的难度比字母文字大得多。

从最初的机械匹配分词,到基于语法分词,到现在的深度学习,分词技术突飞猛进。科大讯飞、哈工大等单位目前在该领域技术雄厚,大家可以去搜索查阅。由于分词技术不是本文重点,就此略过。分词需要达到的目的是将短信句子分成词组,再通过词性判断,仅保留名词、动词,因为这些词汇具有业务性,包含了对短信分类判断的概率依据。

经过以上处理,假设只剩下跨行、支付、人民币三个词汇。

贝叶斯分类器

  • 推理过程

朴素贝叶斯:单词出现概率相互独立 P(AB) = P(A)P(B)

推理结果:

1
R = argmax𝑃(𝐾|𝑇𝑗)𝑃(𝑇𝑗), 𝑇𝑗∈𝑇

单词集合 K:{ 跨行–KH,支付–ZF,人民币–RMB }

类型 T:收入–S 支出–Z 垃圾-R

根据训练样本(训练样本集需要事先准备好,训练基数足够大,如提前对一批短信进行类型人工识别)

得到T先验概率:P(T)=训练样本中类型为T的短信数目/训练样本短信总数

假设:

1
2
3
P(T=S) = 0.2
P(T=Z) = 0.2
P(T=R) = 0.6

条件概率:P(K|T) = T类型短信中出现K单词的短信数目/ T类型短信总数

假设:

1
2
3
4
5
6
7
8
9
10
11
P(KH|S) = 0.021
P(ZF|S)=0.0002
P(RMB|S)=0.3
P(KH|Z) = 0.032
P(ZF|Z)=0.25
P(RMB|Z)=0.32
P(KH|R) = 0.012
P(ZF|R)=0.022
P(RMB|R)=0.33

1
2
3
4
5
P(S|K) = P(S|KH, ZF, RMB) = P(KH, ZF, RMB|S)P(S)/P(KH, ZF, RMB) = C * P(KH|S)P(ZF|S)P(RMB|S)*P(S)=C*0.021*0.0002*0.3*0.2=2.52E-7*C
P(Z|K) = P(Z|KH, ZF, RMB) = P(KH, ZF, RMB|Z)P(Z)/P(KH, ZF, RMB) = C * P(KH|Z)P(ZF|Z)P(RMB|Z)*P(Z)=C*0.032*0.25*0.32*0.2=5.12E-4*C
P(R|K) = P(R|KH, ZF, RMB) = P(KH, ZF, RMB|R)P(R)/P(KH, ZF, RMB) = C * P(KH|R)P(ZF|R)P(RMB|R)*P(R)=C*0.012*0.022*0.33*0.6=5.23E-5*C

三者中P(Z|K)最大,则该条短信判为支出

  • 推理改进

假设出现一个新单词,训练样本中并未出现(词典中不存在),若继续按以上步骤进行,则出现条件概率为0的情况,此时计算结果均为0,无法进行大小判断。

M估计

P(K|T) = (N𝐾 + mp)/(N + m)

N是T类型短信总数,N𝐾是T类型中K单词出现次数,m成为等价样本大小的参数,而p是用户指定的参数。如果没有训练集(即N=0),则P(K|T)=p, 因此p可以看作是在类型T的短信样本中观察单词K的先验概率。等价样本m大小决定先验概率p和观测概率N𝐾/N之间的平衡

多项式模型

先验概率P(T) = T类型短信中单词统计总数/全部短信中单词统计总数

条件概率P(K|T)=(T类型短信中单词K统计总数 +1)/(T类型短信中单词统计总数+|V|)

V是训练样本的单词表(即抽取单词,单词出现多次,只算一个),|V|则表示训练样本包含多少种单词。

在这里,m=|V|, p=1/|V|

  • 训练集存储

数据表结构如下所示

短信类型计数表

类型 单词总量
收入 12
支出 13
垃圾 23

单词计数表

单词 收入短信中该单词出现次数 支出短信中该单词出现次数 垃圾短信中该单词出现次数
消费 12 12 32
工资 123 2 12
转账 23 32 2

整个识别流程介绍完毕,主要是理论上的。在实际运用中还需结合实际情况改进具体流程。