这篇博客主要涉及到Ng的课第二个讲义,包括生成学习算法
(generate learning algorithm)、高斯判别分析( Gaussian Discriminant Analysis,GDA)、朴素贝叶斯( Navie Bayes)、拉普拉斯平滑( Laplace Smoothing),文本事件模型。
- 生成学习算法
首先要清楚什么是生成学习。之前讲的方法如回归等方法都属于判别学习,也就是直接对问题求解的一种方法,思路是直接根据问题对特征变量建模,搜索解空间找到分割面,判断Y属于哪个区域。其实还有第二种思路,就是根据可能性大小来进行分类。比如对于二分类问题,分别对0,1两类分别建模,然后新来的数据输入后,看它属于这两类的概率,概率高的那一类即为预测类。
概括起来就是,对于变量X和Y,我们可以得到先验概率P(y)和条件概率P(x|y),那么根据贝叶斯公式,我们可以得知:
我们只需要得到最大的条件概率就可以了,也就是求:
- 高斯判别分布
这是一种生成学习方法,要求输入的变量必须是连续的。对于N个随机变量(X1,X2,…….,XN),若他们满足多元高斯分布,则概率分布如下:
那么,我们可以利用高斯分布来得到P(x|y),其中涉及到的量分布如下:
代入数据可以求得最大似然函数:
那么对最大函数求最大值即可。
图形化表示如下图:
其实GDA模型可以和Logistic模型统一起来,关系是
其中的θ是参数φ, Σ,μ某种形式的函数
事实上,当先验分布属于指数分布族中的任何一个分布时都可以推导出逻辑斯蒂回归模型;而反之则不成立。因为Logistic回归的条件更加宽泛。如果数据满足正态分布,使用GDA可以达到较好的效果。
- 朴素贝叶斯
朴素贝叶斯算法也是生成学习方法,可以解决属性是离散值的情况。尤其是在文本分类中应用非常广泛。
以垃圾邮件分类为例,目标结果是{0,1}中的一个,属性是词语,那么可以用一个向量形式化表述某个词是否出现。假设我们已经有了一个字典,每个文本,我们可以用长度等于词典大小的向量表示, 如果文本包含某个词,该词在词典中的索引为 index,则表示文本的向量的index 处设为 1,否则为 0。下面是一个例子:
该文本中包含a和词语buy。
直接对 p(x|y)进行建模会遇到特征太多的情况,那么我们怎么降低特征数量呢?这里要用到朴素贝叶斯假设,各个分量之间是独立的,也就是:
那么可以得到以下参数:
可以求得参数的最大似然估计:
可以得到参数的值:
对于一个新的数据,我们可以求得其条件概率:
- Laplace平滑
朴素贝叶斯有一个很严重的缺陷,那就是对于从未出现过的实例,那么P(x)=P(x|y=1)=0,最后的结果将是0/0,这样是没有意义的。一种解决方法就是为新的实例赋予一个小的概率。
对于一个随机变量 Z,取值范围是{1,2,3…,k},对于 m 次试验后的观测
结果{z(1), z(2), z(3), …, z(m)},极大似然估计是:
使用拉普拉斯平滑后,最大似然公式变为:
那么这时候,即使是从未出现过的新的实例,概率最小值也是1/k,避免了0概率的问题。
与此同时,对应的各个分量的计算公式也要一并更改。
- 文本分类事件模型
根据之前朴素贝叶斯的思路,我们根据字典顺序依次看字典中的词是否出现在邮件中。其实还有另一种思路,那就是我们直接根据邮件内容,确定每个词是否出现在字典中,并标识他的位置。这样我们的向量长度就从字典长度变为邮件的长度。
这时候的变量分布变为:
其中K代表是字典中该词的位置。
求得最大似然估计表达式:
最大化最大似然表达式:
如果这时候要进行Laplace平滑,记得分母上加的不再是2,而是K。
- Weka中的朴素贝叶斯
Weka提供了朴素贝叶斯。
首先看下可用的参数:
-K指的是对数值属性使用核密度估计代替正态分布。
-D指的是对数值属性进行有监督的离散化处理。
代码比较简单,和其他分类算法一致:
class NaiveBayesModel {
private String[] options = {"-O"};
public NaiveBayesModel(Instances data) {
NaiveBayes model = new NaiveBayes();
try {
model.setOptions(options);
model.buildClassifier(data);
} catch (Exception e) {
e.printStackTrace();
}
}
}