机器学习 - 朴素贝叶斯

发布于:2024-05-15 ⋅ 阅读:(80) ⋅ 点赞:(0)

朴素贝叶斯是基于贝叶斯定理的一种简单且高效的分类方法,特别适用于文本分类和情感分析等任务。

1. 贝叶斯定理简介

贝叶斯定理描述了后验概率(即在已知某些证据后某事件发生的概率)如何通过先验概率(即事件在未观测到任何证据前的概率)和似然(即在事件发生时观测到某些证据的概率)来计算。其公式如下:

P ( A ∣ B ) = P ( B ∣ A ) ⋅ P ( A ) P ( B ) P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)} P(AB)=P(B)P(BA)P(A)

其中:

  • P(A|B) 是给定证据 B 后事件 A 发生的后验概率。
  • P(B|A) 是在事件 A 发生时证据 B 出现的似然。
  • P(A) 是事件 A 的先验概率。
  • P(B) 是证据 B 的先验概率。

2. 朴素贝叶斯分类器原理

朴素贝叶斯分类器假设特征之间相互独立,且每个特征对分类结果的贡献是相同的。这一假设简化了计算过程,尽管在实际应用中,这一假设可能并不完全成立。

假设我们有一个包含 n 个特征的样本 x = ( x 1 , x 2 , . . . , x n ) x = (x_1, x_2, ..., x_n) x=(x1,x2,...,xn) 我们需要计算样本属于某个类别 Ck 的概率,即 P(Ck|x)。根据贝叶斯定理,我们有:

P ( C k ∣ x ) = P ( x ∣ C k ) ⋅ P ( C k ) P ( x ) P(C_k|x) = \frac{P(x|C_k) \cdot P(C_k)}{P(x)} P(Ckx)=P(x)P(xCk)P(Ck)

由于我们只关注相对大小,因此分母 P(x) 可以忽略。我们需要最大化 P(Ck|x),即最大化 P ( x ∣ C k ) ⋅ P ( C k ) P(x|C_k) \cdot P(C_k) P(xCk)P(Ck)

根据朴素假设,特征之间相互独立:

P ( x ∣ C k ) = P ( x 1 ∣ C k ) ⋅ P ( x 2 ∣ C k ) ⋅ . . . ⋅ P ( x n ∣ C k ) P(x|C_k) = P(x_1|C_k) \cdot P(x_2|C_k) \cdot ... \cdot P(x_n|C_k) P(xCk)=P(x1Ck)P(x2Ck)...P(xnCk)

因此,我们可以得到:

P ( C k ∣ x ) ∝ P ( C k ) ⋅ ∏ i = 1 n P ( x i ∣ C k ) P(C_k|x) \propto P(C_k) \cdot \prod_{i=1}^{n} P(x_i|C_k) P(Ckx)P(Ck)i=1nP(xiCk)

3. 案例:垃圾邮件分类

数据集介绍

假设我们有一个电子邮件数据集,其中每封邮件被标记为“垃圾邮件”或“正常邮件”。我们的任务是基于邮件内容预测其类别。假设我们的数据集如下:

邮件内容 类别
“免费 赢得 奖品” 垃圾邮件
“会议 记录” 正常邮件
“优惠券 打折 免费” 垃圾邮件
“项目 更新 会议” 正常邮件
“赢得 现金 奖品” 垃圾邮件

步骤 1:计算先验概率

先验概率是类别在训练数据中出现的频率:

P ( 垃圾邮件 ) = 3 5 = 0.6 P(\text{垃圾邮件}) = \frac{3}{5} = 0.6 P(垃圾邮件)=53=0.6
P ( 正常邮件 ) = 2 5 = 0.4 P(\text{正常邮件}) = \frac{2}{5} = 0.4 P(正常邮件)=52=0.4

步骤 2:计算条件概率

我们需要计算给定类别下各个单词出现的概率。例如,计算“免费”在“垃圾邮件”和“正常邮件”中的条件概率:

P ( 免费 ∣ 垃圾邮件 ) = “免费”出现在垃圾邮件中的次数 + 1 垃圾邮件中的单词总数 + 词汇表大小 = 2 + 1 9 + 10 = 3 19 P(\text{免费}|\text{垃圾邮件}) = \frac{\text{“免费”出现在垃圾邮件中的次数 + 1}}{\text{垃圾邮件中的单词总数 + 词汇表大小}} = \frac{2+1}{9+10} = \frac{3}{19} P(免费垃圾邮件)=垃圾邮件中的单词总数 + 词汇表大小免费出现在垃圾邮件中的次数 + 1=9+102+1=193

使用拉普拉斯平滑(加 1 平滑),假设我们的词汇表大小为 10。

类似地,我们计算其他单词的条件概率。

步骤 3:计算后验概率

假设我们有一封新邮件“免费 会议”,我们需要计算其属于“垃圾邮件”和“正常邮件”的后验概率:

P ( 垃圾邮件 ∣ 免费 会议 ) ∝ P ( 垃圾邮件 ) ⋅ P ( 免费 ∣ 垃圾邮件 ) ⋅ P ( 会议 ∣ 垃圾邮件 ) P(\text{垃圾邮件}|\text{免费 会议}) \propto P(\text{垃圾邮件}) \cdot P(\text{免费}|\text{垃圾邮件}) \cdot P(\text{会议}|\text{垃圾邮件}) P(垃圾邮件免费 会议)P(垃圾邮件)P(免费垃圾邮件)P(会议垃圾邮件)

根据我们之前计算的条件概率和先验概率,可以计算出:

P ( 垃圾邮件 ∣ 免费 会议 ) ∝ 0.6 ⋅ 3 19 ⋅ 1 19 P(\text{垃圾邮件}|\text{免费 会议}) \propto 0.6 \cdot \frac{3}{19} \cdot \frac{1}{19} P(垃圾邮件免费 会议)0.6193191

同样地,计算 P ( 正常邮件 ∣ 免费 会议 ) P(\text{正常邮件}|\text{免费 会议}) P(正常邮件免费 会议)

最终比较两个后验概率的大小,选择较大的那个类别作为预测结果。

好的,我们使用Python中的scikit-learn库来实现朴素贝叶斯分类器,并列出常见问题及其解决方案。我们将使用一个简单的文本分类任务作为案例。

4. 朴素贝叶斯API

我们将使用scikit-learn中的朴素贝叶斯分类器来构建一个垃圾邮件分类器。

数据准备

首先,我们创建一个简单的数据集,包含一些邮件内容及其标签(垃圾邮件或正常邮件)。

import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score, classification_report

# 创建数据集
data = {
    'text': [
        "免费 赢得 奖品",
        "会议 记录",
        "优惠券 打折 免费",
        "项目 更新 会议",
        "赢得 现金 奖品"
    ],
    'label': ['spam', 'ham', 'spam', 'ham', 'spam']
}
df = pd.DataFrame(data)

# 特征提取
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(df['text'])

# 标签编码
y = df['label']

# 拆分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 训练朴素贝叶斯分类器
model = MultinomialNB()
model.fit(X_train, y_train)

# 预测
y_pred = model.predict(X_test)

# 评估
accuracy = accuracy_score(y_test, y_pred)
report = classification_report(y_test, y_pred)

print(f"Accuracy: {accuracy}")
print("Classification Report:")
print(report)
常见问题及解决方案

问题1:数据不平衡

  • 问题描述:训练数据中某些类别的样本数量远多于其他类别,导致分类器对少数类别的预测效果较差。

  • 解决方案

    • 使用过采样(如SMOTE)或欠采样技术来平衡数据。
    • 使用加权损失函数来惩罚分类错误的少数类别样本。

问题2:文本特征稀疏

  • 问题描述:文本数据在转化为特征向量时,特征向量非常稀疏,影响分类效果。

  • 解决方案

    • 使用TF-IDF(Term Frequency-Inverse Document Frequency)代替词频向量,可以减小常见但无意义的词对分类的影响。
    • 进行特征选择,去除低频或高频词。
from sklearn.feature_extraction.text import TfidfVectorizer

# 使用TF-IDF特征提取
tfidf_vectorizer = TfidfVectorizer()
X_tfidf = tfidf_vectorizer.fit_transform(df['text'])

# 拆分数据集
X_train_tfidf, X_test_tfidf, y_train, y_test = train_test_split(X_tfidf, y, test_size=0.2, random_state=42)

# 训练朴素贝叶斯分类器
model.fit(X_train_tfidf, y_train)

# 预测
y_pred_tfidf = model.predict(X_test_tfidf)

# 评估
accuracy_tfidf = accuracy_score(y_test, y_pred_tfidf)
report_tfidf = classification_report(y_test, y_pred_tfidf)

print(f"Accuracy with TF-IDF: {accuracy_tfidf}")
print("Classification Report with TF-IDF:")
print(report_tfidf)
  • 问题3:高维特征

  • 问题描述:文本特征向量通常非常高维,可能导致模型训练时间过长。

  • 解决方案

    • 使用降维技术,如PCA(主成分分析)或LDA(线性判别分析)来减少特征维度。
    • 进行特征选择,保留重要特征。
  • 问题4:模型过拟合

  • 问题描述:模型在训练数据上表现良好,但在测试数据上表现不佳。

  • 解决方案

    • 使用交叉验证来调优模型参数。
    • 增加正则化项,控制模型复杂度。

问题5:处理未见过的词汇

  • 问题描述:在测试数据中出现的词汇在训练数据中未出现,导致模型无法处理。

  • 解决方案

    • 使用拉普拉斯平滑(加1平滑)来处理未见过的词汇,避免概率为零的情况。
    • 增加训练数据,尽量覆盖更多的词汇。
# 拉普拉斯平滑已经在MultinomialNB中默认处理,无需额外操作

总结

朴素贝叶斯分类器由于其简单和高效,广泛应用于文本分类、情感分析等领域。尽管其假设特征独立性可能在实际应用中不完全成立,但在许多情况下依然表现良好。通过案例可以看到,朴素贝叶斯利用贝叶斯定理和特征独立假设,实现了高效的分类。

更多问题咨询

Cos机器人


网站公告

今日签到

点亮在社区的每一天
去签到