Python实现的朴素贝叶斯算法经典示例【测试可用】
朴素贝叶斯算法是一种常见的分类算法,它基于贝叶斯定理和特征条件独立假设,可以用于文本分类、垃圾邮件过滤、情感分析等领域。在本文中,我们将介绍Python实现的朴素贝叶斯算法经典示例,并提供测试代码。
朴素贝叶斯算法原理
朴素贝叶斯算法是一种基于贝叶斯定理的分类算法,它假设每个特征之间是相互独立的,即特征之间不存在相关性。根据贝叶斯定理,我们可以得到以下公式:
$$P(c|x_1,x_2,…,x_n)=\frac{P(c)P(x_1,x_2,…,x_n|c)}{P(x_1,x_2,…,x_n)}$$
其中,$c$表示类别,$x_1,x_2,…,x_n$表示特征。我们需要计算$P(c|x_1,x_2,…,x_n)$的概率,即在给定特征$x_1,x_2,…,x_n$的条件下,类别$c$的概率。根据贝叶斯定理,我们可以将其转化为以下公式:
$$P(c|x_1,x_2,…,x_n)=\frac{P(c)P(x_1,x_2,…,x_n|c)}{\sum_{i}P(c_i)P(x_1,x_2,…,x_n|c_i)}$$
其中,$c_i$表示所有类别,$\sum_{i}P(c_i)P(x_1,x_2,…,x_n|c_i)$表示所有类别的概率和。
朴素贝叶斯算法示例
示例1:使用朴素贝叶斯算法进行文本分类
在这个示例中,我们将使用朴素贝叶斯算法对文本进行分类。我们首先需要准备训练数据和测试数据。训练数据包含多个文本和对应的类别,测试数据包含多个文本。我们需要使用训练数据训练模型,并使用测试数据测试模型的准确率。
import os
import re
import math
from collections import defaultdict
class NaiveBayesClassifier:
def __init__(self):
self.vocab = set() # 词汇表
self.labels = set() # 类别集合
self.label_word_count = defaultdict(int) # 每个类别中单词的数量
self.label_count = defaultdict(int) # 每个类别的数量
self.word_count = 0 # 单词总数
def train(self, data):
for label, text in data:
self.labels.add(label)
self.label_count[label] += 1
for word in self.tokenize(text):
self.vocab.add(word)
self.label_word_count[label, word] += 1
self.word_count += 1
def classify(self, text):
probabilities = {}
for label in self.labels:
probabilities[label] = math.log(self.label_count[label] / sum(self.label_count.values()))
for word in self.tokenize(text):
probabilities[label] += math.log((self.label_word_count[label, word] + 1) / (self.label_count[label] + len(self.vocab)))
return max(probabilities, key=probabilities.get)
def tokenize(self, text):
text = text.lower()
text = re.sub(r'[^\w\s]', '', text)
return text.split()
def load_data(path):
data = []
for label in os.listdir(path):
for file in os.listdir(os.path.join(path, label)):
with open(os.path.join(path, label, file), 'r', encoding='utf-8') as f:
text = f.read()
data.append((label, text))
return data
train_data = load_data('train')
test_data = load_data('test')
classifier = NaiveBayesClassifier()
classifier.train(train_data)
correct = 0
for label, text in test_data:
if classifier.classify(text) == label:
correct += 1
accuracy = correct / len(test_data)
print('Accuracy:', accuracy)
在这个示例中,我们首先定义了一个名为NaiveBayesClassifier的类,它包含train和classify两个方法。train方法用于训练模型,classify方法用于对文本进行分类。我们使用defaultdict(int)来初始化label_word_count和label_count,它们分别表示每个类别中单词的数量和每个类别的数量。我们使用set()来初始化vocab和labels,它们分别表示词汇表和类别集合。我们使用tokenize方法将文本转换为单词列表。
在train方法中,我们遍历训练数据,对每个文本进行处理。我们使用add方法将类别添加到labels集合中,使用+=运算符将类别的数量加1。我们使用tokenize方法将文本转换为单词列表,遍历单词列表,对每个单词进行处理。我们使用add方法将单词添加到vocab集合中,使用+=运算符将单词在该类别中的数量加1,使用+=运算符将单词总数加1。
在classify方法中,我们首先定义一个空字典probabilities,用于存储每个类别的概率。我们遍历labels集合,对每个类别进行处理。我们使用math.log计算类别的先验概率。我们使用tokenize方法将文本转换为单词列表,遍历单词列表,对每个单词进行处理。我们使用math.log计算单词在该类别中的条件概率。最后,我们返回概率最大的类别。
在load_data方法中,我们遍历训练数据或测试数据,对每个文本进行处理。我们使用os.listdir获取目录下的所有文件名,使用os.path.join拼接文件路径,使用with语句打开文件,使用read方法读取文件内容,将类别和文本添加到data列表中。
在主程序中,我们首先使用load_data方法加载训练数据和测试数据。我们使用NaiveBayesClassifier类创建一个分类器对象classifier,并使用train方法训练模型。我们遍历测试数据,对每个文本进行处理,使用classify方法对文本进行分类。我们使用if语句判断分类结果是否正确,使用+=运算符将正确分类的数量加1。最后,我们计算准确率并输出结果。
示例2:使用朴素贝叶斯算法进行垃圾邮件过滤
在这个示例中,我们将使用朴素贝叶斯算法对邮件进行分类,判断是否为垃圾邮件。我们需要准备训练数据和测试数据,训练数据包含多个邮件和对应的类别,测试数据包含多个邮件。我们需要使用训练数据训练模型,并使用测试数据测试模型的准确率。
import os
import re
import math
from collections import defaultdict
class NaiveBayesClassifier:
def __init__(self):
self.vocab = set() # 词汇表
self.labels = set() # 类别集合
self.label_word_count = defaultdict(int) # 每个类别中单词的数量
self.label_count = defaultdict(int) # 每个类别的数量
self.word_count = 0 # 单词总数
def train(self, data):
for label, text in data:
self.labels.add(label)
self.label_count[label] += 1
for word in self.tokenize(text):
self.vocab.add(word)
self.label_word_count[label, word] += 1
self.word_count += 1
def classify(self, text):
probabilities = {}
for label in self.labels:
probabilities[label] = math.log(self.label_count[label] / sum(self.label_count.values()))
for word in self.tokenize(text):
probabilities[label] += math.log((self.label_word_count[label, word] + 1) / (self.label_count[label] + len(self.vocab)))
return max(probabilities, key=probabilities.get)
def tokenize(self, text):
text = text.lower()
text = re.sub(r'[^\w\s]', '', text)
return text.split()
def load_data(path):
data = []
for label in os.listdir(path):
for file in os.listdir(os.path.join(path, label)):
with open(os.path.join(path, label, file), 'r', encoding='utf-8') as f:
text = f.read()
data.append(('spam' if label == 'spam' else 'ham', text))
return data
train_data = load_data('train')
test_data = load_data('test')
classifier = NaiveBayesClassifier()
classifier.train(train_data)
correct = 0
for label, text in test_data:
if classifier.classify(text) == label:
correct += 1
accuracy = correct / len(test_data)
print('Accuracy:', accuracy)
在这个示例中,我们首先定义了一个名为NaiveBayesClassifier的类,它包含train和classify两个方法。train方法用于训练模型,classify方法用于对邮件进行分类。我们使用defaultdict(int)来初始化label_word_count和label_count,它们分别表示每个类别中单词的数量和每个类别的数量。我们使用set()来初始化vocab和labels,它们分别表示词汇表和类别集合。我们使用tokenize方法将邮件转换为单词列表。
在train方法中,我们遍历训练数据,对每个邮件进行处理。我们使用add方法将类别添加到labels集合中,使用+=运算符将类别的数量加1。我们使用tokenize方法将邮件转换为单词列表,遍历单词列表,对每个单词进行处理。我们使用add方法将单词添加到vocab集合中,使用+=运算符将单词在该类别中的数量加1,使用+=运算符将单词总数加1。
在classify方法中,我们首先定义一个空字典probabilities,用于存储每个类别的概率。我们遍历labels集合,对每个类别进行处理。我们使用math.log计算类别的先验概率。我们使用tokenize方法将邮件转换为单词列表,遍历单词列表,对每个单词进行处理。我们使用math.log计算单词在该类别中的条件概率。最后,我们返回概率最大的类别。
在load_data方法中,我们遍历训练数据或测试数据,对每个邮件进行处理。我们使用os.listdir获取目录下的所有文件名,使用os.path.join拼接文件路径,使用with语句打开文件,使用read方法读取文件内容,将类别和邮件添加到data列表中。我们将垃圾邮件的类别设置为’spam’,将正常邮件的类别设置为’ham’。
在主程序中,我们首先使用load_data方法加载训练数据和测试数据。我们使用NaiveBayesClassifier类创建一个分类器对象classifier,并使用train方法训练模型。我们遍历测试数据,对每个邮件进行处理,使用classify方法对邮件进行分类。我们使用if语句判断分类结果是否正确,使用+=运算符将正确分类的数量加1。最后,我们计算准确率并输出结果。