斯坦福公开课5:生成学习

北京理工大学计算机专业2016级硕士在读,方向:Machine Learning,NLP,DM

2017/3/21 9:08:46

本讲大纲:

1.生成学习算法(Generative learning algorithm) 
2.高斯判别分析(GDA,Gaussian Discriminant Analysis) 
3.朴素贝叶斯(Naive Bayes) 
4.拉普拉斯平滑(Laplace smoothing)


生成学习

判别学习算法(discriminative learning algorithm):直接学习p(y|x)(比如说logistic回归)或者说是从输入直接映射到{0,1}.

生成学习算法(generative learning algorithm):对p(x|y)p(y)进行建模。(p(y)不是很重要)

简单的来说,判别学习算法的模型是通过一条分隔线把两种类别区分开,而生成学习算法是对两种可能的结果分别进行建模,然后分别和输入进行比对,计算出相应的概率。

比如说良性肿瘤和恶性肿瘤的问题,对良性肿瘤建立model1(y=0),对恶性肿瘤建立model2(y=1),p(x|y=0)表示是良性肿瘤的概率,p(x|y=1)表示是恶性肿瘤的概率.

根据贝叶斯公式(Bayes rule)推导出y在给定x的概率为:

另见《生成学习与判别学习的区别》一文

高斯判别分析

GDA是要学习的第一个生成学习算法.

GDA的两个假设:

  • 假设输入特征x∈Rn,并且是连续值;
  • p(x|y)是多维正态分布(multivariate normal distribution);


1、多维正态分布

若x服从多维正态分布(也叫多维高斯分布),均值向量(mean vector),协方差矩阵(convariance matrix),写成x~, 其概率密度函数为: 
 
表示行列式(determinant).

均值: 
协方差Cov(Z)== = ∑

高斯分布的一些例子: 
 
左图均值为零(2*1的零向量),协方差矩阵为单位矩阵I(2*2)(成为标准正态分布). 
中图协方差矩阵为0.6I, 
右图协方差矩阵为2I

 
均值为0,方差分别为: 

可见增加矩阵对角元素的值,即变量间增加相关性,高斯曲面会沿z1=z2(两个水平轴)方向趋于扁平。其水平面投影图如下:

即增加∑对角线的元素,图形会沿45°角,偏转成一个椭圆形状。

若∑对角线元素为负,图形如下:

∑分别为:

不同μ的图形如下:

μ分别为:

μ决定分布曲线中心的位置。

2、高斯判别分析模型 
 
写出概率分布: 

模型的参数为φ,μ0,μ1,∑,对数似然性为: (生成学习考虑的是joint likelihood 联合似然,判别学习算法考虑conditional likelihood)

求出最大似然估计为: (详细推导见http://www.cnblogs.com/jcchen1987/p/4424436.html  Σ的答案有误)

φ:训练样本中标签为1的样本所占的比例

μ0:分母为标签为0的样本数,分子是对标签为0的样本的x(i)求和,结合起来就是对对标签为0的样本的x(i)求均值,与高斯分布参数μ为均值的意义相符

μ1:与μ0同理,标签改为1

结果如图所示:

Predict:

预测结果应该是给定x的情况下最可能的y,等式左边的运算符argmax表示计算p(y|x)最大时的y值,预测公式如下:

因为p(x)独立于y,所以可以忽略p(x)。

如果p(y)为均匀分布,即每种类型的概率都相同,那么也可以忽略p(y),要求的就是使p(x|y)最大的那个y。不过这种情况并不常见。

3、GDA和logistic回归的联系

P(y=1|x)看作x的函数,则有:

其中θ是φ,∑,μ1,μ2的函数,这正是logistic回归的形式。

4、使用生成学习算法的优缺点

推论1:

x|y 服从高斯分布  =>  p(y=1|x)是logistic函数

该推论在反方向不成立。

推论2:

x|y=1 ~ Poisson(λ1),x|y=0 ~ Poisson(λ0)  =>  p(y=1|x)是logistic函数

x|y=1 ~ Poisson(λ1)表示x|y=1服从参数为λ1泊松分布

推论3:

x|y=1 ~ ExpFamily(η1),x|y=0 ~ ExpFamily (η0)  =>  p(y=1|x)是logistic函数

推论2的推广,即x|y的分布属于指数分布族,均可推出结论。显示了logistic回归在建模假设选择方面的鲁棒性

优点:

  • 推论1反方向不成立,因为x|y服从高斯分布这个假设更强,GDA模型做出了一个更强的假设,所以,若x|y服从或近似服从高斯分布,那么GDA会比logistic回归更好,因为它利用了更多关于数据的信息,即算法知道数据服从高斯分布。

缺点:

  • 如果不确定x|y的分布情况,那么判别算法logistic回归性能更好。例如,预先假设数据服从高斯分布,但是实际上数据服从泊松分布,根据推论2,logistic回归仍能获得不错的效果。
  • 生成学习算法比判决学习算法需要更少的数据。如GDA的假设较强,所以用较少的数据能拟合出不错的模型。而logistic回归的假设较弱,对模型的假设更为健壮,拟合数据需要更多的样本。

朴素贝叶斯

学习的第二个生成模型方法

引例:垃圾邮件分类

实现一个垃圾邮件分类器,以邮件输入流作为输入,确定邮件是否为垃圾邮件。输出y为{0,1},1为垃圾邮件,0为非垃圾邮件。

首先,要将邮件文本表示为一个输入向量x,设已知一个含有n个词的字典,那么向量x的第i个元素{0,1}表示字典中的第i个词是否出现在邮件中,x示例如下:

要对p(x|y)建模,x是一个n维的{0,1}向量,假设n=50000,那么x有2^50000种可能的值,一种方法是用多项式分布进行建模(伯努利分布对01建模,多项式分布对k个结果建模),这样就需要2^50000-1个参数,可见参数过多,下面介绍朴素贝叶斯的方法。

假设xi在给定y的时候是条件独立的,则x在给定y下的概率可简化为:(第二个=用到了朴素贝叶斯假设) 假设虽然有缺陷,但是实际效果很好。

模型参数包括:

Φi|y=1 = p(xi=1|y=1)

Φi|y=0 = p(xi=1|y=0)

Φy = p(y=1)

联合似然性:

求得参数结果:

Φi|y=1的分子为标记为1的邮件中出现词j的邮件数目和,分母为垃圾邮件数,总体意义就是训练集中出现词j的垃圾邮件在垃圾邮件中的比例。

Φi|y=0就是出现词j的非垃圾邮件在非垃圾邮件中的比例。

Φy就是垃圾邮件在所有邮件中的比例。

求出上述参数,就知道了p(x|y)和p(y),用伯努利分布对p(y)建模,用上式中p(xi|y)的乘积对p(x|y)建模,通过贝叶斯公式就可求得p(y|x)

可以得到:

朴素贝叶斯的问题: 
假设在一封邮件中出现了一个以前邮件从来没有出现的词,在词典的位置是35000,那么得出的最大似然估计为:

也即使说,在训练样本的垃圾邮件和非垃圾邮件中都没有见过的词,模型认为这个词在任何一封邮件出现的概率为0. 
假设说这封邮件是垃圾邮件的概率比较高,那么

模型失灵.

在统计上来说,在你有限的训练集中没有见过就认为概率是0是不科学的.

Laplace平滑

根据极大似然估计,p(y=1) = #”1”s / (#”0”s + #”1”s),即y为1的概率是样本中1的数目在所有样本中的比例。Laplace平滑就是将分子分母的每一项都加1,,即:

p(y=1) = (#”1”s+1)  / (#”0”s+1 + #”1”s+1)

Generally:若y取k中可能的值


对于朴素贝叶斯,得到的结果为:

代码实践

GDA代码实例

训练数据:鸢尾花数据

  1. # -*- coding: utf-8 -*-
  2. from __future__ import division
  3. import numpy as np
  4. import matplotlib as mpl
  5. import matplotlib.pyplot as plt
  6. def GDA( X, y ):
  7. m , m0 , m1 = len(y) , len(y[y==0]) , len(y[y==1])
  8. phi = m0 / m
  9. u0 = np.sum( X[y==0] , axis=0 ) / m0
  10. u1 = np.sum( X[y==1] , axis=0 ) / m1
  11. sigma = np.zeros( (len(X[0]),len(X[0]) ) )
  12. for x , y in zip( X , y ):
  13. if y == 0:
  14. sigma += np.dot( np.transpose([x - u0]) , (x - u0).reshape(1,2) )
  15. else:
  16. sigma += np.dot( np.transpose([x - u1]) , (x - u1).reshape(1,2) )
  17. sigma /= m
  18. return ( phi , u0 , u1 , sigma )
  19. def predict( x , phi , u0 , u1 , sigma ):
  20. inv = np.linalg.inv(sigma)
  21. y_hat = []
  22. for case in x:
  23. p0 = np.dot( np.dot((case - u0) , inv ) , (case - u0).T ) * (1 - phi)
  24. p1 = np.dot( np.dot((case - u1) , inv ) , (case - u1).T ) * phi
  25. y_hat.append( 0 if p0 < p1 else 1 )
  26. return np.array(y_hat)
  27. df = np.loadtxt(r‘C:\Users\LoveDMR\Desktop\8.iris.data‘, delimiter=‘,‘ , converters = { 4: lambda t : {‘Iris-setosa‘:0,‘Iris-versicolor‘:1,‘Iris-virginica‘:2}[t] } );
  28. df = df[df[:,4] != 2] # 为了方便学习 ,只关心二分类问题
  29. #手工特征选择 2个(方便可视化 0-3)
  30. feature = ( 0 , 1 )
  31. C1 = df[df[:,4] == 0]
  32. C2 = df[df[:,4] == 1]
  33. X , y = np.split(df,(4,), axis=1)
  34. X = X[:,feature[0]:feature[1]+1] # 只取两个特征
  35. y = y[:,0]
  36. phi , u0 , u1 , sigma = GDA( X, y )
  37. # 特征分布情况
  38. plt.figure()
  39. x1_min , x1_max = X[:,0].min() , X[:,0].max()
  40. x2_min , x2_max = X[:,1].min() , X[:,1].max()
  41. t1 = np.linspace(x1_min,x1_max , 500)
  42. t2 = np.linspace(x2_min,x2_max , 500)
  43. x1 , x2 = np.meshgrid( t1 , t2 )
  44. x_test = np.stack((x1.flat,x2.flat),axis=1)
  45. y_hat = predict( x_test , phi , u0 , u1 , sigma )
  46. y_hat = y_hat.reshape(x1.shape)
  47. cm_light = mpl.colors.ListedColormap([‘#77E0A0‘, ‘#FF8080‘])
  48. plt.pcolormesh(x1,x2,y_hat,cmap=cm_light)
  49. plt.plot(C1[:,feature[0]],C1[:,feature[1]] , ‘bv‘)
  50. plt.plot(C2[:,feature[0]],C2[:,feature[1]],‘g*‘)
  51. plt.xlim(x1_min, x1_max)
  52. plt.ylim(x2_min, x2_max)
  53. plt.tight_layout()
  54. plt.show()

特征:花萼宽度+花萼长度(左图) |  花瓣宽度+花瓣长度(右图)


补充:协方差计算公式与意义

http://blog.csdn.net/beechina/article/details/51074750

补充:样本方差公式中为什么要除以(n-1)而不是n呢?

样本方差与样本均值,都是随机变量,都有自己的分布,也都可能有自己的期望与方差。取分母n-1,可使样本方差的期望等于总体方差,即这种定义的样本方差是总体方差的无偏估计。 简单理解,因为算方差用到了均值,所以自由度就少了1,自然就是除以(n-1)了。
再不能理解的话,形象一点,对于样本方差来说,假如从总体中只取一个样本,即n=1,那么样本方差公式的分子分母都为0,方差完全不确定。这个好理解,因为样本方差是用来估计总体中个体之间的变化大小,只拿到一个个体,当然完全看不出变化大小。反之,如果公式的分母不是n-1而是n,计算出的方差就是0——这是不合理的,因为不能只看到一个个体就断定总体的个体之间变化大小为0。

知乎 https://www.zhihu.com/question/20099757

补充:贝叶斯网络

时间: 2024-10-12 17:45:04

斯坦福公开课5:生成学习的相关文章

斯坦福公开课:Developing IOS 8 App with Swift(1-3)心得体会

最近开始学习Swift开发移动程序.跟随斯坦福大学的公开课进行自学. 这真是一个美好的时代,虽然不能在斯坦福求学,但是可以观看录制的授课录像.讲义,好似老师在给我们上课一样! 心得: 1.每节课信息量很大,每个词,每个操作都是有意而为之的.需要课后好好体会,针对课上讲的知识点多练习.多阅读才能有所体会并掌握要点. 2.英语不过关是短腿.这导致了要看字幕.老师的屏幕上输出的代码.老师鼠标操作.另外字幕中出现的不容易翻译的词语是直接输出的英文原文. 导致眼睛要上下左右到处看,很是狼狈.即便如此也经常

(笔记)斯坦福机器学习第五讲--生成学习算法

 本讲内容 1. Generative learning algorithms(生成学习算法) 2. GDA(高斯判别分析) 3. Naive Bayes(朴素贝叶斯) 4. Laplace Smoothing(拉普拉斯平滑) 1.生成学习算法与判别学习算法 判别学习算法:直接学习  或者学习一个假设  直接输出0或者1.logistic回归是判别学习算法的一个例子. 生成学习算法:对  建模,即在给定所属的类别的情况下,对特征出现的概率建模.出于技术上的考虑,也会对  建模.   根据贝叶斯公

【编译器】斯坦福公开课学习2

02-01 将会为教学用语言COOL编写编译器,把COOL编译成MIPS汇编语言.会分为五个部分讲解,首先是写一个COOL程序,程序本身会是一个解释器.之后是词法分析.语法分析.语义分析.代码生成.这些部分都是分离的.即在我们自己实现语法分析时,我们将自己完成的部分嵌入到一个参考编译器中.参考编译器中已经有其他的部分了.这便于对各个部分独立排除错误. 一些COOL代码示例,用于熟悉COOL语言. class Main{ main():Int {1}; }; class Main{ i : IO

iOS菜鸟成长笔记(3)——斯坦福公开课学习(1)

一.iOS四层结构 1.Core OS 是用FreeBSD和Mach所改写的Darwin, 是开源.符合POSIX标准的一个Unix核心.这一层包含或者说是提供了整个iPhone OS的一些基础功能,比如:硬件驱动, 内存管理,程序管理,线程管理(POSIX),文件系统,网络(BSD Socket),以及标准输入输出等等,所有这些功能都会通过C语言的API来提供.另外,值得一题的是,这一层最具有UNIX色彩,如果你需要把 UNIX上所开发的程序移植到iPhone上,多半都会使用到Core OS的

斯坦福公开课1:机器学习的动机与应用

什么是机器学习? 一个程序对于任务T,输入经验E,通过性能评测方法P衡量该程序在T的性能得到改进. 监督学习 Regression(举例:房屋价格与房屋面积的关系) Classification(举例 :根据年龄和肿瘤大小判断乳腺肿瘤是良性/恶性) 非监督学习 clustering(举例:鸡尾酒会问题) 强化学习 (举例:机器狗,好狗!坏狗!)

swift-计算器(斯坦福公开课)

看了斯坦福老头的课,真心觉得,我的中文怎么也变的这么垃圾了.是关于iOS8的课程,用swift写的,一个计算器应用的制作,看看人家的课,再看看咱们学校的课(不过垃圾学校,纯粹觉得大学浪费了),废话啊,废话,继续废话.那个老头的代码有些我给省略了,不知道会出现什么问题,反正我是没有发现,如果你发现了,请告诉我.还有就是这个计算器的具体操作步骤是,你先4-> 回车-> 5-> 回车 ->乘号 显示计算结果20 首先是界面的搭建,就是0-9一共10个按钮,然后加减乘除四个操作按键,以及,

斯坦福公开课4:牛顿方法

北京理工大学计算机专业2016级硕士在读,方向:Machine Learning,NLP,DM 本讲大纲: 1.牛顿方法(Newton's method) 2.指数族(Exponential family) 3.广义线性模型(Generalized linear models) 牛顿法 假设有函数:,我们希望找到满足的值. 这里是实数. 牛顿方法执行下面的更新: 具体原理可参考文章<Jacobian矩阵和Hessian矩阵> 下图为执行牛顿方法的过程:  简单的来说就是通过求当前点的导数得到下

斯坦福公开课:Statistical Learning中做错的选择题

4.4 R1 In which of the following problems is Case/Control Sampling LEAST likely to make a positive impact? A. Predicting a shopper's gender based on the products they buy B. Finding predictors for a certain type of cancer C. Predicting if an email is

关于ios8斯坦福公开课第二课

在这个课程中,我们遇到了这样的代码 @IBAction func oprate(sender: UIButton) { let opration = sender.currentTitle! if userIsOnInput { enter() } switch opration { case "+": performOperation{ $0+$1 } case "−": performOperation{ $1-$0 } case "×":