天池龙珠训练营—机器学习算法(二): 朴素贝叶斯(Naive Bayes)

本文主要是介绍天池龙珠训练营—机器学习算法(二): 朴素贝叶斯(Naive Bayes),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理为基础,故统称为贝叶斯分类。而朴素朴素贝叶斯分类是贝叶斯分类中最简单,也是常见的一种分类方法。这篇文章我尽可能用直白的话语总结一下我们学习会上讲到的朴素贝叶斯分类算法,希望有利于他人理解。
分类问题综述
对于分类问题,其实谁都不会陌生,日常生活中我们每天都进行着分类过程。例如,当你看到一个人,你的脑子下意识判断他是学生还是社会上的人;你可能经常会走在路上对身旁的朋友说“这个人一看就很有钱、”之类的话,其实这就是一种分类操作。

既然是贝叶斯分类算法,那么分类的数学描述又是什么呢?

从数学角度来说,分类问题可做如下定义:已知集合[公式]和[公式],确定映射规则y = f(),使得任意[公式]有且仅有一个[公式],使得[公式]成立。

其中C叫做类别集合,其中每一个元素是一个类别,而I叫做项集合(特征集合),其中每一个元素是一个待分类项,f叫做分类器。分类算法的任务就是构造分类器f。

分类算法的内容是要求给定特征,让我们得出类别,这也是所有分类问题的关键。那么如何由指定特征,得到我们最终的类别,也是我们下面要讲的,每一个不同的分类算法,对应着不同的核心思想。

朴素贝叶斯分类
那么既然是朴素贝叶斯分类算法,它的核心算法又是什么呢?

是下面这个贝叶斯公式:在这里插入图片描述
换个表达形式就会明朗很多,如下:在这里插入图片描述
我们最终求的p(类别|特征)即可!就相当于完成了我们的任务。
例题分析
下面我先给出例子问题。

给定数据如下:在这里插入图片描述
现在给我们的问题是,如果一对男女朋友,男生想女生求婚,男生的四个特点分别是不帅,性格不好,身高矮,不上进,请你判断一下女生是嫁还是不嫁?

这是一个典型的分类问题,转为数学问题就是比较p(嫁|(不帅、性格不好、身高矮、不上进))与p(不嫁|(不帅、性格不好、身高矮、不上进))的概率,谁的概率大,我就能给出嫁或者不嫁的答案!

这里我们联系到朴素贝叶斯公式:在这里插入图片描述
我们需要求p(嫁|(不帅、性格不好、身高矮、不上进),这是我们不知道的,但是通过朴素贝叶斯公式可以转化为好求的三个量,p(不帅、性格不好、身高矮、不上进|嫁)、p(不帅、性格不好、身高矮、不上进)、p(嫁)(至于为什么能求,后面会讲,那么就太好了,将待求的量转化为其它可求的值,这就相当于解决了我们的问题!)
朴素贝叶斯算法的朴素一词解释
那么这三个量是如何求得?

是根据已知训练数据统计得来,下面详细给出该例子的求解过程。

回忆一下我们要求的公式如下:在这里插入图片描述
那么我只要求得p(不帅、性格不好、身高矮、不上进|嫁)、p(不帅、性格不好、身高矮、不上进)、p(嫁)即可,好的,下面我分别求出这几个概率,最后一比,就得到最终结果。
p(不帅、性格不好、身高矮、不上进|嫁) = p(不帅|嫁)*p(性格不好|嫁)*p(身高矮|嫁)*p(不上进|嫁),那么我就要分别统计后面几个概率,也就得到了左边的概率!

等等,为什么这个成立呢?学过概率论的同学可能有感觉了,这个等式成立的条件需要特征之间相互独立吧!

对的!这也就是为什么朴素贝叶斯分类有朴素一词的来源,朴素贝叶斯算法是假设各个特征之间相互独立,那么这个等式就成立了!

但是为什么需要假设特征之间相互独立呢?

1、我们这么想,假如没有这个假设,那么我们对右边这些概率的估计其实是不可做的,这么说,我们这个例子有4个特征,其中帅包括{帅,不帅},性格包括{不好,好,爆好},身高包括{高,矮,中},上进包括{不上进,上进},那么四个特征的联合概率分布总共是4维空间,总个数为233*2=36个。

24个,计算机扫描统计还可以,但是现实生活中,往往有非常多的特征,每一个特征的取值也是非常之多,那么通过统计来估计后面概率的值,变得几乎不可做,这也是为什么需要假设特征之间独立的原因。2、假如我们没有假设特征之间相互独立,那么我们统计的时候,就需要在整个特征空间中去找,比如统计p(不帅、性格不好、身高矮、不上进|嫁),

我们就需要在嫁的条件下,去找四种特征全满足分别是不帅,性格不好,身高矮,不上进的人的个数,这样的话,由于数据的稀疏性,很容易统计到0的情况。 这样是不合适的。

根据上面俩个原因,朴素贝叶斯法对条件概率分布做了条件独立性的假设,由于这是一个较强的假设,朴素贝叶斯也由此得名!这一假设使得朴素贝叶斯法变得简单,但有时会牺牲一定的分类准确率。

好的,上面我解释了为什么可以拆成分开连乘形式。那么下面我们就开始求解!

我们将上面公式整理一下如下:在这里插入图片描述
在这里插入图片描述
则 p(嫁) = 6/12(总样本数) = 1/2
p(不帅|嫁)=?统计满足样本数如下:在这里插入图片描述
则p(不帅|嫁) = 3/6 = 1/2
p(性格不好|嫁)= ?统计满足样本数如下:在这里插入图片描述
1.3.朴素贝叶斯(Naive Bayes)的应用
朴素贝叶斯算法假设所有特征的出现相互独立互不影响,每一特征同等重要,又因为其简单,而且具有很好的可解释性一般。相对于其他精心设计的更复杂的分类算法,朴素贝叶斯分类算法是学习效率和分类效果较好的分类器之一。朴素贝叶斯算法一般应用在文本分类,垃圾邮件的分类,信用评估,钓鱼网站检测等。

sklearn库提供了三个朴素贝叶斯分类算法:

高斯朴素贝叶斯(GaussianNB):特征变量是连续变量,符合高斯分布,比如说人的身高,物体的长度;
类目朴素贝叶斯(CategoricalNB):专用于离散数据集;
多项式朴素贝叶斯(MultinomialNB):特征变量是离散变量,符合多项分布,在文档分类中特征变量体现在一个单词出现的次数,或者是单词的 TF-IDF 值等。不支持负数,所以输入变量特征的时候,别用StandardScaler进行标准化数据,可以使用MinMaxScaler进行归一化。多项式朴素贝叶斯是以单词为粒度,会计算在某个文件中的具体次数,适用于文本分类;
伯努利朴素贝叶斯(BernoulliNB):不支持负数,所以输入变量特征的时候,别用StandardScaler进行标准化数据,可以使用MinMaxScaler进行归一化。伯努利朴素贝叶斯是以文件为粒度,如果该单词在某文件中出现了即为 1,否则为 0。常见于文本分类场景。
算法实战——基于iris数据集的贝叶斯分类

导入高斯朴素贝叶斯分类器

from sklearn.naive_bayes import GaussianNB

sklearn内置的dataset支持直接返回自变量与因变量

X, y = datasets.load_iris(return_X_y=True)

拆分训练集和测试集

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
1
2
3
4
5
6
我们需要计算两个概率分别是:条件概率:P ( X ( i ) = x ( i ) ∣ Y = c k ) P(X{(i)}=x{(i)}|Y=c_k)P(X
(i)
=x
(i)
∣Y=c
k

)和类目c k c_kc
k

的先验概率:P ( Y = c k ) P(Y=c_k)P(Y=c
k

)。

通过分析发现训练数据是数值类型的数据,这里假设每个特征服从高斯分布(正态分布),因此我们选择高斯朴素贝叶斯来进行分类计算。

高斯朴素贝叶斯假设每个特征都服从高斯分布,我们把一个随机变量X服从数学期望为μ,方差为σ 2 σ^2σ
2
的数据分布称为高斯分布。对于每个特征我们一般使用平均值来估计μ和使用所有特征的方差估计σ 2 σ^2σ
2

P ( X ( i ) = x ( i ) ∣ Y = c k ) = 1 2 π σ y 2 exp ⁡ ( − ( x ( i ) − μ c k ) 2 2 σ c k 2 ) P(X{(i)}=x{(i)}|Y=c_k) = \frac{1}{\sqrt{2\pi\sigma^2_y}} \exp\left(-\frac{(x^{(i)} - \mu_{c_k})2}{2\sigma2_{c_k}}\right)
P(X
(i)
=x
(i)
∣Y=c
k

)=
2πσ
y
2

1

exp(−

c
k

2

(x
(i)
−μ
c
k


)
2


)

2.1. 模型训练与预测

使用高斯朴素贝叶斯进行计算

clf = GaussianNB(var_smoothing=1e-8) # var_smoothing进行拉普拉斯平滑,方便有效的避免零概率问题
clf.fit(X_train, y_train)

评估

y_pred = clf.predict(X_test)
acc = np.sum(y_test == y_pred) / X_test.shape[0] # 分类正确的除以整体数量
print(“Test Acc : %.3f” % acc) # 0.967

预测

y_proba = clf.predict_proba(X_test[:1])
print(clf.predict(X_test[:1]))
print(“预计的概率值:”, y_proba) # 软分类模型,可输出各种类别的置信概率

[1.63542393e-232 2.18880483e-006 9.99997811e-001]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
从上述例子中的预测结果中,我们可以看到类别2对应的后验概率值最大,所以我们认为类目2是最优的结果。

  1. 模拟离散数据集–贝叶斯分类
    3.1. 创建模拟离散数据

使用基于类目特征的朴素贝叶斯

from sklearn.naive_bayes import CategoricalNB

模拟数据

rng = np.random.RandomState(1)

随机生成600个100维的数据,每一维的特征都是[0, 4]之前的整数

X = rng.randint(5, size=(600, 100))

y = np.array([1, 2, 3, 4, 5, 6] * 100)
data = np.c_[X, y]

X和y进行整体打散

random.shuffle(data)
X = data[:,:-1]
y = data[:, -1]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
至此,所有的数据特征都是离散特征,我们引入基于离散特征的朴素贝叶斯分类器。

3.2. 模型训练&预测

当 alpha=1 时,使用的是 Laplace 平滑; 当 0<alpha<1 时,使用的是 Lidstone 平滑

clf = CategoricalNB(alpha=1)
clf.fit(X_train, y_train)
acc = clf.score(X_test, y_test)
print(“Test Acc : %.3f” % acc) # 0.683
1
2
3
4
5

随机数据测试,分析预测结果,贝叶斯会选择概率最大的预测结果

x = rng.randint(5, size=(1, 100))
print(clf.predict_proba(x))
print(clf.predict(x))

[3.48859652e-04, 4.34747491e-04, 2.23077189e-03, 9.90226387e-01, 5.98248900e-03, 7.76745425e-04]

可见第四个类别概率最大

1
2
3
4
5
6
这里的测试数据的准确率没有任何意义,因为数据是随机生成的,不一定具有贝叶斯先验性,这里只是作为一个列子

alpha=1这个参数表示什么?

我们知道贝叶斯法一定要计算两个概率:条件概率:P ( X ( i ) = x ( i ) ∣ Y = c k ) P(X{(i)}=x{(i)}|Y=c_k)P(X
(i)
=x
(i)
∣Y=c
k

)和类目c k c_kc
k

的先验概率:P ( Y = c k ) P(Y=c_k)P(Y=c
k

)。

对于离散特征:

P ( X ( j ) = x ( j ) ∣ Y = c k ) = ∑ i = 1 N I ( x i j = a j l , y i = c k ) + α ∑ i = 1 N I ( y i = c k ) + S j α P(X{(j)}=x{(j)}|Y=c_k)=\frac{\sum_{i=1}{N}I(x_ij=a_{jl},y_i=c_k)+\alpha}{\sum_{i=1}^{N}I(y_i=c_k)+S_j\alpha}
P(X
(j)
=x
(j)
∣Y=c
k

)=

i=1
N

I(y
i

=c
k

)+S
j

α

i=1
N

I(x
i
j

=a
jl

,y
i

=c
k

)+α

我们可以看出就是对每一个变量的多加了一个频数alpha。当alphaλ=0时,就是极大似然估计。通常取值alpha=1,这就是拉普拉斯平滑(Laplace smoothing),这有叫做贝叶斯估计,主要是因为如果使用极大似然估计,如果某个特征值在训练数据中没有出现,这时候会出现概率为0的情况,导致整个估计都为0,因为引入贝叶斯估计。

其中:

S j S_jS
j

:表示第j个特征的个数。

x i j x_i^jx
i
j

:表示第i个样本的第j维元素。

y i y_iy
i

:第i个样本的label。

  1. 朴素贝叶斯在自然语言处理中的应用
    4.1. TD-IDF
    sklearn 中我们直接使用 TfidfVectorizer 类,它可以帮我们计算单词 TF-IDF 向量的值。

TfidfVectorizer(stop_words=stop_words, token_pattern=token_pattern)

停用词 stop_words 是一个列表 List 类型。停用词就是在分类中没有用的词,这些词一般词频 TF 高,但是 IDF 很低,起不到分类的作用

过滤规则 token_pattern 是正则表达式

1
2
3
4.2. 文本分类
4.2.1. 准备阶段
4.2.1.1. 文档分词
在英文文档中,最常用的是 NTLK 包。NTLK 包中包含了英文的停用词 stop words、分词和标注方法。

import nltk
word_list = nltk.word_tokenize(text) #分词
nltk.pos_tag(word_list) #标注单词的词性
1
2
3
在中文文档中,最常用的是 jieba 包,jieba 包中包含了中文的停用词 stop words 和分词方法。

import jieba
word_list = jieba.cut (text) #中文分词
1
2
4.2.1.2. 去停用词
加载停用词表我们需要自己读取停用词表文件

stop_words = [line.strip().decode(‘utf-8’) for line in io.open(‘stop_words.txt’).readlines()]
1
4.2.1.3. 单词权重计算
直接创建 TfidfVectorizer 类,然后使用 fit_transform 方法进行拟合,得到 TF-IDF 特征空间 features,可以理解为选出来的分词就是特征。

max_df 参数用来描述单词在文档中的最高出现率,一般很少设置 min_df,因为 min_df 通常都会很小。

tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5)
features = tf.fit_transform(train_contents)
1
2
3
4.2.2. 分类阶段
4.2.2.1. 通过训练集得到朴素贝叶斯分类器
将特征训练集的特征空间 train_features,以及训练集对应的分类 train_labels 传递给贝叶斯分类器 clf,它会自动生成一个符合特征空间和对应分类的分类器。

其中,alpha 为平滑参数,因为如果一个单词在训练样本中没有出现,这个单词的概率就会被计算为 0。但训练集样本只是整体的抽样情况,我们不能因为一个事件没有观察到,就认为整个事件的概率为 0。

当 alpha=1 时,使用的是 Laplace 平滑。Laplace 平滑就是采用加 1 的方式,来统计没有出现过的单词的概率。这样当训练样本很大的时候,加 1 得到的概率变化可以忽略不计,也同时避免了零概率的问题。
当 0<alpha<1 时,使用的是 Lidstone 平滑。对于最大似然平滑来说,alpha 越小,迭代次数越多,精度越高。我们可以设置 alpha 为 0.001。

多项式贝叶斯分类器

from sklearn.naive_bayes import MultinomialNB
clf = MultinomialNB(alpha=0.001).fit(train_features, train_labels)
1
2
3
4.2.2.2. 将分类器应用于测试集,并与实际结果做对比
首先我们需要得到测试集的特征矩阵,用训练集的分词创建一个 TfidfVectorizer 类,使用同样的 stop_words 和 max_df,然后用这个 TfidfVectorizer 类对测试集的内容进行 fit_transform 拟合,得到测试集的特征矩阵 test_features。

test_tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5, vocabulary=train_vocabulary)
test_features=test_tf.fit_transform(test_contents)
1
2
用训练好的分类器对新数据做预测。方法是使用 predict 函数,传入测试集的特征矩阵 test_features,得到分类结果 predicted_labels,predict 函数做的工作就是求解所有后验概率并找出最大的那个。

4.2.2.3. 最终得到测试集的分类准确率
算准确率实际上是对分类模型的评估。我们可以调用 sklearn 中的 metrics 包,在 metrics 中提供了 accuracy_score 函数

from sklearn import metrics
print metrics.accuracy_score(test_labels, predicted_labels)

这篇关于天池龙珠训练营—机器学习算法(二): 朴素贝叶斯(Naive Bayes)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/410471

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]