NaiveBayes(朴素贝叶斯)
NaiveBayes是一个Estimator,是比较基础的分类算法。输入带有label和features列的训练集得到分类器模型;NaiveBayesModel是spark对训练集fit后的模型对象,该对象中存放了模型为了预测最终概率而存放的一些中间值,比如所有分类在数据集中的先验概率对数;最终transform新数据的输出包含了原有输入信息,先验概率与条件概率乘积后的对数(raw prediction),各个分类值的后验概率(probability)以及最终预测的分类(prediction)。
伪算法过程
贝叶斯公式
贝叶斯公式是一种通过已知的先验概率和条件概率来求得后验概率的公式:
$$p(C|F_{1},…,F_{n})=\frac{p(C)p(F_{1},…,F_{n}|C)}{p(F_{1},…,F_{n})}$$
其中左式部分就要求的当属性集合F的一组数据发生时,类别C的条件概率,又被称为后验概率(posterior);右式中的$p(C)$表示C分类发生的先验概率(prior);右式中的$p(F_{1},…,F_{n}|C)$是当C类样本发生后属性集出现某一组值的条件概率(likelihood);右式中的$p(F_{1},…,F_{n})$是整个属性集上某一组值发生的概率(evidence),这部分对于所有分类C来说是常数。
根据贝叶斯公式,以最大的C类别出现的概率作为分类结果,既是贝叶斯分类。由于likelihood的计算需要知道各个属性间的联合概率分布,难以精确计算,所以在这个模型前我们假设各个属性相互独立,这样的话,likelihood就变为计算各个属性发生的概率的乘积:
$$p(F_{1},…,F_{n}|C)=\prod_{i=1}^{n}p(F_{i}|C)$$
这种所有属性相互独立的假设大家都觉得比较艰(tu)苦(de)朴(diao)素(zha),所以这样的模型被称为朴素贝叶斯分类模型。
模型
Spark中可以使用的贝叶斯模型有2种类型,取决于属性集代表的含义,当属性集字段中的数值表示每种属性出现的频次(>=0)数据时,使用multinomial模型,当属性集字段中的数值表示某件事情发生和未发生时(只能是0/1),使用bernoulli模型。(现实中属性集如果是正态分布的连续型随机变量,比如身高体重等,则可以使用Gaussian Naive Bayes模型,但Spark当前版本2.2.0内还没有实现该模型)
概率计算
贝叶斯模型的计算比较简单,可以直接精确计算,不需要想线性回归算法那样进行迭代拟合,所以执行效率非常高。Spark的实现——公式中的先验概率(prior)——$p(C)$使用训练集中C类样本出现的频率来近似;条件概率(likelihood)——$p(F_{1},…,F_{n}|C)$使用训练集每个C类样本中各个属性F出现的频率来近似;全概率常量(evidence)——$p(F_{1},…,F_{n})$相当于各个分类C发生后的条件概率的和,不再需要单独计算。
平滑补偿
平滑补偿(Additive smoothing)是用来在贝叶斯模型的训练集中出现某些分类值缺失,或者某些属性值缺失(频率为0)的情况下,使得模型不出现0概率的预测。频率计算通常采用出现的次数/总体样本数,当出现的次数在训练集中恰巧缺失的情况下,出现0概率预测,为了避免这种情况,默认给频次和总体样本数加上一个小到可以忽略不计的补偿值α。公式如下,当α=1时也称为拉普拉斯平滑(Laplace smoothing):
$$\frac{f_{i}+\alpha}{N+\alpha{d}}\quad (i=1,…,d)$$
上式中d为属性f可能的取值范围,这样所有可能性加起来还能保证为全概率1。Spark中如果是multinomial模型,d为所有features数;如果是bernoulli模型d为2。
权重
Spark支持带权重的朴素贝叶斯模型,权重值相当于对训练集数据做了采样(Sampling),在计算属性频率时会乘上权重值。
参数
输入输出相关:
- labelCol: 输入训练集中标记字段的名称 (默认值: label)
- featuresCol: 输入训练集和预测数据集中的属性向量的字段名称(默认值: features)
- weightCol: 输入训练集中权重字段的名称,如果输入的训练集包含权重字段,则采用带权重的回归模型,如果不包含,相当于权重都是1.0 (没有默认值)
- rawPredictionCol: 输出结果数据中存放先验概率与条件概率乘积后的对数的字段名称 (默认值: rawPrediction)
- probabilityCol: 输出结果数据中存放各个分类值的后验概率的字段名称 (默认值: probability)
- predictionCol: 输出结果数据中最终判别类别的字段名称 (默认值: prediction)
算法模型相关:
- modelType: 根据属性参数含义选取不通概率计算模型(默认值:multinomial)
可选项1. multinomial-属性集字段中的数值表示每种属性出现的频次(>=0)数据;
可选项2. bernoulli-属性集字段中的数值表示某件事情发生和未发生时(只能是0/1)。 - smoothing: 平滑参数,具体使用方式见上面平滑补偿(Additive smoothing)相关介绍,当该值为0时既是不采取平滑。(>=0,默认值: 1.0)
- thresholds: 获取最终分类结果时,根据该组数组值将计算得到后验概率映射到分类类别上,该数组长度必须和类别数量吻合,最终选择的分类是几率值除以该分类的threshold值最大的那个,如果没有设置,相当于直接取概率最大的。(无默认值)
model对象的成员
- numClasses: 返回模型有多少个分类。
- numFeatures: 返回模型有多少个属性。
- pi: 返回模型中每个分类的先验概率的对数值,是一个长度为训练集中类别出现次数的向量。
- theta: 返回模型中每个分类下每个属性发生的条件概率的对数值,是一个长为训练集中类别出现次数,宽为属性个数的矩阵。
例子
1 | val training = spark.createDataFrame(Seq( |