京公网安备 11010802034615号
经营许可证编号:京B2-20210330
一、概述
朴素贝叶斯分类算法是基于概率论中的贝叶斯公式得到的,也是比较常用的一种算法,而朴素代表的是属性之间的独立性,这样联合概率可以转换成各概率分量的乘积。
二、算法思想
其实这个算法的思想就是贝叶斯公式,如果不是很了解也没什么关系,只要看点例子就明白了,但由于这里只想给大家提供一些实用代码,因此就不仔细说例子了,《机器学习实战》中的那个灰石头的例子就不错,另外,如果还感觉不是很清楚,推荐看一下《数据挖掘导论》中贝叶斯分类器部分。
三、实例算法
不说废话了,现在开始介绍朴素贝叶斯的matlab代码编写,这里我们的目标是利用朴素贝叶斯进行文档分类,即确定该文档是侮辱类还是非侮辱类,分别以1和0表示。
1. 创建测试数据
%% 建立测试数据
postingList = [{‘my dog has flea problems help please’};
{‘maybe not take him to dog park stupid’};
{‘my dalmation is so cute I love him’};
{‘stop posting stupid worthless garbage’};
{‘mr licks ate my steak how to stop him’};
{‘quit buying worthless dog food stupid’}];
classVec = [0, 1, 0, 1, 0, 1];
意义应该还是比较明确的,就是说2,4,6是带有侮辱性语句的文档
2. 创建无重复单词的列表
%% 创建无重复单词的列表
[m, n] = size(postingList);
VocabList = [];
for i = 1: m
tempstr = postingList{i};
str_split = regexp(tempstr, ‘W*s+’, ‘split’);
VocabList = [VocabList, str_split];
end
VocabList_unique = unique(VocabList);
可以看一下单词列表
>> VocabList_unique
VocabList_unique =
Columns 1 through 8
‘I’ ‘ate’ ‘buying’ ‘cute’ ‘dalmation’ ‘dog’ ‘flea’ ‘food’
Columns 9 through 16
‘garbage’ ‘has’ ‘help’ ‘him’ ‘how’ ‘is’ ‘licks’ ‘love’
Columns 17 through 24
‘maybe’ ‘mr’ ‘my’ ‘not’ ‘park’ ‘please’ ‘posting’ ‘problems’
Columns 25 through 32
‘quit’ ‘so’ ‘steak’ ‘stop’ ‘stupid’ ‘take’ ‘to’ ‘worthless’
3. 创建列表向量
由于单词不好进行表述,我们需要根据单词列表创建一个向量表示列表中的单词是否出现,出现用1表示,未出现用0表示。
setOfWords2Vec.m文件如下
function wordsVec = setOfWords2Vec(vocabList, inputSet)
vocabList = unique(vocabList);
inputSet = unique(inputSet);
Listnum = length(vocabList);
inputnum = length(inputSet);
wordsVec = zeros(1, Listnum);
for i = 1: inputnum
for j = 1: Listnum
if (strcmp(vocabList{j}, inputSet{i}))
wordsVec(j) = 1;
end
end
end
列表向量测试代码如下
%% 创建列表向量测试
tempstr = postingList{1};
str_split = regexp(tempstr, ‘W*s+’, ‘split’);
wordsVec = setOfWords2Vec(VocabList_unique, str_split);
测试结果如下
wordsVec =
Columns 1 through 14
0 0 0 0 0 1 1 0 0 1 1 0 0 0
Columns 15 through 28
0 0 0 0 1 0 0 1 0 1 0 0 0 0
Columns 29 through 32
0 0 0 0
上面的意思是测试postingList第一句’my dog has flea problems help please’
在单词表中的描述,对照上面的单词列表可以看到结果是正确的,比如wordsVec中的第六第七项为1,在单词表中表示的是dog 和 flea,这连个此时在上面那句话中出现的。
4. 贝叶斯分类函数编写
trainNB0.m文件
function [p0Vect, p1Vect, pAbusive] = trainNB0(trainMatrix, trainCategory)
[m, n] = size(trainMatrix);
pAbusive = sum(trainCategory) / m;
p1words = trainMatrix(find(trainCategory), :);
p0words = trainMatrix(find(1 – trainCategory), :);
p0wordscount = sum(p0words, 1) + 1; % 加1是为了防止出现0概率
p1wordscount = sum(p1words, 1) + 1;
p0Vect = log(p0wordscount ./ sum(p0wordscount));
p1Vect = log(p1wordscount ./ sum(p1wordscount));
这段代码还是要说明一下的
(1)注释位置那句对每个单词的出现初始化为1,就是说就算单词没出现,也将其计算为1,这是防止出现0概率,导致乘积为0。当然避免这个的方法有很多,每本书都不太一样,这里的+1采用的是Laplace平滑方法。
(2)最后算概率加了个log是减少其动态范围。
这两个都是为了实际应用对代码进行的修改,也就是说,就基本原理而言,不需要+1和增加log。
下面,我们对这个代码进行测试
%% 测试trainNB0
trainMatrix = [];
for i = 1: m
tempstr = postingList{i};
str_split = regexp(tempstr, ‘W*s+’, ‘split’);
wordsVec = setOfWords2Vec(VocabList_unique, str_split);
trainMatrix = [trainMatrix;wordsVec];
end
[p0V, p1V, pAb] = trainNB0(trainMatrix, classVec);
p0V代表0分类下,每个单词的出现概率,也就是先验概率(由于用了log,所以是负数,并且由于+1,故没有无穷大项目)
p0V =
Columns 1 through 8
-3.3322 -3.3322 -4.0254 -3.3322 -3.3322 -3.3322 -3.3322 -4.0254
Columns 9 through 16
-4.0254 -3.3322 -3.3322 -2.9267 -3.3322 -3.3322 -3.3322 -3.3322
Columns 17 through 24
-4.0254 -3.3322 -2.6391 -4.0254 -4.0254 -3.3322 -4.0254 -3.3322
Columns 25 through 32
-4.0254 -3.3322 -3.3322 -3.3322 -4.0254 -4.0254 -3.3322 -4.0254
p1V意义类似
p1V =
Columns 1 through 8
-3.9318 -3.9318 -3.2387 -3.9318 -3.9318 -2.8332 -3.9318 -3.2387
Columns 9 through 16
-3.2387 -3.9318 -3.9318 -3.2387 -3.9318 -3.9318 -3.9318 -3.9318
Columns 17 through 24
-3.2387 -3.9318 -3.9318 -3.2387 -3.2387 -3.9318 -3.2387 -3.9318
Columns 25 through 32
-3.2387 -3.9318 -3.9318 -3.2387 -2.5455 -3.2387 -3.2387 -2.8332
pAb代表的是分类为1的文件占所有文件的比例
pAb = 0.5
这个很明显,因为测试数据中有三个分类为1,并且一个有6项。
5. 分类测试
训练部分的代码已经写完了,下面我们的分类器就可以使用了,利用贝叶斯公式计算p(c | w)并比较大小可以确定分类c。
对于本例来说
p(w|0) = 待分类语句中每个单词在0类出现的概率的乘积
p(w|1) = 待分类语句中每个单词在1类出现的概率的乘积
p(0|w) = p(w|0)*p(0) / p(w)
p(1|w) = p(w|1)*p(1) / p(w)
如果p(0|w) > p(1|w)分类就是0,反之就是1
代码如下
classifyNB.m
function classRes = classifyNB(vec2Classify, p0Vec, p1Vec, pClass1)
p1 = sum(vec2Classify .* p1Vec) + log(pClass1);
p0 = sum(vec2Classify .* p0Vec) + log(1 – pClass1);
if p1 > p0
classRes = 1;
else
classRes = 0;
end
说明:
由于前面的概率是以log形式表示的,所以乘积就变成了加法,还有就是p(w)不影响比较结果,因此未予计算。
测试代码如下
%% 进行分类测试
testEntry = ‘love my dalmation’;
str_split = regexp(testEntry, ‘W*s+’, ‘split’);
wordsVec1 = setOfWords2Vec(VocabList_unique, str_split);
classRes1 = classifyNB(wordsVec1, p0V, p1V, pAb);
testEntry = ‘stupid garbage’;
str_split = regexp(testEntry, ‘W*s+’, ‘split’);
wordsVec2 = setOfWords2Vec(VocabList_unique, str_split);
classRes2 = classifyNB(wordsVec2, p0V, p1V, pAb);
结果就是
classRes1 = 0
classRes2 = 1
也就是说,分类确定第二句带有侮辱性,其实从其中的stupid就可以看出
四、算法应用
前面就说过,这个算法应用很广,《实战》中给出了两个实例,一个是垃圾邮件分类,这个和我们这里做的文本分类非常类似,另外一个就是从个人广告中获取区域倾向。都是平时我们经常使用的功能,如果有兴趣可以自己编着试一下,很多还是挺有意思的。
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
CDA数据分析师 出品 作者:李诗怡 定义: 用户增长核心分析框架,刻画用户从接触产品到自发推荐的全生命周期,五个递进环节构建 ...
2026-09-15在数字化营销与精细化用户运营时代,企业传统的广撒网式营销模式成本高、转化率低,已无法适配精准商业竞争需求。客户画像作为大 ...
2026-09-15 很多数据分析师精通描述性统计,能熟练计算均值、中位数、标准差,但当被问到“用500个样本如何推断10万用户的真实满意度” ...
2026-09-15在MySQL数据库数据查询与数据分析中,GROUP BY与ORDER BY是使用频率极高的核心关键字。二者语法结构相似,常搭配使用,但核心功 ...
2026-09-14随着数字化治理、智慧运营、数字孪生技术的普及,数字体征成为衡量业务状态、系统运行、城市治理与企业经营健康度的核心体系。数 ...
2026-09-14 很多数据分析师沉迷于复杂的模型和算法,却忽略了数据分析的一项基础能力——描述性统计。事实上,大量商业分析问题,用描述 ...
2026-09-14在MySQL数据库运维与开发实践中,经常出现一种典型现象:数据库实际存储的数据量很小,数据表条数少、文件体积低,但服务器整体 ...
2026-09-11 很多数据分析师能熟练计算均值、标准差,但当被问到“总体和样本有什么区别”“参数和统计量有什么关系”“数据级别的高低如 ...
2026-09-11CDA数据分析师 出品 作者:李诗怡 定义: 将同一时间段内因具备相同属性或共同经历的用户划分为群体,分析其留存与生命周期价值 ...
2026-09-11在零售、商超、餐饮、线下门店等实体商业运营中,客流与销售额是衡量门店经营状态的两大核心指标。销售额是门店经营的最终结果, ...
2026-09-10在数据可视化体系中,柱形图是最基础、应用最广泛的图表类型,其中**累计柱形图(堆积柱状图)**是兼顾整体总量与内部结构的核心 ...
2026-09-10 许多数据分析师精通Excel函数和SQL查询,但当面对一张上万行的销售明细表,要快速回答“哪个地区销量最高”“哪款产品增长最 ...
2026-09-10在Python Pandas数据分析中,DataFrame是承载结构化数据的核心载体,数据清洗、数据修正、条件赋值、字段更新等实操场景,都离不 ...
2026-09-09 很多数据分析师掌握了Excel函数、会写SQL查询,但当被问到“数据从哪里来”“数据加工有哪些步骤”“如何使用分析工具连接数 ...
2026-09-09卡方检验(Chi-Square Test)是统计学中针对分类数据的经典显著性检验方法,核心用于判断两个离散分类变量是否相互独立、数据实 ...
2026-09-09CDA数据分析师 出品 作者:李诗怡 1. 销售漏斗阶段判断 题目:销售漏斗模型中,通过广告、社交媒体等方式触达品牌信息(如浏览品 ...
2026-09-07在Python数据分析中,Pandas库的DataFrame是最核心、最常用的结构化数据表对象,类似于Excel的二维表格,具备规整的行列结构、字 ...
2026-09-07在数据分析、经营复盘、业绩预测与经济统计工作中,平均增速(平均增长率)是衡量数据长期变化趋势、业务发展快慢的核心指标。不 ...
2026-09-07 很多数据分析师精通Excel单元格操作,但当被问到“表结构数据的基本处理单位是什么”“字段和记录的本质区别”“为什么表结 ...
2026-09-07随着大数据技术的快速发展,商业竞争逐步从传统的经验式经营转变为数据驱动的精细化运营。海量的用户行为数据、交易数据、运营数 ...
2026-09-04