IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> ML朴素贝叶斯分类器 -> 正文阅读

[人工智能]ML朴素贝叶斯分类器

贝叶斯分类器

多摘自西瓜书

1.贝叶斯决策论

贝叶斯决策论 (Bayesian decision theory) 是概率框架下实施决策的基本方法。对于分类任务来说,在所有相关概率都已知的理想情形下,贝叶斯决策论考虑如何基于这些概率和误判损失来选择最优的类别标记。

假设有 N N N 种可能的类别标记,即 y = { c 1 , c 2 , . . . , c N } y = \{ c_1, c_2,...,c_N \} y={c1?,c2?,...,cN?}, λ i j \lambda_{ij} λij? 是将一个真实标记为 c j c_j cj? 的样本误分类为 c i c_i ci? 所产生的损失。基于后验概率 P ( c i ∣ x ) P(c_i|x) P(ci?x) 可获得将样本 x x x 分类为 c i c_i ci? 所产生的期望损失或风险, 即在样本 x x x 上的“条件风险”
R ( c i ∣ x ) = ∑ j = 1 N λ i j P ( c j ∣ x ) R(c_i|x) = \sum_{j=1}^{N} \lambda_{ij} P(c_j|x) R(ci?x)=j=1N?λij?P(cj?x)
我们的任务是寻找一个判定准则 $h: \chi \mapsto y $ 以最小化总体风险
R ( h ) = E [ R ( h ( x ) ∣ x ) ] R(h) = E[R(h(x) | x)] R(h)=E[R(h(x)x)]
显然,对每个样本 x x x, 若 h h h 能最小化条件风险 R ( h ( x ) ∣ x ) R(h(x) | x) R(h(x)x), 则总体风险 R ( h ) R(h) R(h) 也将被最小化。这就产生了贝叶斯准则 (Bayes decision rule): 为最小化总体风险,只需在每个样本上选择那个能使条件风险 R ( h ( x ) ∣ x ) R(h(x) | x) R(h(x)x) 最小的类别标记,即
h ? ( x ) = arg ? min ? c ∈ y R ( c ∣ x ) h^*(x) = \mathop{\arg\min}\limits_{c \in y} R(c|x) h?(x)=cyargmin?R(cx)
此时, h ? h^* h? 成为贝叶斯最优分类器,与之对应的总体风险 R ( h ? ) R(h*) R(h?) 称为贝叶斯风险。 1 ? R ( h ? ) 1-R(h^*) 1?R(h?) 反映了分类器所能达到的最好性能,即通过机器学习所能产生的模型精度的理论上限。

具体来说,若目标是最小化分类错误率,则误判损失 λ i j \lambda_{ij} λij? 可写为:
λ i j = { 0 , i f i = j 1 o t h e r w i s e \lambda_{ij} = \left\{\begin{matrix} 0, & if \quad i=j \\ 1 & otherwise \end{matrix}\right. λij?={0,1?ifi=jotherwise?
此时条件风险为
R ( c ∣ x ) = 1 ? P ( c ∣ x ) R(c|x) = 1-P(c|x) R(cx)=1?P(cx)

于是,最小化分类错误率的贝叶斯最优分类器为
h ? ( x ) = arg ? min ? c ∈ y P ( c ∣ x ) h^*(x) = \mathop{\arg\min}\limits_{c \in y} P(c|x) h?(x)=cyargmin?P(cx)
即对每个样本 x x x, 选择能使后验概率 P ( c ∣ x ) P(c|x) P(cx) 最大的类别标记。

因此,欲使用贝叶斯准则来最小化决策风险,首先要获得后验概率 P ( c ∣ x ) P(c|x) P(cx)
P ( c ∣ x ) = P ( x , c ) P ( x ) P(c|x) = \frac{P(x,c)}{P(x)} P(cx)=P(x)P(x,c)?
基于贝叶斯定理, P ( c ∣ x ) P(c|x) P(cx) 可写为
P ( c ∣ x ) = P ( c ) P ( x ∣ c ) P ( x ) P(c|x) = \frac{P(c)P(x|c)}{P(x)} P(cx)=P(x)P(c)P(xc)?
其中, P ( c ) P(c) P(c) 是类先验概率; P ( c ∣ x ) P(c|x) P(cx) 是样本 x x x 相对于类标记 c c c 的类条件概率, 或称为似然; 分母 p ( x ) p(x) p(x) 是用于归一化的“证据因子”。对于给定样本 x x x, 证据因子 P ( x ) P(x) P(x) 与类标记无关,因此估计 P ( c ∣ x ) P(c|x) P(cx) 的问题就转化为如何基于训练数据 D D D 来估计先验 P ( c ) P(c) P(c) 和似然 P ( x ∣ c ) P(x|c) P(xc).

2.朴素贝叶斯

基于贝叶斯公式 ( 9 ) (9) (9) 来估计后验概率 P ( c ∣ x ) P(c|x) P(cx) 的主要困难在于:类条件概率 P ( x ∣ c ) P(x|c) P(xc) 是所有属性上的联合概率,难以从有限的训练样本直接估计而得。为了避免这个障碍,朴素贝叶斯分类器采用了“属性条件独立性假设”:

对已知类别,假设所有属性相互独立. 换言之,假设每个属性独立的对分类结果发生影响.

基于属性条件独立性假设,式 ( 9 ) (9) (9) 可重写为
P ( c ∣ x ) = P ( c ) P ( x ∣ c ) P ( x ) = P ( c ) P ( x ) ∏ i = 1 d P ( x i ∣ c ) P(c|x) = \frac{P(c)P(x|c)}{P(x)} = \frac{P(c)}{P(x)} \prod_{i=1}^{d} P(x_i|c) P(cx)=P(x)P(c)P(xc)?=P(x)P(c)?i=1d?P(xi?c)

其中 d d d 为属性数目, x i x_i xi? x x x 在第 i i i 个属性上的取值.

由于对所有类别来说 P ( x ) P(x) P(x) 相同,因此基于式 ( 6 ) (6) (6) 的贝叶斯判定准则有
h n b ( x ) = arg ? min ? c ∈ y P ( c ) ∏ i = 1 d P ( x i ∣ c ) h_{nb}(x) = \mathop{\arg\min}\limits_{c \in y} P(c) \prod_{i=1}^{d} P(x_i|c) hnb?(x)=cyargmin?P(c)i=1d?P(xi?c)
这就是朴素贝叶斯分类器的表达式.

D c D_c Dc? 表示训练集 D D D 中出现第 c c c 类样本组成的集合, 若有充足的独立同分布样本,则可容易的估计出类先验概率
P ( c ) = ∣ D c ∣ ∣ D ∣ P(c) = \frac{|D_c|}{|D|} P(c)=DDc??
对离散属性而言,令 D c , x i D_{c,x_i} Dc,xi?? 表示 D c D_c Dc? 中在第 i i i 个属性上取值为 x i x_i xi? 的样本组成的集合, 则条件概率 P ( x i ∣ c ) P(x_i|c) P(xi?c) 可估计为
P ( x i ∣ c ) = ∣ D c , x i ∣ ∣ D c ∣ P(x_i|c) = \frac{|D_{c,x_i}|}{|D_c|} P(xi?c)=Dc?Dc,xi???
对连续属性而言,可考虑概率密度函数,假定 $p(x_i|c) \sim N(\mu_{c,i},\sigma_{c,i}^{2}) $, 其中 μ c , i \mu_{c,i} μc,i? σ c , i 2 \sigma_{c,i}^2 σc,i2? 分别是第 c c c 类样本在第 i i i 个属性上取值的均值和方差,则有
p ( x i ∣ c ) = 1 2 π σ c , i e x p ( ? ( x i ? μ c , i ) 2 2 σ c , i 2 ) p(x_i|c) = \frac{1}{\sqrt{2\pi} \sigma_{c,i}}exp(-\frac{(x_i-\mu_{c,i})^2}{2\sigma_{c,i}^2}) p(xi?c)=2π ?σc,i?1?exp(?2σc,i2?(xi??μc,i?)2?)
为了避免其他属性携带的信息被训练集中未出现的属性值“抹去”,在估计概率值时通常要进行“平滑”,常用“拉普拉斯修正” (Laplacian correction). 具体来说,令 N N N 表示训练集 D D D 中可能的类别数, N i N_i Ni? 表示第 i i i 个属性可能的取值数, 则式 ( 11 ) (11) (11) 和式 ( 12 ) (12) (12) 可修正为
P ( c ) = ∣ D c ∣ + 1 ∣ D ∣ + N P(c) = \frac{|D_c| + 1}{|D| + N} P(c)=D+NDc?+1?

P ( x i ∣ c ) = ∣ D c , x i ∣ + 1 ∣ D c ∣ + N i P(x_i|c) = \frac{|D_{c,x_i}| + 1}{|D_c| + N_i} P(xi?c)=Dc?+Ni?Dc,xi??+1?

显然, 拉普拉斯修正避免了因训练样本不充分而导致概率估值为零的问题,并且在训练集变大时,修正过程所引入的先验的影响也会逐渐变得可忽略,使得估值渐趋向于实际概率值。

举个栗子:

在这里插入图片描述


朴素贝叶斯优缺点:

优点:

  • 算法逻辑简单, 易于实现
  • 分类过程中时空开销小

缺点:

理论上,朴素贝叶斯模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为朴素贝叶斯模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。

3.朴素贝叶斯代码实现

import numpy as np
import pandas as pd
import copy

class naiveBayesClassifier():
    def __init__(self):
        self.data = None
        self.prior = None
        
    # 构造fit函数
    def fit(self,Xtrain,Ytrain):
        data = pd.concat([pd.DataFrame(Xtrain),pd.DataFrame(Ytrain)],axis=1)
        self.data = data
    
    # 计算先验概率
    def cal_prior(self):
        prior = {}
        num_sample = len(self.data) # 样本个数
        data_count = self.data.iloc[:,-1].value_counts() # 对label统计
        for i in range(len(data_count)):
            prior[data_count.index[i]] = data_count[i] / num_sample # 先验概率 公式11
        self.prior = prior
        return True
    
    # 计算先验概率 拉普拉斯修正
    def cal_prior_laplacian(self):
        prior = {}
        num_sample = len(self.data) # 样本个数
        data_count = self.data.iloc[:,-1].value_counts() # 对label统计
        for i in range(len(data_count)):
            prior[data_count.index[i]] = (data_count.iloc[i] + 1) / (num_sample + len(data_count)) # 先验概率 公式14
        self.prior = prior
        #print(prior)
        return True
    
    
    # 对数据按照label进行分组
    def group_data(self):
        data_group_label = {}
        labels = pd.unique(self.data.iloc[:,-1]) # 获取label
        data_group = self.data.groupby(self.data.columns[-1]) # 将数据集按label分组
        for i in labels:
            data_group_label[i] = pd.DataFrame(data_group.get_group(i))
        return data_group_label # 返回分组
    
    # 期望构造一个函数判断哪些属性是离散属性,哪些属性是连续属性
    def judge_feture(self):
        feature = {}
        for i in self.data.columns[:-1]:
            if len(pd.unique(self.data.loc[:,i])) < len(self.data)* 0.5: # 如果某个属性定义域 < 样本数 则认为是离散变量 标记1
                feature[i] = 1
            elif len(pd.unique(self.data.loc[:,i])) >= len(self.data) * 0.5: # 如果某个属性定义域 = 样本数 则认为是连续变量 标记0
                feature[i] = 0
        return feature
    
    # 若属性为离散,计算当前属性的条件概率
    def cal_prob(self,group_data,feature,column):
        prob_label = {}
        for label in group_data.keys():
            prob_label[label] = (np.sum(group_data[label].loc[:,column] == feature)) / len(group_data[label]) # 公式12
        return prob_label
    
    # 若属性为离散,计算当前属性的条件概率 拉普拉斯修正
    def cal_prob_laplacian(self,group_data,feature,column):
        prob_label = {}
        for label in group_data.keys():
            num_features = len(np.unique(X.loc[:,column]))
            prob_label[label] = (np.sum(group_data[label].loc[:,column] == feature) + 1) / (len(group_data[label]) + num_features) # 公式15
        return prob_label
    
    
    # 若属性为连续属性,计算概率密度
    def cal_density(self,group_data,feature,column):
        density = {}
        for label in group_data.keys():
            mu = np.mean(group_data[label].loc[:,column]) # 均值
            sigma = np.std(group_data[label].loc[:,column],ddof=1)
            density[label] = (1 / (np.sqrt(2*np.pi) * sigma)) * np.exp(-np.power((feature-mu),2) / (2 * (sigma ** 2))) # 公式13
        return density
    
    # 构造预测函数预测单个样本
    def predict_single(self,xtest_single):
        xtest_single = pd.DataFrame(xtest_single).T
        feature_judge = self.judge_feture() # 判断连续变量/ 离散变量
        group_data_label = self.group_data() # 测试集按标签分组

        # 循环计算条件概率
        cond_prob = {}
        for i in xtest_single.columns:
            if feature_judge[i]: # 如果为离散属性
                cond_prob[i] = self.cal_prob_laplacian(group_data_label,xtest_single.loc[0,i],i)
            elif not feature_judge[i]: # 如果为连续属性
                cond_prob[i] = self.cal_density(group_data_label,xtest_single.loc[0,i],i)
        result = copy.deepcopy(self.prior)
        for i in self.prior.keys():
            for j in cond_prob.keys():
                result[i] *= cond_prob[j][i] # 计算各个概率
        #pred_lable = max(result, key = result.get)
        return result
    
    # 定义预测函数
    def predict(self,test):
        xtest = pd.DataFrame(test)
        self.cal_prior_laplacian() # 计算先验概率
        pred = []
        xtest.reset_index(inplace=True,drop=True)
        for i in xtest.index:
            result = self.predict_single(xtest.iloc[i,:])
            pred.append(max(result, key = result.get)) # 概率最大的label作为预测标签
        return pred
    
    # 概率预测函数
    def predict_prob(self,test):
        xtest = pd.DataFrame(test)
        self.cal_prior_laplacian() # 计算先验概率
        pred_prob = []
        pred_prob.append([i for i in self.prior.keys()])
        xtest.reset_index(inplace=True,drop=True)
        for i in xtest.index:
            result = self.predict_single(xtest.iloc[i,:])
            pred_prob.append([result[i] for i in self.prior.keys()]) # 保存概率
        return pred_prob


if __name__ == '__main__':
    # 西瓜数据集3.0 p.84 表 4.3
    dataset = {
        '色泽': ['青绿', '乌黑', '乌黑', '青绿', '浅白', '青绿', '乌黑', '乌黑', '乌黑', '青绿', '浅白', '浅白', '青绿', '浅白', '乌黑', '浅白', '青绿'],
        '根蒂': ['蜷缩', '蜷缩', '蜷缩', '蜷缩', '蜷缩', '稍蜷', '稍蜷', '稍蜷', '稍蜷', '硬挺', '硬挺', '蜷缩', '稍蜷', '稍蜷', '稍蜷', '蜷缩', '蜷缩'],
        '敲声': ['浊响', '沉闷', '浊响', '沉闷', '浊响', '浊响', '浊响', '浊响', '沉闷', '清脆', '清脆', '浊响', '浊响', '沉闷', '浊响', '浊响', '沉闷'],
        '纹理': ['清晰', '清晰', '清晰', '清晰', '清晰', '清晰', '稍糊', '清晰', '稍糊', '清晰', '模糊', '模糊', '稍糊', '稍糊', '清晰', '模糊', '稍糊'],
        '脐部': ['凹陷', '凹陷', '凹陷', '凹陷', '凹陷', '稍凹', '稍凹', '稍凹', '稍凹', '平坦', '平坦', '平坦', '凹陷', '凹陷', '稍凹', '平坦', '稍凹'],
        '触感': ['硬滑', '硬滑', '硬滑', '硬滑', '硬滑', '软粘', '软粘', '硬滑', '硬滑', '软粘', '硬滑', '软粘', '硬滑', '硬滑', '软粘', '硬滑', '硬滑'],
        '密度': [0.697, 0.774, 0.634, 0.608, 0.556, 0.403, 0.481, 0.437, 0.666, 0.243, 0.245, 0.343, 0.639, 0.657, 0.360,
               0.593, 0.719],
        '含糖率': [0.460, 0.367, 0.264, 0.318, 0.215, 0.237, 0.149, 0.211, 0.091, 0.267, 0.057, 0.099, 0.161, 0.198, 0.370,
                0.042, 0.103],
        '好瓜': ['是', '是', '是', '是', '是', '是', '是', '是', '否', '否', '否', '否', '否', '否', '否', '否', '否']
    }
	
    # 测试集
    test = {
        '色泽': ['青绿'],
        '根蒂': ['蜷缩'],
        '敲声': ['浊响'],
        '纹理': ['清晰'],
        '脐部': ['凹陷'],
        '触感': ['硬滑'],
        '密度': [0.697],
        '含糖率': [0.460]
    }

    data = pd.DataFrame(dataset)
    X = data.iloc[:, :-1]
    Y = data.iloc[:, -1]
    xtest = pd.DataFrame(test)

    clf = naiveBayesClassifier()
    clf.fit(X, Y)
    print(clf.predict(xtest))
    print(clf.predict_prob(xtest))

4.sklearn库实现

简单实现一下,详细可看:
https://blog.csdn.net/qq_38163244/article/details/109154089

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import BernoulliNB
from sklearn.metrics import accuracy_score

# 导入鸢尾花数据集
iris = load_iris()
x = iris.data[:, :-1]
y = iris.target

# 划分数据集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=666)

# 初始化模型
clf = BernoulliNB(alpha=50,binarize=5) # alpha 无改变,binarize 26%->93%
clf.fit(x_train,y_train)
y_pred = clf.predict(x_test)

accuracy_score(y_test,y_pred)

5.参数

详见:
https://blog.csdn.net/qq_38163244/article/details/109154089


仅作学习笔记使用,侵删

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-11-12 19:35:32  更:2021-11-12 19:37:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 6:20:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码