朴素贝叶斯算法matlab实例
时间: 2023-10-31 09:41:05 浏览: 131
朴素贝叶斯算法是一种基于贝叶斯定理的分类算法,通常应用于文本分类、垃圾邮件过滤等领域。下面是一个基于matlab的简单实现示例。
1.准备数据集
假设我们有一个数据集,其中包含5个文档,每个文档都有一个分类标签:spam(垃圾邮件)或ham(正常邮件)。我们的任务是根据文档中出现的单词来预测文档的分类。
spam ham hello world spam hello hello goodbye spam world
2.建立词汇表
我们需要将所有文档中出现的单词整理成一个词汇表,用于后续计算。可以使用matlab中的unique函数实现:
docs = {'spam', 'ham', 'hello', 'world', 'spam', 'hello', 'hello', 'goodbye', 'spam', 'world'};
vocab = unique(docs)
词汇表vocab的结果为:
vocab =
1×5 cell array
{'goodbye'} {'ham'} {'hello'} {'spam'} {'world'}
3.计算单词出现次数
接下来,我们需要计算每个文档中每个单词出现的次数。可以使用matlab中的histcounts函数实现:
doc_counts = histcounts(find(ismember(vocab, docs)), length(vocab))
doc_counts的结果为:
doc_counts =
0 1 3 3 2
其中,第一个数字表示单词“goodbye”在所有文档中出现的次数(0次),第二个数字表示单词“ham”在所有文档中出现的次数(1次),以此类推。
4.计算先验概率
根据贝叶斯定理,我们需要计算先验概率P(spam)和P(ham)。在这个示例中,我们有3个spam文档和2个ham文档,因此:
prior_spam = 3/5
prior_ham = 2/5
5.计算条件概率
接下来,我们需要计算条件概率P(word|spam)和P(word|ham),即在spam和ham文档中出现某个单词的概率。可以使用一个计算函数实现:
function [cond_prob_spam, cond_prob_ham] = calc_cond_prob(vocab, docs, doc_counts, prior_spam, prior_ham)
num_docs = length(docs);
num_words = length(vocab);
cond_prob_spam = zeros(1, num_words);
cond_prob_ham = zeros(1, num_words);
for i=1:num_words
word = vocab{i};
word_count_spam = 0;
word_count_ham = 0;
for j=1:num_docs
if strcmp(word, docs{j})
if strcmp(docs{j+1}, 'spam')
word_count_spam = word_count_spam + doc_counts(i);
else
word_count_ham = word_count_ham + doc_counts(i);
end
end
end
cond_prob_spam(i) = (word_count_spam + 1) / (sum(doc_counts(ismember(docs, 'spam'))) + num_words);
cond_prob_ham(i) = (word_count_ham + 1) / (sum(doc_counts(ismember(docs, 'ham'))) + num_words);
end
end
该函数计算每个单词在spam和ham文档中出现的次数,并计算相应的条件概率。在计算中,我们使用了拉普拉斯平滑(Laplace smoothing)技术,避免了概率为0的情况。
6.预测分类
现在,我们可以使用贝叶斯公式进行分类预测。假设我们有一个新的文档:
new_doc = {'hello', 'world', 'spam'}
我们需要计算P(spam|new_doc)和P(ham|new_doc),然后比较这两个概率大小,选择概率更大的分类作为预测结果。可以使用一个计算函数实现:
function [prob_spam, prob_ham] = predict_class(new_doc, vocab, cond_prob_spam, cond_prob_ham, prior_spam, prior_ham)
num_words = length(vocab);
prob_spam = log(prior_spam);
prob_ham = log(prior_ham);
for i=1:length(new_doc)
word = new_doc{i};
if ismember(word, vocab)
idx = find(strcmp(vocab, word));
prob_spam = prob_spam + log(cond_prob_spam(idx));
prob_ham = prob_ham + log(cond_prob_ham(idx));
end
end
prob_spam = exp(prob_spam);
prob_ham = exp(prob_ham);
end
该函数计算P(spam|new_doc)和P(ham|new_doc),并使用log转换避免了数值下溢的问题。
7.完整代码
最后,我们将上述所有步骤整合到一个完整的matlab代码中:
docs = {'spam', 'ham', 'hello', 'world', 'spam', 'hello', 'hello', 'goodbye', 'spam', 'world'};
vocab = unique(docs);
doc_counts = histcounts(find(ismember(vocab, docs)), length(vocab));
prior_spam = 3/5;
prior_ham = 2/5;
[cond_prob_spam, cond_prob_ham] = calc_cond_prob(vocab, docs, doc_counts, prior_spam, prior_ham);
new_doc = {'hello', 'world', 'spam'};
[prob_spam, prob_ham] = predict_class(new_doc, vocab, cond_prob_spam, cond_prob_ham, prior_spam, prior_ham)
运行代码,得到预测结果:
prob_spam = 0.6029
prob_ham = 0.3971
由于P(spam|new_doc) > P(ham|new_doc),因此该文档被预测为垃圾邮件。
阅读全文