最近较忙,代码先码一下,后续再更新仔细讲解

Eigen是个第三方包,自己找个教程安装一下,里面的计算是根据高斯混合模型的公式推导结果写的,终止条件那里可以自己改,目前只是用次数控制的。

1.gmm.h

#include <Eigen/Dense>
using namespace Eigen;
void GMM_EM(MatrixXd Y, int K, int times, double thre);

2.gmm.cpp

#include "gmm.h"
#include <opencv2/opencv.hpp>
#define _USE_MATH_DEFINES
#include <math.h>
#include <vector>
#include <Eigen/Dense>
#include <random>
using namespace cv;
using namespace std;
using namespace Eigen;class GmmParam {MatrixXd mu;Matrix<MatrixXd, Dynamic, Dynamic> cov;VectorXd alpha;//函数  给属性赋值
public:void init(MatrixXd mu1, Matrix<MatrixXd, Dynamic, Dynamic> cov1, VectorXd alpha1) {mu = mu1;cov = cov1;alpha = alpha1;}MatrixXd getMu() {return mu;}Matrix<MatrixXd, Dynamic, Dynamic> getCov() {return cov;}VectorXd getAlpha() {return alpha;}
};
/**
* pdf标量公式:f(X)=1/(δ(2Π)^1/2)exp(-0.5((x-mu)^2/δ^2))
* pdf多维向量公式:f(X)=1/(((2Π)^k*|cov|)^1/2)exp(-0.5((x-mu)'*cov*(x-mu)))
* mu_k是D*1(因为pdf的推导公式是列向量,所以这里得传列向量)
* cov_k是D*D
* Y_j是D*1(为了和mu_k对应)
**/
double phi(MatrixXd mu_k, MatrixXd cov_k, MatrixXd Y_j) {int D = mu_k.rows();//数据维度auto dev = Y_j - mu_k;/*cout << "dev:\n" << dev << endl << endl;cout << "dev:\n" << cov_k << endl << endl;cout << "dev:\n" << cov_k.inverse() << endl << endl;*/auto maha = dev.transpose()*cov_k.inverse()*dev;/*cout << "maha:\n" << maha << endl << endl;cout << "maha00:\n" << maha(0, 0) << endl << endl;*/double a = exp(-0.5*maha(0, 0));double b = cov_k.determinant();double result = 1 / (sqrt(pow(2 * M_PI, D)*b))*a;return result;
}//mu是K*D,cov是K*D*D(外层是一行K列,每1行1列是个D*D的矩阵),Y是N*D
MatrixXd E_step(MatrixXd Y, MatrixXd mu, Matrix<MatrixXd, Dynamic, Dynamic> cov, VectorXd alpha) {int N = Y.rows();//样本数int D = Y.cols();//数据维度int K = alpha.size();//类别MatrixXd gamma(N, K);vector<double> gammaSum(N, 0);for (int j = 0; j < N; j++) {for (int k = 0; k < K; k++){gamma(j, k) = alpha[k] * phi(mu.row(k).transpose(), cov(0, k), Y.row(j).transpose());gammaSum[j] = gammaSum[j] + gamma(j, k);}}for (int j = 0; j < N; j++) {gamma.row(j) = gamma.row(j) / gammaSum[j];}cout << "gamma:\n" << gamma << endl << endl;return gamma;
}//mu是K*D,cov是K*D*D(外层是一行K列,每1行1列是个D*D的矩阵),Y是N*D,gamma是N*K
GmmParam M_step(MatrixXd Y, MatrixXd gamma, MatrixXd mu, Matrix<MatrixXd, Dynamic, Dynamic> cov, VectorXd alpha) {int K = gamma.cols();//类别int N = Y.rows();//样本数int D = Y.cols();//维度VectorXd Nk = gamma.colwise().sum();//记录属于这个component的样本的响应度和MatrixXd Y_gamma(Y.rows(), Y.cols());//记录每个component对每个值的贡献程度for (int k = 0; k < K; k++) {//gamma作为系数和Y相乘,而不是点乘for (int j = 0; j < N; j++) {Y_gamma.row(j) = gamma(j, k)*Y.row(j);//通过Y和响应度系数相乘计算预测出来的贡献程度}alpha[k] = Nk[k] / N;mu.row(k) = Y_gamma.colwise().sum() / Nk[k];}MatrixXd cov_gamma(N, D);//记录预测出来的观测值MatrixXd dev(N, D);for (int k = 0; k < K; k++) {//gamma作为系数和Y相乘,而不是点乘for (int j = 0; j < N; j++) {dev.row(j) = Y.row(j) - mu.row(k);cov_gamma.row(j) = gamma(j, k)*dev.row(j);//通过Y和响应度系数相乘计算预测出来的观测值}cov(0, k) = dev.transpose()*cov_gamma / Nk[k];//D*D}GmmParam gmmParam;gmmParam.init(mu, cov, alpha);return gmmParam;
}void GMM_EM(MatrixXd Y, int K, int times, double thre) {int N = Y.rows();//样本数int D = Y.cols();//数据维度//初始化均值、协方差、权重系数MatrixXd mu = MatrixXd::Random(K, D);/*MatrixXd mu(K, D);mu << 0.04937, 0.73136,0.69989, 0.05192;*/cout << "mu:\n" << mu << endl << endl;Matrix<MatrixXd, Dynamic, Dynamic> cov;cov.resize(1, K);for (int i = 0; i < K; i++) {MatrixXd cov_k = MatrixXd::Identity(D, D);cov(0, i) = cov_k;}VectorXd alpha = VectorXd::Ones(K) * (1.0 / K);cout << "alpha:\n" << alpha << endl << endl;for (int i = 0; i < times; i++) {MatrixXd gamma = E_step(Y, mu, cov, alpha);//用这个的delta*delta'来控制终止条件(或者mu/cov/alpha)GmmParam gmmParam = M_step(Y, gamma, mu, cov, alpha);mu = gmmParam.getMu();alpha = gmmParam.getAlpha();cov = gmmParam.getCov();cout << "cov:\n" << cov(0, 0) << endl << endl;}cout << "mu:\n" << mu << endl << endl;cout << "alpha:\n" << alpha << endl << endl;
}

3.main.cpp---------这里的测试数据不想折腾了,直接用python生成的随机数copy过来的,K是类别数(GMM组件数),40是迭代次数,thre是控制终止条件的阈值(目前没有用,可自行修改)。

#include <opencv2/opencv.hpp>
#include "gmm.h"
using namespace Eigen;
using namespace cv;
using namespace std;int main() {MatrixXd Y(40,2);Y << 0.90399, 1.75717,1.90245, 0.90256,1.05317, 1.89239,2.20109, 1.95815,-0.70211, 1.47465,0.83586, 1.20565,1.36202, 1.48171,-0.38448, 0.37853,-1.15287, 2.19155,-0.94483, 1.07071,-0.35403, 0.72768,0.38726, 1.16318,-1.09941, 0.97615,-0.52283, 0.68882,-0.39215, 0.35754,0.29295, 0.39324,0.02062, 0.95334,0.49576, 1.58207,2.10293, 0.95540,-0.54234, 1.96534,3.19150, 4.56735,1.00127, 3.94349,1.33137, 4.29915,3.22761, 3.65609,1.32311, 4.71277,3.07591, 4.57711,2.09273, 3.07348,1.44289, 4.22786,2.71425, 4.85522,2.25975, 7.12721,2.36885, 5.64459,1.87930, 4.80476,1.81077, 7.25826,2.93794, 4.60977,1.72519, 3.75386,1.84943, 5.28985,2.65972, 4.54997,2.81061, 5.15333,0.91457, 6.11026,2.23573, 3.90546;double thre = 0.1;int K = 2;GMM_EM(Y,K,40, thre);
}

高斯混合模型(GMM),c++实现相关推荐

  1. 高斯混合模型GMM、核心参数、高斯混合模型GMM的数学形式

    高斯混合模型GMM.核心参数.高斯混合模型GMM的数学形式 高斯混合模型GMM 混合模型是一个可以用来表示在总体分布(distribution)中含有 K 个子分布的概率模型,换句话说,混合模型表示了 ...

  2. 高斯混合模型--GMM(Gaussian Mixture Model)

    参考:http://blog.sina.com.cn/s/blog_54d460e40101ec00.html 概率指事件随机发生的机率,对于均匀分布函数,概率密度等于一段区间(事件的取值范围)的概率 ...

  3. 高斯混合模型--GMM

    原文:http://blog.sina.com.cn/s/blog_54d460e40101ec00.html   高斯混合模型--GMM(Gaussian Mixture Model)     统计 ...

  4. 单高斯分布模型GSM,高斯混合模型GMM

    本文就高斯混合模型(GMM,Gaussian Mixture Model)参数如何确立这个问题,详细讲解期望最大化(EM,Expectation Maximization)算法的实施过程. 单高斯分布 ...

  5. EM算法应用:k均值聚类(k-means)和高斯混合模型(GMM)

    文章目录 k-means聚类 EM角度的理解 算法流程 特点 k值选择 局限性 高斯混合模型 GMM的问题描述 1,明确隐变量 2.EM算法的E步:确定Q函数 3. EM算法的E步 4. 停止条件 上 ...

  6. 高斯混合模型GMM的理解

    高斯混合模型(Gaussian Mixture Model,简称GMM)是用高斯概率密度函数(正态分布曲线)精确地量化事物,将一个事物分解为若干的基于高斯概率密度函数(正态分布曲线)形成的模型.通俗点 ...

  7. 混合高斯模型_大数据小白入门高斯混合模型(GMM)聚类算法

    导读 高斯混合模型(Gaussian Mixture Model)通常简称GMM,是一种业界广泛使用的聚类算法,属于生成式模型,它假设所有的数据样本都是由某一个给定参数的 多元高斯分布 所生成的.从中 ...

  8. 使用高斯混合模型(GMM)近似未知分布:EM算法的应用

    该篇博客是对邱锡鹏老师<神经网络与深度学习>的学习笔记.在阅读本博文之前,建议读者先阅读上一篇博客EM算法. 高斯混合模型(Gaussian Mixture Model) 如果一个连续随机 ...

  9. EM算法及高斯混合模型GMM详述

    1.最大似然估计 最大似然估计(Maximum Likelihood Estimation,MLE)就是利用已知的样本结果,反推最有可能(最大概率)导致这样结果的参数值的计算过程.直白来讲,就是给定了 ...

  10. 高斯混合模型 GMM 的详细解释

    高斯混合模型(后面本文中将使用他的缩写 GMM)听起来很复杂,其实他的工作原理和 KMeans 非常相似,你甚至可以认为它是 KMeans 的概率版本. 这种概率特征使 GMM 可以应用于 KMean ...

最新文章

  1. IF、如果、Rudyard Kipling
  2. DirectionalLayout线性布局
  3. boost::geometry::srs::projection用法的测试程序
  4. html中input不可编辑状态,css如何实现input不可编辑
  5. MaxCompute JOIN优化小结
  6. mfc编程 孙鑫_孙鑫VC++视频教程笔记-(3)MFC程序框架的剖析 附1-SDI程序流程图
  7. 07-windows下Elasticsearch安装-elasticsearch-service服务
  8. Spine 动画工具
  9. java 图片特效_强大的Java图像滤镜特效类库Java Image Filters
  10. linux内核 header.s,arm架构的linux内核中,clrex指令的作用是什么
  11. VC之fseek函数、ftell函数和rewind函数
  12. 计算机网络工程师中级软考试题及答案,软考中级历年真题+章节题库
  13. shell脚本for循环的基础格式以及取值列表的多种取值方式
  14. 不再当码农-Flash AS3.0多个影片剪辑实现同一功能循环问题
  15. 不讲废话,全程硬核,处理结构化数据的终极解决方案
  16. PTA 7-3 查询水果价格 (15 分)
  17. google浏览器打开出现“喔唷,崩溃啦”解决办法
  18. python替换列表中元素_python中关于元素替换的一些总结
  19. 安装oaj2se出现问题
  20. pandas数据分析模块(二)

热门文章

  1. js 获取到number的length
  2. 量化交易策略代码java_3.量化交易策略基本框架
  3. 大数据常用web页面
  4. python解一元一次方程标准形式_一元一次方程的标准形式的概念以及解法
  5. 程序员都知道的二维码扫码登录的底层原理
  6. linux如何伪装ip,如何伪装你的IP(二)
  7. 黑客攻防技术宝典(六)
  8. 虚拟机SSH免密登录配置
  9. python词云词频分析_Python词云(词频统计,掩膜显示)
  10. 推荐系统(十六)多任务学习:腾讯PLE模型(Progressive Layered Extraction model)