目录
贝叶斯模型
1.判别模型与生成模型
2. 基于最小风险贝叶斯决策理论
3. 高斯判别分析模型(Gaussian Discriminant Analysis)
3.1 高斯判别分析(GDA)与LR的关系
4. 朴素贝叶斯模型(Gaussian Discriminant Analysis)
4.1 后验概率最大化的含义
4.2 学习与分类算法
4.3 拉普拉斯平滑
5. EM算法(Expectation-Maximization)期望最大化
5.1 极大似然估计
5.2 EM算法
5.3 例子说明
6. 实例
6.1 文本分类
6.2 测试算法:根据现实情况修改分类器
例子 |
|
判别模型 |
要确定一只羊是山羊还是绵羊,用判别模型的方法是: 先从历史数据中学习到模型,然后通过提取这只羊的特征来预测这只羊是山羊的概率和绵羊的概率(即条件概率P(y|x) |
生成模型 |
可根据山羊的特征,首先学习出一个山羊模型;然后根据绵羊的特征学习到绵羊模型。然后从某一直羊中提取特征,分别放到山羊模型和绵羊模型中,判断哪个模型输出的概率大,哪个概率大就是哪个类。 |
有监督学习的所有模型大体上可以划分为2大类 |
|
判别模型 |
主要是根据特征值求结果的概率,形式化P(y|x;w)(比如LR)。在参数w确定下,求解p(y|x)的概率。 |
生成模型 |
|
常见模型 |
|
判别模型 |
线性回归、对数回归、线性判别分析、SVM、Boosting、CRF、神经网络等 |
生成模型 |
HMM、NB、高斯混合模型、LDA(主题模型)、受限波尔斯曼及 |
参考资料:
多变量正态分布
ID |
X1 |
X2 |
Y |
1 |
1 |
S |
-1 |
2 |
1 |
M |
-1 |
3 |
1 |
M |
1 |
4 |
1 |
S |
1 |
5 |
1 |
S |
-1 |
6 |
2 |
S |
-1 |
7 |
2 |
M |
-1 |
8 |
2 |
M |
1 |
9 |
2 |
L |
1 |
10 |
2 |
L |
1 |
11 |
3 |
L |
1 |
12 |
3 |
M |
1 |
13 |
3 |
M |
1 |
14 |
3 |
L |
1 |
15 |
3 |
L |
-1 |
极大似然估计思想:已知某个参数能使这个样本出现的概率最大,我们当然不会再去选择其他小概率的样本,所以干脆就把这个参数作为估计的真实值。
求最大似然函数估计值的一般步骤:
(1)写出似然函数;
(2)对似然函数取对数,并整理;
(3)求导数,令导数为0,得到似然方程;
(4)解似然方程,得到的参数即为所求;
如果将200名学生混乱在一起,抽取到的每个样本都不知道是从哪个分布抽取的。
只有我们知道了哪些人属于同一个高斯模型的时候,才能对这个分布的参数作出靠谱的预测,但现在两种高斯分布混在一起了,我们不知道哪些人属于第一个高斯分布还是第二个高斯分布,所以就没有办法估计这两个分布的参数。反过来,只有我们对这两个高斯分布的参数作出准确的估计的时候,才能知道哪些人属于第一个分布,哪些人属于第二个分布。
这就造成“先有鸡还是先有蛋”的问题。
初始化男生女生的正态分布参数:均值和方差; Expectation step: 计算出每个样本可能属于哪一个分布,男生分布A,女生分布B; Maximization step: 根据最大似然估计重新得到正太分布的均值和方差; 根据重新得到的均值和方差,再进行E步操作,入如此反复,直到参数基本不变化为止。 |
假设现在有两枚硬币1和2,,随机抛掷后正面朝上概率分别为P1,P2。为了估计这两个概率,做实验,每次取一枚硬币,连掷5下,记录下结果,如下:
硬币 |
结果 |
统计 |
1 |
正正反正反 |
3正-2反 |
2 |
反反正正反 |
2正-3反 |
1 |
正反反反反 |
1正-4反 |
2 |
正反反正正 |
3正-2反 |
1 |
反正正反反 |
2正-3反 |
可以很容易地估计出P1和P2,如下:
P1 = (3+1+2)/ 15 = 0.4
P2= (2+3)/10 = 0.5
如果不知道哪个硬币抛的。求P1和P2
轮 |
硬币 |
结果 |
统计 |
1 |
Unknown |
正正反正反 |
3正-2反 |
2 |
Unknown |
反反正正反 |
2正-3反 |
3 |
Unknown |
正反反反反 |
1正-4反 |
4 |
Unknown |
正反反正正 |
3正-2反 |
5 |
Unknown |
反正正反反 |
2正-3反 |
如果用EM算法来估计的,步骤如下:
首先随机初始化P1和P2,如P1=0.2,P2=0.7 1st轮: if Unknown==硬币1: p1=0.2*0.2*0.2*0.8*0.8=0.00512 if Unknown==硬币2: p2=0.7*0.7*0.7*0.3*0.3=0.03087 if p2>p1: 硬币可能为硬币2 else: 硬币可能为硬币1 2nd轮: if Unknown==硬币1: p1=0.2*0.2*0.8*0.8*0.8=0.02048 if Unknown==硬币2: p2=0.7*0.7*0.3*0.3*0.3=0.01323 if p2>p1: 硬币可能为硬币2 else: 硬币可能为硬币1 同理…计算得到的结果如下表 |
轮数 |
若是硬币1 |
若是硬币2 |
最有可能是 |
1 |
0.00512 |
0.03087 |
硬币2 |
2 |
0.02048 |
0.01323 |
硬币1 |
3 |
0.08192 |
0.00567 |
硬币1 |
4 |
0.00512 |
0.03087 |
硬币2 |
5 |
0.02048 |
0.01323 |
硬币1 |
P1 = (2+1+2)/ 15 = 0.333
P2= (3+3)/10 = 0.6
可以期待,按照上面的思路,用估计出的p1和p2再来估计为哪个硬币,反复迭代下去,最终得到p1=0.4,p2=0.5 |
进阶版
用最大似然概率估计出的z值,然后再用z值按照最大似然概率法则估计出P1和P2。如果考虑所有的z值,对每一个z都估计出一个新的p1和p2,将每一个z值概率大小作为权重,将所有新的p1和p2分别加权相加,这样的p1和p2应该会更好一些。
轮数 |
若是硬币1 |
若是硬币2 |
1 |
0.00512 |
0.03087 |
2 |
0.02048 |
0.01323 |
3 |
0.08192 |
0.00567 |
4 |
0.00512 |
0.03087 |
5 |
0.02048 |
0.01323 |
利用上面这个表,我们可以计算出每轮的使用的硬币的概率。如:第一轮使用硬币1的概率为:0.00512/(0.00512+0.03087)=0.14
那么使用硬币2的概率为:1-0.14=0.86;
依次可计算出其他4轮的概率如下:
轮数 |
z_i=硬币1 |
z_i=硬币2 |
1 |
0.14 |
0.86 |
2 |
0.61 |
0.39 |
3 |
0.94 |
0.06 |
4 |
0.14 |
0.86 |
5 |
0.61 |
0.39 |
得到p1、p2的值,再进行极大似然估计,反复迭代,直到p1=0.4,p2=0.5
分类:
if p1(x,y)>p2(x,y),属于类别1
if p1(x,y)<p2(x,y),属于类别2
如何计算概率值呢? p(ci|x,y)=p(x,y|ci)p(ci)p(x,y)
即在(x,y)的条件下属于类别ci的概率值
背景:构建一快速过滤器,判断留言板是否使用了负面或者侮辱性的语言
Step 1: 创建字典作为特征
将每一篇文档转换为词汇表上的向量
# 词表到向量的转换函数
def loadDataSet():
postingList = [['my','dog','has','flea','problems','help','please'],
['maybe','not','take','him','to','dog','park','stupid'],
['my','dalmation','is','so','cute','I','love','him'],
['stop','posting','stupid','worthless','garbage'],
['mr','licks','ate','my','steak','how','to','stop','him'],
['quit','buying','worthless','dog','food','stupid']]
classVec = [0,1,0,1,0,1] # 1代表侮辱性文字,0代表正常言论
return postingList, classVec
'''创建一个包含在所有文档中出现的不重复词的列表'''
def createVocabList(dataSet):
vocabSet=set([])
"""set 集合,无序不重复元素集,基本功能包括关系测试和消除重复元素,支持&,|,-,交集并集差集
set()可以去掉重复的元素
"""
for document in dataSet:
vocabSet=vocabSet|set(document)
return list(vocabSet)
'''输入词汇表和某个文档,生成词汇向量'''
def setOfWords2Vec(vocabList,inputSet):
returnVec = [0]*len(vocabList)
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)] = 1
else: print('the word: %s is not in my Vocabulary!') % word
return returnVec
Step 2: 训练算法,从词向量计算概率
p(w0,w1,w2...wN)|Ci)=p(w0|Ci)p(w1|Ci)...p(wN|Ci)
伪代码:
计算每个类别中的文档数据:
对每篇训练文档:
对每个类别:
如果词条出现文档中–>增加该词条计数
增加所有词条计数值
对每个类别:
对每个词条:
将该词条的数目除以总词条数目得到条件概率
返回每个类别的条件概率
'''输入文档矩阵和类别标签向量'''
def trainNB0(trainMatrix,trainCategory):
"""
trainMatrix: 文档矩阵
trainCategory:每篇文档类别标签所构成的向量
"""
numtrainDocs=len(trainMatrix)#多少个文档
pAbusive=sum(trainCategory)/float(numtrainDocs)[1] #p(C=1)
numWords=len(trainMatrix[0])#每个文档中包含多少个单词
p0Num=np.zeros(numWords)
p1Num=np.zeros(numWords)
p0Denom=0.0
p1Denom=0.0
for i in range(numtrainDocs):
if trainCategory[i]==1:
p1Num+=trainMatrix[i]
p1Denom+=sum(trainMatrix[i])
else:
p0Num+=trainMatrix[i]
p0Denom+=sum(trainMatrix[i])
p1Vec=p1Num/p1Denom[2] #每个字条的p(wi|c1)
p0Vec=p0Num/p0Denom#每个字条的p(wi|c0)
return p1Vec,p0Vec,pAbusive
Step 3: 测试算法: 朴素贝叶斯分类函数
运行结果:
['love', 'my', 'dalmation'] classified as: 0
['stupid', 'garbage'] classified as: 1