补充朴素贝叶斯 (CNB) 算法
朴素贝叶斯算法是一组非常流行和常用的机器学习算法,用于分类。朴素贝叶斯算法有许多不同的实现方式,如高斯朴素贝叶斯、多项朴素贝叶斯等。要了解更多关于朴素贝叶斯的基础知识,您可以点击此链接。
补充朴素贝叶斯在某种程度上是对标准多项朴素贝叶斯算法的改编。多项朴素贝叶斯在不平衡数据集上表现不佳。不平衡数据集是某些类的示例数高于属于其他类的示例数的数据集。这意味着示例的分布不均匀。这种类型的数据集可能很难使用,因为模型很容易过度拟合这些数据,以支持具有更多示例的类。
CNB的工作原理:
Complement Naive Bayes 特别适合处理不平衡的数据集。在补充朴素贝叶斯中,我们不是计算某个项目属于某个类别的概率,而是计算该项目属于所有类别的概率。这是补语这个词的字面量意思,因此被称为 Complement Naive Bayes。
算法的逐步高级概述(不涉及任何数学):
- 对于每个类,计算给定实例不属于它的概率。
- 计算完所有类后,我们检查所有计算值并选择最小值。
- 选择最小值(最低概率)是因为它不是那个特定类别的最低概率。这意味着它实际上属于该类别的概率最高。所以选择了这个类。
注意:我们不选择具有最高值的那个,因为我们正在计算概率的补码。具有最高值的最不可能是该项目所属的类别。
现在,让我们考虑一个例子:假设我们有两个类: Apples 和 Bananas ,我们必须根据一定数量的单词的频率来分类给定的句子是与 apples 还是bananas 相关。这是简单数据集的表格表示:Sentence Number Round Red Long Yellow Soft Class 1 2 1 1 0 0 Apples 2 1 1 0 9 5 Bananas 3 2 1 0 0 1 Apples
“苹果”类的总字数 = (2+1+1) + (2+1+1) = 8
“香蕉”类的总字数 = (1 + 1 + 9 + 5) = 16
因此,句子属于“Apples”类的概率,
类似地,一个句子属于“香蕉”类的概率,
在上表中,我们表示了一个数据集,其中的列表示给定句子中单词的频率,然后显示该句子属于哪个类。在开始之前,您必须先了解贝叶斯定理。假设另一个事件发生,贝叶斯定理用于找出一个事件的概率。公式是:
其中 A 和 B 是事件,P(A) 是 A 发生的概率,P(A|B) 是在事件 B 已经发生的情况下 A 发生的概率。 P(B),事件B发生的概率不可能为0,因为它已经发生了。如果您想了解有关常规朴素贝叶斯和贝叶斯定理的更多信息,可以点击此链接。
现在让我们看看朴素贝叶斯和补充朴素贝叶斯是如何工作的。常规的朴素贝叶斯算法是,
其中 f i是某些属性的频率。例如,某些单词在句子中出现的次数。
然而,在补充朴素贝叶斯中,公式为:
如果您仔细查看公式,您会发现补码朴素贝叶斯只是常规朴素贝叶斯的逆。在朴素贝叶斯中,从公式中得到最大值的类就是预测类。所以,由于 Complement Naive Bayes 正好是逆,所以从 CNB 公式得到的值最小的类就是预测类。
现在,让我们举个例子,尝试使用我们的数据集和 CNB 进行预测,Round Red Long Yellow Soft Class 1 1 0 0 1 ?
所以,我们需要找到,
和
我们需要比较这两个值并选择具有较小值的类作为预测类。我们也必须对香蕉这样做,并选择价值最小的那个。即,如果 (y = Apples) 的值较小,则该类被预测为 Apples,如果 (y = Bananas) 的值较小,则该类被预测为 Bananas。
对这两个类使用补充朴素贝叶斯公式,
现在,由于 6.302 < 85.333,预测的类是Apples 。
我们不使用具有更高值的类,因为更高的值意味着带有这些词的句子更有可能不属于该类。这正是该算法被称为Complement Naive Bayes 的原因。
何时使用 CNB?
- 当数据集不平衡时:如果要对其进行分类的数据集不平衡,多项式和高斯朴素贝叶斯可能会给出低准确率。但是,Complement Naive Bayes 的表现会非常好,并且会提供相对更高的准确度。
- 对于文本分类任务:Complement Naive Bayes 在文本分类任务中优于 Gaussian Naive Bayes 和 Multinomial Naive Bayes。
Python中CNB的实现:
对于这个例子,我们将使用稍微不平衡的葡萄酒数据集。它从各种化学参数确定葡萄酒的原产地。要了解有关此数据集的更多信息,您可以查看此链接。
为了评估我们的模型,我们将检查测试集的准确性和分类器的分类报告。我们将使用 scikit-learn 库来实现 Complement Naive Bayes 算法。
代码:
# Import required modules
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report
from sklearn.naive_bayes import ComplementNB
# Loading the dataset
dataset = load_wine()
X = dataset.data
y = dataset.target
# Splitting the data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.15, random_state = 42)
# Creating and training the Complement Naive Bayes Classifier
classifier = ComplementNB()
classifier.fit(X_train, y_train)
# Evaluating the classifier
prediction = classifier.predict(X_test)
prediction_train = classifier.predict(X_train)
print(f"Training Set Accuracy : {accuracy_score(y_train, prediction_train) * 100} %\n")
print(f"Test Set Accuracy : {accuracy_score(y_test, prediction) * 100} % \n\n")
print(f"Classifier Report : \n\n {classification_report(y_test, prediction)}")
输出
Training Set Accuracy : 65.56291390728477 %
Test Set Accuracy : 66.66666666666666 %
Classifier Report :
precision recall f1-score support
0 0.64 1.00 0.78 9
1 0.67 0.73 0.70 11
2 1.00 0.14 0.25 7
accuracy 0.67 27
macro avg 0.77 0.62 0.58 27
weighted avg 0.75 0.67 0.61 27
我们在训练集上得到了 65.56% 的准确率,在测试集上得到了 66.66% 的准确率。它们几乎相同,考虑到数据集的质量,它们实际上相当不错。该数据集因难以使用我们在这里使用的简单分类器进行分类而臭名昭著。所以准确度是可以接受的。
结论:
既然您知道 Complement Naive Bayes 分类器是什么以及它们是如何工作的,那么下次遇到不平衡数据集时,您可以尝试使用 Complement Naive Bayes。
参考:
- scikit-learn 文档。