机器学习|朴素贝叶斯算法(二)-用sklearn实践贝叶斯

相信上一篇博客肯定已经让你了解了啥叫朴素贝叶斯算法,好歹知道贝叶斯公式是咋来的了,够了!接下来会谈一谈我在刚接触机器学习时,通过sklearn这个实验级的库感受到的朴素贝叶斯算法的强大。

tip:文章可能很长,希望看完了能有所收获

机器学习|朴素贝叶斯算法(一)-贝叶斯简介及应用
机器学习|朴素贝叶斯算法(二)-用sklearn实践贝叶斯
机器学习|朴素贝叶斯算法(三)-深入理解朴素贝叶斯原理

初学机器学习,我用的是python中的sklearn库(scikit-learn)。
这里简单的介绍一下这个强大的库:

简单高效的数据挖掘和数据分析工具
可供所有人使用,并可在各种环境下重复使用
基于NumPy,SciPy和matplotlib(都是python强大的数据处理库)
开源!!!也就是说每一个具体的function我们都能看到源代码!

那么如何用sklearn来做机器学习呢?

数据的预处理(Preprocess),这个其实是最头痛的过程,按照具体情况而异,因为我也是刚刚入坑机器学期不久,也没有实战的经验(以后会有啦,还会补充),这里就简单谈一下如何用sklearn做一个朴素贝叶斯算法(naïve_bayes)的分类器(NextGEN Gallery ),听说还有半朴素贝叶斯分类器(semi-naïve Byes classficat)。。。

首先再来说一下贝叶斯分类器的分类原理

通过某对象的先验概率,利用贝叶斯公式计算出其后验概率,即该对象属于某一类的概率,选择具有最大后验概率的类作为该对象所属的类。目前研究较多的贝叶斯分类器主要有四种,分别是:Naive Bayes、TAN、BAN和GBN。

先验概率,后验概率,似然和概率,我相信很多人是跟我之前是一样是非常糊(meng)涂(bi),这里也不深入研究,就简单说一下目前我的理解,如果觉得说的哪里不对,欢迎博客下方留下指教哈( ̄︶ ̄)↗ 

先验概率:事情还没有发生,要求这件事情发生的可能性大小。比如说你扔一枚硬币,求它正面朝上的概率,基于我们之前抛掷一百万次的事实基础,我们知道的这个概率就是先验概率。

下面重点来说说似然(函数)和概率,这个也是整了一会也问了老师才彻(gang)底(gang)明(ru)白(men)的。

什么叫似然?

似然就是从观察值来推测参数,换句话说,似然是在未知数据分布函数的情况下,根据已有的观察值去推断该观察值来源于什么样的分布函数的概率,这里我观察值可以理解为分类的结果。更专业的解释:似然函数也称作似然,是一个关于统计模型参数的函数。也就是这个函数中自变量是统计模型的参数(一个变量概率分布函数的自变量就是那个$X$,这里可以理解成反过来,也就是上文所说的,已知一个观测到的结果去求一种参数设置对产生这个结果的概率是多少)。对于结果 $x$ ,在参数集合 $θ$ 上的似然,就是在给定这些参数值的基础上,观察到的结果的概率 $L(θ|x)=P(x|θ)$ 。也就是说,似然是关于参数的函数,在参数给定的条件下,对于观察到的 $x$ 的值的条件分布。最后来举个例子,同样的像上文一样我抛一枚硬币十次,观察到的结果十次都是朝上,那么请问“这个硬币是正反两面均匀的可能性是多少”,这里求的“可能性”就是似然。

什么叫概率?

概率是有了参数来预测观察值,话句话讲,概率就是已知数据分布函数去推断的。

好了,难点终于解释完了,那么后验概率呢?可别想蒙混过关。

什么叫后验概率?

是在得到观察值之后在重新加以修正的概率,也就是所谓的条件概率。

再来看一个公式:$Posterior∝Likelihood∗Prior$(后验概率正比于似然乘以先验概率),这样就能更好理解了,其实就是第一篇里举例的时候说到的,其实是有贝叶斯公式得来的,只不过我们在解决问题的时候分母是同一个,也就是固定的,所以就可以推导出这个正比的关系。

不信你再看一遍贝叶斯公式:$P ( H | E ) = \frac{P (E | H) * P (H)}{P (E)}$

$P (E | H)$就是似然函数,而$P(H)$就是先验概率(Prior),$P(E)$起到归一化作用。啥叫归一化,简单来说就是为了使数据之间具有可比较性而进行的标准化处理使其处于同一数量级,所以归一化也叫标准化,比如1厘米和1米就没有可比较性,要么同一到厘米,要么同一到米呗。

而在scikit-learn中,一共有3个朴素贝叶斯的分类算法类。分别是GaussianNB,MultinomialNB和BernoulliNB。这三种分类算法是按照先验的不同而划分产生的,其中GaussianNB就是先验为高斯分布的朴素贝叶斯,MultinomialNB就是先验为多项式分布的朴素贝叶斯,而BernoulliNB就是先验为伯努利分布的朴素贝叶斯。

朴素贝叶斯方法是一种基于贝叶斯定理和每对特征间独立假设的监督学习算法。 给定一个类变量和一个从属特征向量,贝叶斯定理说明了如下关系:

$$ P\left ( y|x_{1},…,x_{n} \right )=\frac{P\left ( y \right )P\left ( x_{1},…x_{n}|y \right )}{P\left ( x_{1},…x_{n} \right )} $$

使用朴素独立的假设我们可以知道:

$$ P\left ( x_{i}|y,x_{1},…,x_{i-1},..x_{i+1},…x_{n} \right )=P\left ( x_{i}|y \right ) $$

其实上面的 $P\left ( x_{i} \right |y,x_{1},x_{2},….x_{i-1},x_{i},…x_{n})$这个意思就是$x_{i}$在$y,x_{1},x_{2},….x_{i-1},x_{i},…x_{n}$这些变量的联合条件(自创概念)下的概率,又因为我们所采用的朴素贝叶斯分类进行了“属性条件独立性假设”,也就是说每一个$x_{i}$之间互相独立,所以上等式成立。

既然自创了联合条件,那么我还是把什么叫联合概率简单说一下吧!

以二维的举例:

二位随机变量(X,Y)的性质不仅与X及Y有关,而且还(可能相互依赖,比如朴素贝叶斯就假设相互独立)依赖于这两个随机变量的相互关系。因此,借助“分布函数”来研究二维随机变量。

设(X,Y)是二维随机变量,对于任意实数$x,y,$二元函数:

$$ F\left(x,y \right )=P\left \{ \left(X\leqslant x \right )\cap \left(Y\leqslant y \right )\right \}\Rightarrow $$

$$ P\left \{ X\leqslant x,Y\leqslant y \right \} $$

称为二维随机变量(X,Y)的(联合)分布函数。

由上面分析,可以得到这个等式:$P\left(x_{1},…,x_{n}|y \right )=\prod_{i=1}^{n}P\left(x_{i}|y \right )$

因此,对所有的 i 这个关系可以被简化为:

$$ P\left ( y|x_{1},…,x_{n} \right )=\frac{P\left ( y \right )\prod_{i=1}^{n}P\left ( x_{i}|y \right )}{P\left ( x_{1},……x_{n} \right )} $$

由于输入的$P\left(x_{1},…,x_{n}\right)$是固定不变的,我们可以使用下面的分类规则:

$$ P\left(y|x_{1},…x_{n} \right )\propto P\left(y \right )\prod_{i=1}^{n}P\left(x_{i}|y \right ) $$

$$ \Rightarrow $$

$$ \hat{y}=arg\underset{y}{max}P\left ( y \right )\prod_{i=1}^{n}P\left ( x_{i}|y \right ) $$

我们可以用最大后验估计(Maximum A Posteriori ,MAP)来估计$P\left(y\right)$和$P\left(x_{i}|y \right )$,其中$P\left(y\right)$是训练集中y的相对频率(也就是$y$训练集总数)。

不同的朴素贝叶斯分类器的主要区别在于它们对$P\left(x_{i}|y \right )$的分布的假设。

显然朴素贝叶斯是在假设条件之间互相独立(显然,这样简化貌似有点草率),但是朴素贝叶斯分类器已经在许多现实世界的情况下工作得却很好,尤其是在的文档分类垃圾邮件过滤的应用上。因为他们需要少量的训练数据来估计必要的参数,比如上文提到的垃圾邮件过滤实践,只需要一封垃圾邮件,就能估计出很多相似类型的邮件为垃圾邮件。

和其他机器学习算法相比,sklearn中朴素贝叶斯算法的可调参数相对较少,而且学习难度也低(要不咋第一篇写呢),但是分类所需时间却可以非常的快(我试过和SVM比较过,忘了是fit()时间较少还是predict()时间较少了,这个自己遇到动手试一下就ojbk啦)。类别条件特征分布的解耦(啥叫耦合,这里意思就是条件特征相互有影响)意味着每个分布可以被独立地估计为一维分布。这就有助于减少维度过多带来的麻烦。
另一方面,尽管朴素贝叶斯(Naïve Bayes)被认为是一个不错的分类器,但它被认为是一个不好的估计器,所以一般不用它来获得测试向量的概率估计。

下面贴一下我用sklearn代码吧!(数据预处理省略(我也不会(ノへ ̄、)))

def classify(features_train, labels_train):
    import numpy as np 
    from sklearn.naive_bayes 
    import GaussianNB 
    X = features_train 
    Y = labels_train 
    clf = GaussianNB() 
    clf.fit(X, Y) 
    return clf 
  
 
def NB_Accuracy(features_train, labels_train,features_test, labels_test): 
  """ 计算分类器的准确率""" 
  ### 导入sklearn模块的GaussianNB 
  from sklearn.naive_bayes import GaussianNB 
  
  ### 创建分类器 
  clf = GaussianNB() 
  
  ### 训练分类器 
  X=features_train 
  Y=labels_train 
  clf.fit(X,Y) 
  
  ### 用训练好的分类器去预测测试集的标签值 
  pred =clf.predict(features_test) 
  
  ### 计算并返回在测试集上的准确率 
  from sklearn.metrics import accuracy_score 
  y_pred =pred 
  y_true =labels_test
  accuracy_score(y_true, y_pred) 
  
  return accuracy_score(y_true, y_pred,normalize=False)

sklearn我觉得应该算是实验级的机器学期库,也是开源的,如果初学机器学习,不妨用sklearn上手,可以在不知其所以然的情况下进行预测等一些机器学习实践,让你自信心爆棚!下面会从另一个角度再理解一下朴素贝叶斯算法,加深对算法的理解,何乐而不为呢

点赞