目录
目录
一、引言:朴素贝叶斯算法
朴素贝叶斯算法是一种基于贝叶斯定理的监督学习算法,主要用于分类问题,特别是在处理离散特征时。朴素贝叶斯算法是假设特征之间相互独立的,因此称之为“朴素”。尽管这个假设在现实中往往不成立,但它在实际应用中仍然表现出很好的性能,特别是在文本分类(如垃圾邮件检测、情感分析)等领域。
二、朴素贝叶斯概述:
朴素贝叶斯是贝叶斯决策理论中的一部分,而贝叶斯决策理论是基于贝叶斯定理的一种统计方法,因此我会先为大家介绍何为“贝叶斯定理”。
2.1 贝叶斯定理
贝叶斯定理是概率论中的一个定理,它描述了在已知的一些条件下,某事件发生的概率。人对某一事件未来会发生的认知,大多取决于该事件或类似事件过去发生的频率。这就是贝叶斯定理的数学模型,它最早由数学家托马斯·贝叶斯提出。
贝叶斯定理的过程可以归纳为:“过去经验”加上“新的证据”得到“修正后的判断”。它提供了一种将新观察到的证据和已有的经验结合起来进行推断的客观方法。
在介绍贝叶斯定理前,先为大家引入先验概率、后验概率和条件概率的概念。
先验概率:是基于统计的概率,是基于以往历史经验和分析得到的结果,不需要依赖当前发生的条件。
条件概率:记事件A发生的概率为P(A),事件B发生的概率为P(B),则在事件B发生的前提下,事件A发生的概率即为条件概率,记为P(A|B)。
后验概率:则是从条件概率而来,由因推果,是基于当下发生了事件之后计算的概率,依赖于当前发生的条件。
贝叶斯公式:假设有随机事件A和B,则贝叶斯公式如下:
其中,事件A是要考察的目标事件,P(A)是事件A的初始概率,称为先验概率,它是根据一些先前的观测或者经验得到的概率。
B是新出现的一个事件,它会影响事件A。P(B)表示事件B发生的概率。
P(B|A)表示在事件A发生的条件下事件B发生的概率,称之为条件概率。
P(A|B)表示当事件B发生时事件A发生的概率(也是条件概率),它是我们要计算的后验概率,指在得到一些观测信息后某事件发生的概率。
因此,根据贝叶斯公式可知,先验概率一般是由以往的数据分析或统计得到的概率数据。后验概率是在某些条件下发生的概率,是在得到信息之后再重新加以修正的概率。也就是说,后验概率可以在先验概率的基础上进行修正并得到。
2.2 朴素贝叶斯
朴素贝叶斯是以贝叶斯定理为基础并且假设特征条件之间相互独立的方法。在给定的训练数据集上,朴素贝叶斯学习每个特征与每个类别的概率关系,然后使用贝叶斯定理来预测新实例的类别。
特征条件假设:假设每个特征之间没有联系,给定训练数据集,其中每个样本x都包括n维特征,即x=(x1,x2,x3,...,xn);类标记集合含有k种类别,即𝑦=(𝑦1,𝑦2,...,𝑦𝑘)
对于给定的新样本x,判断其属于哪个标记的类别,根据贝叶斯定理,可以得到x属于类别𝑦𝑘的概率𝑃(𝑦𝑘|𝑥):
后验概率最大的类别记为预测类别,即:arg𝑚𝑎𝑥𝑃(𝑦𝑘|𝑥)。
朴素贝叶斯算法对条件概率分布作出了独立性的假设,通俗地讲就是说假设各个维度的特征互相独立,在这个假设的前提上,条件概率可以转化为:
代入上面贝叶斯公式中,得到:
于是,朴素贝叶斯分类器可表示为:
因为对所有的,上式中的分母的值都是一样的,所以可以忽略分母部分,朴素贝叶斯分类器最终表示为:
三、案例实战思路
3.1垃圾分类器系统
假设我们有一个垃圾邮件分类器系统,该系统需要能够自动识别哪些邮件是垃圾邮件。那么我们可以利用朴素贝叶斯算法来实现这一功能。首先,我们需要对数据进行预处理,将文本数据转换成类似于向量的形式,这样可以方便计算。接着,我们需要将数据集划分成训练集和测试集。
在训练集上,我们可以计算每个特征在不同分类下出现的概率,并计算不同分类的先验概率。这样,我们就可以得到一个分类模型,该模型可以在测试集上进行表现测试。我们可以将测试集中的每个邮件分别输入到模型中,该模型能够根据邮件的各项属性计算概率,从而预测该邮件的分类。
总的来说,朴素贝叶斯算法是一种比较简单易用的分类算法,其主要优点是计算速度快、准确率高,并且可以在大数据量下进行有效的处理。由于其基于简单的统计原理,所以其可持续性、简单性和可解释性都非常好。
代码部分:
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score
# 1. 加载数据
data = pd.read_csv('spam.csv', encoding='latin-1')
# 2. 数据预处理
data.drop(['Unnamed: 2', 'Unnamed: 3', 'Unnamed: 4'], axis=1, inplace=True)
data = data.rename(columns={'v1': 'label', 'v2': 'text'})
data['label'] = data['label'].map({'ham': 0, 'spam': 1})
# 3. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(data['text'], data['label'], test_size=0.2, random_state=42)
# 4. 特征提取
vectorizer = CountVectorizer()
X_train_counts = vectorizer.fit_transform(X_train)
X_test_counts = vectorizer.transform(X_test)
# 5. 训练分类器
clf = MultinomialNB()
clf.fit(X_train_counts, y_train)
# 6. 预测
y_pred = clf.predict(X_test_counts)
# 7. 评估分类器性能
acc_score = accuracy_score(y_test, y_pred)
print('Accuracy:', acc_score)
这个案例的目的是建立一个垃圾邮件分类器,使用朴素贝叶斯算法对电子邮件进行分类。在这个案例中,我们首先需要加载数据,接着对数据进行预处理。预处理步骤包括将特定列重命名,将标签用数字表示,删除不需要的列等。然后,我们将数据集拆分成训练集和测试集。在这个案例中,我们将80%的数据用于训练,20%的数据用于测试。接下来,我们使用词袋模型提取特征。这里我们使用了 CountVectorizer 类,该类可以计算出每个单词出现的次数。然后,我们使用 MultinomialNB 类训练一个分类器。最后,我们使用分类器对测试集进行预测,并使用 accuracy_score 函数计算分类器的性能。在这个案例中,在测试集上的准确率约为 98%。
# 8. 特征工程优化
from sklearn.pipeline import Pipeline
text_clf = Pipeline([
('vect', CountVectorizer()),
('clf', MultinomialNB())
])
text_clf.fit(X_train, y_train)
# 9. 交叉验证
from sklearn.model_selection import cross_val_score
scores = cross_val_score(text_clf, data['text'], data['label'], cv=5)
print('5-fold cross-validation scores:', scores)
print('Mean cross-validation score:', scores.mean())
# 10. 模型优化
from sklearn.model_selection import GridSearchCV
parameters = {
'vect__ngram_range': [(1,1), (1,2)],
'vect__max_df': [0.75, 1.0],
'vect__min_df': [1, 2],
'clf__alpha': [0.1, 1, 10]
}
gs_clf = GridSearchCV(text_clf, parameters, cv=5)
gs_clf.fit(data['text'], data['label'])
print('Best parameters:', gs_clf.best_params_)
print('Best score:', gs_clf.best_score_)
在这个后半段代码中,我们进行了特征工程的优化。首先,我们使用 Scikit-learn 的管道机制,将文本特征提取和分类器训练过程合并为一个步骤。这个管道包含两个步骤,即特征提取和分类器训练。我们还使用交叉验证来评估模型的性能。在这个案例中,我们使用了 5 折交叉验证。最后,我们对模型进行了优化,使用网格搜索(GridSearchCV)寻找最佳超参数组合。在这个案例中,我们要优化的参数包括词袋模型的 ngram_range、max_df 和 min_df 参数,以及朴素贝叶斯分类器的平滑参数 alpha。我们使用网格搜索找到最佳超参数组合,并输出最佳得分和参数。
四、实验总结
通过对这个垃圾邮件分类器系统我了解到了朴素贝叶斯分类器的结构非常直观,易于理解,这使得它在很多领域都有广泛的应用。同时,也需要注意朴素贝叶斯算法对特征独立性的假设,这可能会降低模型的准确性。