机器学习(一)——朴素贝叶斯分类(Naive Bayes Classification)

 一、贝叶斯简介

         朴素贝叶斯分类器用于计算可能条件的分支概率。每个独立的特征都是「朴素」或条件独立的,因此它们不会影响别的对象。例如,在一个装有共 5 个黄色和红色小球的罐子里,连续拿到两个黄色小球的概率是多少?从图中最上方分支可见,前后抓取两个黄色小球的概率为 1/10。朴素贝叶斯分类器可以计算多个特征的联合条件概率。

✅ 贝叶斯定理
根据先验概率和条件概率得到后验概率
✅ 朴素贝叶斯定理
在贝叶斯原理基础上,加了一个前提假设:所有的条件对结果都是独立发生作用的
✅ 条件概率
事件 B 在另一个事件 A 已经发生条件下的概率,记作 P(B|A)。
在统计学中,也称之为似然函数。
✅ 先验概率
事件 A 或 事件 B 是根据经验来判断发生的概率,记作 P(A)、P(B)。
✅后验概率
我们已经看到某个事情发生了,再判断这个事情发生原因的概率,即在事件已经发生后,推测原因。比如 P(A|B) 是已知 B 发生后 A 的条件概率,也叫做 A 的后验概率。
✅优点
算法的逻辑简单
不需要训练,算法计算的时候对资源占用比较小
✅缺点
使用非常有局限性,只有在条件比较少,并且相互独立的时候,朴素贝叶斯的效果才会比较好
✅应用场景
从算法场景来说,比较适合文本分类、情感分析、垃圾邮件分类这类场景,因为这些数据的相互独立性更高
从开发成本来说,适合项目周期比较紧张,算力资源不太充足的情况

垃圾邮件分类: 根据电子邮件的内容识别电子邮件是否为垃圾邮件

实时预测系统: 该模型相对较快,因此可以实时预测目标变量

情绪分析:识别产品的反馈并将其分类为“正面”或“负面”

 二、条件概率

对条件概率公式进行变形,可以得到如下形式:

机器学习实战教程(四):朴素贝叶斯基础篇之言论过滤器

我们把P(A)称为"先验概率"(Prior probability),即在B事件发生之前,我们对A事件概率的一个判断。

P(A|B)称为"后验概率"(Posterior probability),即在B事件发生之后,我们对A事件概率的重新评估。

P(B|A)/P(B)称为"可能性函数"(Likelyhood),这是一个调整因子,使得预估概率更接近真实概率。

所以,条件概率可以理解成式子:后验概率 = 先验概率 x 调整因子

三、朴素贝叶斯推断

理解了贝叶斯推断,那么让我们继续看看朴素贝叶斯。贝叶斯和朴素贝叶斯的概念是不同的,区别就在于“朴素”二字,朴素贝叶斯对条件个概率分布做了条件独立性的假设。 比如下面的公式,假设有n个特征:

机器学习实战教程(四):朴素贝叶斯基础篇之言论过滤器

由于每个特征都是独立的,我们可以进一步拆分公式 :

机器学习实战教程(四):朴素贝叶斯基础篇之言论过滤器

法国数学家拉普拉斯最早提出用加1的方法估计没有出现过的现象的概率。 拉普拉斯平滑处理后的条件概率计算公式为: 

                                       

四、动手实践 

import numpy as np
"""
函数功能:创建实验数据集
参数说明:无参数
返回:
postingList:切分好的样本词条
classVec:类标签向量
"""
def loadDataSet():  #loadDataSet:创建实验数据集
    dataSet=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
                    ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
                    ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
                    ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
                    ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
                    ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']] #切分好的词条
    classVec = [0,1,0,1,0,1] #类别标签向量,1代表侮辱性词汇,0代表非侮辱性词汇
    return dataSet,classVec

dataSet,classVec=loadDataSet()

"""
函数功能:将切分的样本词条整理成词汇表(不重复)
参数说明:
dataSet:切分好的样本词条
返回:
vocabList:不重复的词汇表
"""
def createVocabList(dataSet):
    vocabSet = set() #创建一个空的集合
    for doc in dataSet: #遍历dataSet中的每一条言论
        vocabSet = vocabSet | set(doc) #取并集
        vocabList = list(vocabSet)
    return vocabList

vocabList = createVocabList(dataSet)

"""
函数功能:根据vocabList词汇表,将inputSet向量化,向量的每个元素为1或0
参数说明:
vocabList:词汇表
inputSet:切分好的词条列表中的一条
返回:
returnVec:文档向量,词集模型
"""
def setOfWords2Vec(vocabList, inputSet):
    returnVec = [0] * len(vocabList) #创建一个其中所含元素都为0的向量
    for word in inputSet: #遍历每个词条
        if word in vocabList: #如果词条存在于词汇表中,则变为1
            returnVec[vocabList.index(word)] = 1
        else:
            print(f" {word} is not in my Vocabulary!" )
    return returnVec #返回文档向量

"""
函数功能:生成训练集向量列表
参数说明:
dataSet:切分好的样本词条
返回:
trainMat:所有的词条向量组成的列表
"""
def get_trainMat(dataSet):
    trainMat = [] #初始化向量列表
    vocabList = createVocabList(dataSet) #生成词汇表
    for inputSet in dataSet: #遍历样本词条中的每一条样本
        returnVec=setOfWords2Vec(vocabList, inputSet) #将当前词条向量化
        trainMat.append(returnVec) #追加到向量列表中
    return trainMat

trainMat = get_trainMat(dataSet)

def trainNB(trainMat,classVec):
    n = len(trainMat) #计算训练的文档数目
    m = len(trainMat[0]) #计算每篇文档的词条数
    pAb = sum(classVec)/n #文档属于侮辱类的概率
    p0Num = np.zeros(m) #词条出现数初始化为0
    p1Num = np.zeros(m) #词条出现数初始化为0
    p0Denom = 0 #分母初始化为0
    p1Denom = 0 #分母初始化为0
    for i in range(n): #遍历每一个文档
        if classVec[i] == 1: #统计属于侮辱类的条件概率所需的数据
                p1Num += trainMat[i]
                p1Denom += sum(trainMat[i])
         else: #统计属于非侮辱类的条件概率所需的数据
                p0Num += trainMat[i]
                p0Denom += sum(trainMat[i])
    p1V = p1Num/p1Denom
    p0V = p0Num/p0Denom
    return p0V,p1V,pAb #返回属于非侮辱类,侮辱类和文档属于侮辱类的概率

p0V,p1V,pAb = trainNB(trainMat, classVec)
### 朴素贝叶斯分类器的概念与实现 #### 概念概述 朴素贝叶斯分类器(Naive Bayes Classifier)是种基于贝叶斯定理和特征条件独立假设的分类算法。其核心思想是通过已知的数据集学习到各个类别的先验概率以及每个特征在不同类别下的条件概率,进而利用这些概率来预测新数据点所属的类别[^3]。 具体来说,“朴素”的含义在于它假设所有的输入特征之间相互独立,即使这种假设在现实中往往并不完全成立。然而,在许多应用场景下,这简化假设并不会显著影响模型的表现,并且能够极大地降低计算复杂度[^4]。 #### 数学基础 贝叶斯定理提供了从先验概率转换成后验概率的方法: \[ P(C|X) = \frac{P(X|C)P(C)}{P(X)} \] 其中, - \( C \): 表示某个特定的类别; - \( X \): 是由多个特征组成的观测向量; - \( P(C) \): 类别\( C \) 的先验概率; - \( P(X|C) \): 给定类别条件下观察到特征组合的概率; - \( P(X) \): 特征组合的整体概率; 由于分母对于所有可能的类别都是相同的常数项,因此我们可以忽略它并仅比较分子部分以找到最有可能的类别标签[^2]。 #### 条件独立性假设 为了使计算变得可行,朴素贝叶斯步做出如下假设:给定某固定类别之后,各维度上的属性彼此间不存在关联关系——即它们互相独立。这样做的好处是可以分别单独估计每个维度上对应的条件概率密度函数而不是联合分布形式,从而大大减少了所需的训练样例数量以及运算负担[^1]。 #### 平滑处理 当某些特征值从未出现在训练集中对应某类别的实例里时,则直接依据经验频率得到零概率的结果会使得整个乘积也为零,这显然不合理也不利于后续判断过程正常开展下去。为此引入拉普拉斯修正(Laplace Smoothing),通过对计数值加个小正整数调整原始比例关系达到避免上述情况发生的目的。 #### Python 实现案例 下面展示如何使用Python中的`sklearn`库快速搭建起个简单的文本分类任务所使用的MultinomialNB版本的朴素贝叶斯模型: ```python 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 # 假设我们有如下数据集 texts = ["buy cheap medicine", "free lottery win now", "hello how are you doing", "get your free trial today", "can we meet tomorrow afternoon"] labels = ['spam', 'spam', 'ham', 'spam', 'ham'] vectorizer = CountVectorizer() X = vectorizer.fit_transform(texts) y = labels # 划分训练集测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) clf = MultinomialNB() # 训练模型 clf.fit(X_train, y_train) # 预测结果 predictions = clf.predict(X_test) print(f'Accuracy Score: {accuracy_score(y_test,predictions)*100:.2f}%') print(classification_report(y_test, predictions)) ``` 此脚本首先定义了些模拟电子邮件正文及其相应标记作为例子演示用途。接着运用词袋模型将字符串转化为稀疏矩阵表示法供机器理解操作之需。最后调用了多变量伯努利型朴素贝叶斯变种完成最终的任务目标评估工作流程说明完毕。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值