统计学习方法c++实现之八 EM算法与高斯混合模型

EM算法与高斯混合模型

前言

EM算法是一种用于含有隐变量的概率模型参数的极大似然估计的迭代算法。如果给定的概率模型的变量都是可观测变量,那么给定观测数据后,就可以根据极大似然估计来求出模型的参数,比如我们假设抛硬币的正面朝上的概率为p(相当于我们假设了概率模型),然后根据n次抛硬币的结果就可以估计出p的值,这种概率模型没有隐变量,而书中的三个硬币的问题(先抛A然后根据A的结果决定继续抛B还是C),这种问题中A的结果就是隐变量,我们只有最后一个硬币的结果,其中的隐变量无法观测,所以这种无法直接根据观测数据估计概率模型的参数,这时就需要对隐变量进行估计,进而得到概率模型的参数,这里要注意,概率模型是已知的(已经假定好了),包括隐变量的模型也是假设好的,只是具体的参数未知,这时候就需要用EM算法求解未知参数,这里我用EM算法估计了高斯混合模型的参数,并用高斯混合模型实现了聚类,代码地址

EM算法

EM算法中文名称是期望极大算法,EM是expectation maximization的缩写,从名字就可以窥视算法的核心,求期望,求极大。求谁的期望?求似然函数对隐变量的期望,所以,首先必须确定隐变量是什么。其次,对谁求极大?当然是求出概率模型的参数使得上一步的期望最大。算法如下:

输入:观测变量数据Y,隐变量数据Z(这里也是知道的?其实这里我的理解是,这里不是已知的,但是却是可以根据假设的隐变量的参数得到的),联合分布\(P(Y,Z|\theta)\), 条件分布\(P(Z|Y,\theta)\)

输出:模型参数\(\theta\)

  1. E步:记\(\theta^{(i)}\)为第i次迭代参数\(\theta\)的估计值,i+1次迭代的E步, 计算

    \(Q(\theta, \theta^{(i)})=E_Z[logP(Y,Z|\theta)|Y, \theta^{(i)}]=\sum_{Z}logP(Y,Z|\theta)P(Z|Y,\theta^{(i)})\)

  2. M步,求使\(Q(\theta, \theta^{(i)})\)极大的\(\theta\),作为下一次迭代的\(\theta^{(i+1)}\)
  3. 重复2,3直到收敛

可以看出最重要的在于求\(Q(\theta, \theta^{(i)})\),那么为什么每一次迭代最大化\(\sum_{Z}logP(Y,Z|\theta)P(Z|Y,\theta^{(i)})\)就能使观测数据的似然函数最大(这是我们的最终目的)?这里书上有证明,很详细,就不赘述了。先看一下我们要最大化的极大似然函数,然后这里主要引用西瓜书中的解释来从理解EM算法:

\(L(\theta)=logP(Y|\theta)=log(\sum_ZP(Y,Z|\theta))=log(\sum_ZP(Y|Z,\theta)P(Z|\theta))\)

在迭代过程中,若参数\(\theta\)已知,则可以根据训练数据推断出最优隐变量Z的值(E步);反之,若Z的值已知,则可以方便的对参数\(\theta\)做极大似然估计(M步)。

可以看出就是一种互相计算,一起提升的过程。

这部分如果推导看不懂了,可以结合下面的二维高斯混合模型的EM算法来理解。

c++实现

这里我使用EM算法来估计高斯混合模型的参数来进行聚类,高斯混合模型还有一个很大的作用是进行前景提取,这里仅仅用二维混合高斯模型进行聚类。

代码结构

关键代码

这里实现起来其实没什么难点,难点在于推导参数的更新公式,详情参考西瓜书p206。

void GMM::EMAlgorithm(vector<double> &alphaOld, vector<vector<vector<double>>> &sigmaOld,
        vector<vector<double>> &muOld) {
// compute gamma
    for (int i = 0; i < trainDataF.size(); ++i) {
        double probSum = 0;
        for (int l = 0; l < alpha.size(); ++l) {
            double gas = gaussian(muOld[l], sigmaOld[l], trainDataF[i]);
            probSum += alphaOld[l] * gas;
        }
        for (int k = 0; k < alpha.size(); ++k) {
            double gas = gaussian(muOld[k], sigmaOld[k], trainDataF[i]);
            gamma[i][k] = alphaOld[k] * gas / probSum;
        }
    }
// update mu, sigma, alpha
    for (int k = 0; k < alpha.size(); ++k) {
        vector<double> muNew;
        vector<vector<double>> sigmaNew;
        double alphaNew;
        vector<double> muNumerator;
        double sumGamma = 0.0;
        for (int i = 0; i < trainDataF.size(); ++i) {
            sumGamma += gamma[i][k];
            if (i==0) {
                muNumerator = gamma[i][k] * trainDataF[i];
            }
            else {
                muNumerator = muNumerator + gamma[i][k] * trainDataF[i];
            }
        }
        muNew = muNumerator / sumGamma;
        for (int i = 0; i < trainDataF.size(); ++i) {
            if (i==0) {
                auto temp1 = gamma[i][k]/ sumGamma * (trainDataF[i] - muNew);
                auto temp2 = trainDataF[i] - muNew;
                sigmaNew = vecMulVecToMat(temp1, temp2);
            }
            else {
                auto temp1 = gamma[i][k] / sumGamma * (trainDataF[i] - muNew);
                auto temp2 = trainDataF[i] - muNew;
                sigmaNew = sigmaNew + vecMulVecToMat(temp1, temp2);
            }
        }
        alphaNew = sumGamma / trainDataF.size();
        mu[k] = muNew;
        sigma[k] = sigmaNew;
        alpha[k] = alphaNew;
    }
}

总结

前面的代码一直用vector来实现向量,但是这里用到了矩阵,矩阵的相关计算都添加的计算函数。最正规的应该是写个类,实现矩阵运算,但是这里偷懒了,以后写代码一定要考虑周到,这样添添补补的太低效了。

原文地址:https://www.cnblogs.com/bobxxxl/p/10479468.html

时间: 2024-10-07 02:03:40

统计学习方法c++实现之八 EM算法与高斯混合模型的相关文章

EM算法求高斯混合模型参数估计——Python实现

EM算法一般表述: 当有部分数据缺失或者无法观察到时,EM算法提供了一个高效的迭代程序用来计算这些数据的最大似然估计.在每一步迭代分为两个步骤:期望(Expectation)步骤和最大化(Maximization)步骤,因此称为EM算法. 假设全部数据Z是由可观测到的样本X={X1, X2,--, Xn}和不可观测到的样本Z={Z1, Z2,--, Zn}组成的,则Y = X∪Z.EM算法通过搜寻使全部数据的似然函数Log(L(Z; h))的期望值最大来寻找极大似然估计,注意此处的h不是一个变量

EM算法 - 2 - EM算法在高斯混合模型学习中的应用

声明: 1,本篇为个人对<2012.李航.统计学习方法.pdf>的学习总结,不得用作商用,欢迎转载,但请注明出处(即:本帖地址). 2,由于本人在学习初始时有很多数学知识都已忘记,所以为了弄懂其中的内容查阅了很多资料,所以里面应该会有引用其他帖子的小部分内容,如果原作者看到可以私信我,我会将您的帖子的地址付到下面. 3,如果有内容错误或不准确欢迎大家指正. 4,如果能帮到你,那真是太好了. 在开始讲解之前,我要先给看这篇文章的你道个歉,因为<2012.李航.统计学习方法.pdf>中

机器学习第三课(EM算法和高斯混合模型)

EM算法,这是cv界比较有名的一种算法了,虽然很早就听说过,但真正深究还是最近几天看斯坦福公开课笔记的时候.之所以EM和MoG放在一起,是因为我们在求解MoG模型的时候需要用到EM算法,所以这里我们先来介绍下EM算法. 在介绍EM算法的之前,我们先来普及下Jensen不等式的知识.首先我们来给出Jensen不等式的定义: 定理很简单,总结下来就是这么几点.如果f是一个凸函数并且二阶导数大于零(上文中有提出),则有.进一步, 若二阶导数恒大于 0,则不等式等号成立当且仅当 x=E[x],即 x 是

R语言:EM算法和高斯混合模型的实现

原文 :http://tecdat.cn/?p=3433 本文我们讨论期望最大化理论,应用和评估基于期望最大化的聚类. 软件包 install.packages("mclust"); require(mclust) ## Loading required package: mclust ## Package 'mclust' version 5.1 ## Type 'citation("mclust")' for citing this R package in p

机器学习(十二、十三):K-means算法、高斯混合模型

简介: 本节介绍STANFORD机器学习公开课中的第12.13集视频中的算法:K-means算法.高斯混合模型(GMM).(9.10.11集不进行介绍,略过了哈) 一.K-means算法 属于无监督学习的聚类算法,给定一组未标定的数据(输入样本),对其进行分类,假设可分为k个类.由于算法比较直观,故直接给出步骤和MATLAB代码.(k-means算法在数学推导上是有意义的) MATLAB代码: %% %k均值聚类 clear all; close all; %% n=2; m=200; v0=r

统计学习方法 李航---第9章 EM算法及其推广

第9章 EM算法及其推广 EM算法是一种迭代算法,用于含有隐变量(hidden variable)的概率模型参数的极大似然估计,或极大后验概率估计.EM算法的每次迭代由两步组成:E步,求期望(expectation):M步,求极大( maximization ),所以这一算法称为期望极大算法(expectation maximization algorithm),简称EM算法. 9.1  EM算法的引入 一般地,用Y表示观测随机变量的数据,Z表示隐随机变量的数据.Y和Z连在一起称为完全数据( c

EM算法 - 1 - 介绍

声明: 1,本篇为个人对<2012.李航.统计学习方法.pdf>的学习总结,不得用作商用,欢迎转载,但请注明出处(即:本帖地址). 2,由于本人在学习初始时有很多数学知识都已忘记,所以为了弄懂其中的内容查阅了很多资料,所以里面应该会有引用其他帖子的小部分内容,如果原作者看到可以私信我,我会将您的帖子的地址付到下面. 3,如果有内容错误或不准确欢迎大家指正. 4,如果能帮到你,那真是太好了. 在开始之前需要准备些预备知识,如果你已经全部掌握那就直接向下翻到EM算法这一章吧. 极大似然估计 由于E

聚类之K均值聚类和EM算法

这篇博客整理K均值聚类的内容,包括: 1.K均值聚类的原理: 2.初始类中心的选择和类别数K的确定: 3.K均值聚类和EM算法.高斯混合模型的关系. 一.K均值聚类的原理 K均值聚类(K-means)是一种基于中心的聚类算法,通过迭代,将样本分到K个类中,使得每个样本与其所属类的中心或均值的距离之和最小. 1.定义损失函数 假设我们有一个数据集{x1, x2,..., xN},每个样本的特征维度是m维,我们的目标是将数据集划分为K个类别.假定K的值已经给定,那么第k个类别的中心定义为μk,k=1

实战EM算法与图像分割

EM 算法是求参数极大似然估计的一种方法,它可以从非完整数据集中对参数进行估计,是一种非常简单实用的学习算法.这种方法可以广泛地应用于处理缺损数据.截尾数据以及带有噪声等所谓的不完全数据,可以具体来说,我们可以利用EM算法来填充样本中的缺失数据.发现隐藏变量的值.估计HMM中的参数.估计有限混合分布中的参数以及可以进行无监督聚类等等. 贴相关几个好文章:从最大似然到EM算法浅解 混合高斯模型(Mixtures of Gaussians)和EM算法 斯坦福大学机器学习--EM算法求解高斯混合模型