目录
一、朴素贝叶斯算法
朴素贝叶斯算法是一种基于贝叶斯定理的分类方法,它通过统计训练数据来求解分类问题。其核心是贝叶斯定理,可以将难以计算的条件概率转换为容易计算的概率。
朴素:所有的特征都是独立的。也就是说没有哪个属性变量对于决策结果来说占有着较大的比重,也没有哪个属性变量对于决策结果占有着较小的比重。虽然这个简化方式在一定程度上降低了贝叶斯分类算法的分类效果,但是在实际的应用场景中,极大地简化了贝叶斯方法的复杂性。
二、贝叶斯公式
P(A):事件A 发生的概率,也称先验概率。
P(B):事件B发生的概率。
P(A|B):表示B发生的情况下A发生的概率, 也被称为后验概率。
P(B|A): A发生的条件下,B发生的概率,也称似然性。
贝叶斯公式的主要用途在于通过已知的三个概率来推测第四个概率。
三、垃圾邮件过滤
这是一个二分类问题,即邮件要么是垃圾邮件,要么不是。我们可以使用朴素贝叶斯算法来解决这个问题。
1.实现步骤
数据预处理:
-
数据预处理:首先,我们需要将邮件文本转换为特征向量。
-
训练模型:使用朴素贝叶斯算法来训练模型。我们计算每个类别下每个特征的条件概率。
-
预测:对于一个新的邮件,我们计算它属于每个类别的概率,然后选择概率最大的类别作为预测结果。
2.实验
1.数据处理:
垃圾邮件和正常邮件各25封,从中随机拿出5封作为测试。
import os
import re
from collections import defaultdict
from math import log
def preprocess_text(text):
# 将文本转换为小写
text = text.lower()
# 移除非字母字符
text = re.sub(r'[^a-z\u4e00-\u9fa5\s]', '', text)
# 分词
words = text.split()
return words
read_files_in_folder
函数:用于读取文件夹中的所有文件
def read_files_in_folder(folder_path, encoding='utf-8'):
files = os.listdir(folder_path)
emails = []
for file_name in files:
with open(os.path.join(folder_path, file_name), 'r', encoding=encoding, errors='ignore') as file:
content = file.read()
emails.append(content)
return emails
train_naive_bayes
函数:则使用这些邮件内容来计算先验概率和每个单词在垃圾邮件和正常邮件中的频率
def train_naive_bayes(spam_folder, ham_folder):
spam_emails = read_files_in_folder(spam_folder, encoding='ISO-8859-1')
ham_emails = read_files_in_folder(ham_folder, encoding='ISO-8859-1')
# 计算先验概率
total_emails = len(spam_emails) + len(ham_emails)
prior_spam = len(spam_emails) / total_emails
prior_ham = len(ham_emails) / total_emails
# 初始化词频统计
spam_word_count = defaultdict(int)
ham_word_count = defaultdict(int)
# 遍历垃圾邮件
for email in spam_emails:
words = preprocess_text(email)
for word in words:
spam_word_count[word] += 1
# 遍历正常邮件
for email in ham_emails:
words = preprocess_text(email)
for word in words:
ham_word_count[word] += 1
return prior_spam, prior_ham, spam_word_count, ham_word_count
def classify_naive_bayes(email, prior_spam, prior_ham, spam_word_count, ham_word_count):
words = preprocess_text(email)
# 初始化概率
log_prob_spam = log(prior_spam)
log_prob_ham = log(prior_ham)
# 计算垃圾邮件概率
for word in words:
log_prob_spam += log((spam_word_count[word] + 1) / (sum(spam_word_count.values()) + len(spam_word_count)))
# 计算正常邮件概率
for word in words:
log_prob_ham += log((ham_word_count[word] + 1) / (sum(ham_word_count.values()) + len(ham_word_count)))
# 返回分类结果和概率
prob_spam = log_prob_spam / (log_prob_spam + log_prob_ham)
prob_ham = log_prob_ham / (log_prob_spam + log_prob_ham)
return prob_spam, prob_ham
if __name__ == '__main__':
# 指定训练集和测试集的文件夹路径
spam_folder = r'D:\University\Junior year\Machine learning\Bayes\email\spam'
ham_folder = r'D:\University\Junior year\Machine learning\Bayes\email\ham'
test_folder = r'D:\University\Junior year\Machine learning\Bayes\email\test'
2. 训练模型
prior_spam, prior_ham, spam_word_count, ham_word_count = train_naive_bayes(spam_folder, ham_folder)
3.遍历测试集并输出概率和结论
test_emails = read_files_in_folder(test_folder, encoding='ISO-8859-1')
for idx, email in enumerate(test_emails, 1):
prob_spam, prob_ham = classify_naive_bayes(email, prior_spam, prior_ham, spam_word_count, ham_word_count)
print(f"Email {idx}:")
print(f"Probability of spam: {prob_spam:.4f}")
print(f"Probability of ham: {prob_ham:.4f}")
# 输出分类结果
if prob_spam > prob_ham:
print("Result: This email is spam")
else:
print("Result: This email is ham")
print()
结果截图:
四、总结
朴素贝叶斯的优缺点:
优点:简单高效,易于理解实现。对小规模数据表现良好,适用于多分类问题。
缺点:假设特征独立, 朴素贝叶斯算法的一个主要假设是所有特征都是相互独立的。在现实世界的某些情况下,这个假设可能并不成立,从而影响了分类的准确性。
尽管朴素贝叶斯有其局限性,但在许多实际应用中,它仍然是一个简单而有效的分类算法。根据具体问题的性质,以及数据的特点,选择合适的分类算法非常重要。OVER