Python递归实现朴素贝叶斯算法

2023-04-16 00:00:00 算法 递归 朴素

朴素贝叶斯算法是一种基于贝叶斯定理的分类算法。在这个算法中,我们通过统计各个特征对于不同分类的概率来确定数据属于哪一类。算法本身很简单,但是效果却很不错,被广泛应用于文本分类、情感分析等领域。

递归实现朴素贝叶斯算法的代码如下:

import math

class NaiveBayes:
    def __init__(self):
        self.words = set()
        self.labels = {}
        self.word_count = {}
        self.word_prob = {}
        self.label_prob = {}

    def train(self, data):
        # 接收数据,进行训练
        for d in data:
            label = d[0]  # 标签
            words = set(d[1:])  # 句子中出现的词
            if label not in self.labels:
                self.labels[label] = 0
                self.word_count[label] = {}
            self.labels[label] += 1
            for w in words:
                if w not in self.word_count[label]:
                    self.word_count[label][w] = 0
                    self.words.add(w)
                self.word_count[label][w] += 1

        # 计算词频和标签概率
        total_count = sum(self.labels.values())
        for label in self.labels:
            self.label_prob[label] = self.labels[label] / total_count
            for word in self.words:
                count = self.word_count[label].get(word, 0)
                if word not in self.word_prob:
                    self.word_prob[word] = {}
                self.word_prob[word][label] = (count + 1) / (self.labels[label] + 2)

    def classify(self, sentence):
        # 对句子进行分类
        probs = {}
        words = set(sentence.split())
        for label in self.labels:
            probs[label] = math.log(self.label_prob[label])
            for word in words:
                if word in self.word_prob:
                    probs[label] += math.log(self.word_prob[word].get(label, 1/(self.labels[label]+2)))
                else:
                    probs[label] += math.log(1/(self.labels[label]+2))

        return max(probs, key=probs.get)

接下来解释一下每个方法的功能:

  • __init__: 初始化一些变量,包括该分类器涉及到的所有词语、所有标签、每个标签下出现的每个词语的数量以及每个词语在每个标签下的概率和每个标签的概率。
  • train: 对输入的数据进行训练。训练的过程包括对每个标签出现的次数进行统计,以及对每个标签下出现的每个词语的数量进行统计。同时还要计算每个词语在每个标签下的概率和每个标签的概率。
  • classify: 对输入的句子进行分类。对于句子中出现的每个词语,计算它在每个标签下的概率并取对数,再加上该标签的概率。最后返回概率最大的标签。

这里要注意一下的是,计算每个词语在每个标签下的概率时,我们使用了拉普拉斯平滑。也就是说,我们将每个词语在每个标签下出现的数量加上一,将每个标签下出现的所有词语的数量加上二,使得每个词语在每个标签下的概率不为零。

我们可以看一个小例子来理解这个算法:

nb = NaiveBayes()
data = [
    ('spam', 'send me your password'),
    ('spam', 'send me your bank account number'),
    ('spam', 'add $1000 to your account today'),
    ('normal', 'Hi, how are you?'),
    ('normal', 'I am at home'),
    ('normal', 'See you later'),
]
nb.train(data)
print(nb.classify('send me your password'))
# 输出:spam
print(nb.classify('I am at home'))
# 输出:normal

在这个例子中,我们用一些简单的数据来训练分类器,然后用一些句子来测试分类器的准确性。

相关文章