高斯混合模型聚类_GMM: Gaussian Mixed Model(高斯混合模型)

f8fab5b28ee6c499e40ec477dd2f8b0b.png

0. 简介

GMM和Kmeans一样也属于聚类,其算法训练流程也十分相似,Kmeans可认为是“硬聚类”,GMM是“软聚类”。

给定数据集X,Kmeans算法流程是这样的----- a 初始化:随机初始k个中心(即k个点,记为μ);b 矫正数据归属:计算X中每个点与k个中心的距离,并将其归为相距最近的那个中心;c 矫正中心:计算每个中心(共k个)所有点的均值,并将其更新为中心值;d 完成整体训练:循环b和c,直到聚类到“足够好”。

GMM算法流程和Kmeans基本一致,区别在于:a 除了初始化k个中心(μ)外,每个中心还对应一个协方差矩阵(Σ)和混合概率(π),其中μ代表高斯分布的中心,Σ代表高斯分布形状,π代表高斯函数值的大小;b 矫正数据归属,GMM中每个数据点并不完全归属某个中心,而是归属每个中心,只是归属的概率不同;c 矫正中心,每个中心矫正更新时考虑数据集X中的所有点,而非某一部分数据点。

以下使用鸢尾花数据集按照a~d的流程解析GMM;导入鸢尾花数据集如下;

from sklearn import datasets
import numpy as npiris = datasets.load_iris()
X = iris.data
N, D = X.shape
display(X.shape, X[:10])
(150, 4)
array([[5.1, 3.5, 1.4, 0.2],[4.9, 3. , 1.4, 0.2],[4.7, 3.2, 1.3, 0.2],[4.6, 3.1, 1.5, 0.2],[5. , 3.6, 1.4, 0.2],[5.4, 3.9, 1.7, 0.4],[4.6, 3.4, 1.4, 0.3],[5. , 3.4, 1.5, 0.2],[4.4, 2.9, 1.4, 0.2],[4.9, 3.1, 1.5, 0.1]])

即鸢尾花数据集是一个150行4列的矩阵。

1. 初始化

定义聚类数量为3类,每一类都初始化一个中心μ、一个协方差矩阵Σ和混合概率π;

mus = X[np.random.choice(X.shape[0], 3, replace=False)]
covs = [np.identity(4) for i in range(3)]
pis = [1/3] * 3

2. 矫正数据归属

普通高斯概率函数(只有一个中心)如下,其中D是数据维度,此处D=4;

8b16413e3bf5c4ebbe49c7338f9ce045.png

表示数据点x归属该中心(μ、Σ)的概率,代码如下;

def gaussian(X, mu, cov):diff = X - mureturn 1 / ((2 * np.pi) ** (D / 2) * np.linalg.det(cov) ** 0.5) * np.exp(-0.5 * np.dot(np.dot(diff, np.linalg.inv(cov)), diff))

当用混合高斯函数(即多个中心)时,表示一个数据点n归属中心k(μ_k、Σ_k)的概率函数如下,其中k表示第k个中心,此处总共有3个中心,即K=3;

46013bb7af61e7c82fdd0c48fea9b30d.png

将上式定义为γ_z_nk,即

63a9557207419aa7317e812918e540a6.png

代码如下:

gammas = []
for mu_, cov_, pi_ in zip(mus, covs, pis):# loop each centergamma_ = [[pi_ * gaussian(x_, mu_, cov_)] for x_ in X]# loop each pointgammas.append(gamma_)
gammas = np.array(gammas)
gamma_total = gammas.sum(0)
gammas /= gamma_total

3. 矫正中心

根据2.中的gammas值,更新μ、Σ和π值,公式如下,其中N表示数据总个数,此处N=150;

940019de9ea9dffba038214d6e9e9b6d.png

f025a8e54918cedceea2f72230e8f206.png

1410c0537bf54c4b426f1b08705be407.png

代码如下;

mus, covs, pis = [], [], []
for gamma_ in gammas:#loop each centergamma_sum = gamma_.sum()pi_ = gamma_sum / Nmu_ = (gamma_ * X).sum(0) / gamma_sumcov_ = []for x_, gamma_i in zip(X, gamma_):diff = (x_ - mu_).reshape(-1, 1)cov_.append(gamma_i * np.dot(diff, diff.T))cov_ = np.sum(cov_, axis=0) / gamma_sumpis.append(pi_)mus.append(mu_)covs.append(cov_)

4. 完成整体训练

将2.~3.作为一个循环单元,写成一个函数;

def train_step(X, mus, covs, pis):gammas = []for mu_, cov_, pi_ in zip(mus, covs, pis):# loop each centergamma_ = [[pi_ * gaussian(x_, mu_, cov_)] for x_ in X]# loop each pointgammas.append(gamma_)gammas = np.array(gammas)gamma_total = gammas.sum(0)gammas /= gamma_totalmus, covs, pis = [], [], []for gamma_ in gammas:#loop each centergamma_sum = gamma_.sum()pi_ = gamma_sum / Nmu_ = (gamma_ * X).sum(0) / gamma_sumcov_ = []for x_, gamma_i in zip(X, gamma_):diff = (x_ - mu_).reshape(-1, 1)cov_.append(gamma_i * np.dot(diff, diff.T))cov_ = np.sum(cov_, axis=0) / gamma_sumpis.append(pi_)mus.append(mu_)covs.append(cov_)return mus, covs, pis

训练50次;

for _ in range(50):mus, covs, pis = train_step(X, mus, covs, pis)

训练完成后,会得到3个中心,可计算每个点归属这三个中心的概率(即γ_z_nk,第n个点归属第k个中心的概率),并将其归属于概率最大的那个中心;因为数据集是4维,无法可视化,仅选择前两维度进行可视化展示如下;

21eb407d0bdaacd29ee035c03d0e7bcd.png

整个训练过程的动态图如下;

072cb1d212363422ef3076c5a10578a1.gif

完整代码如下;

from sklearn import datasets
import numpy as np
import matplotlib.pyplot as pltiris = datasets.load_iris()
X = iris.data
N, D = X.shapemus = X[np.random.choice(X.shape[0], 3, replace=False)]
covs = [np.identity(4) for i in range(3)]
pis = [1/3] * 3def gaussian(X, mu, cov):diff = X - mureturn 1 / ((2 * np.pi) ** (D / 2) * np.linalg.det(cov) ** 0.5) * np.exp(-0.5 * np.dot(np.dot(diff, np.linalg.inv(cov)), diff))def get_likelihood(gamma_total):return np.log(gamma_total).sum()def train_step(X, mus, covs, pis):gammas = []for mu_, cov_, pi_ in zip(mus, covs, pis):# loop each centergamma_ = [[pi_ * gaussian(x_, mu_, cov_)] for x_ in X]# loop each pointgammas.append(gamma_)gammas = np.array(gammas)gamma_total = gammas.sum(0)gammas /= gamma_totalmus, covs, pis = [], [], []for gamma_ in gammas:#loop each centergamma_sum = gamma_.sum()pi_ = gamma_sum / Nmu_ = (gamma_ * X).sum(0) / gamma_sumcov_ = []for x_, gamma_i in zip(X, gamma_):diff = (x_ - mu_).reshape(-1, 1)cov_.append(gamma_i * np.dot(diff, diff.T))cov_ = np.sum(cov_, axis=0) / gamma_sumpis.append(pi_)mus.append(mu_)covs.append(cov_)return mus, covs, pis, gamma_totallog_LL = []
for _ in range(50):mus, covs, pis, gamma_total = train_step(X, mus, covs, pis)log_LL.append(get_likelihood(gamma_total))
plt.plot(log_LL)
plt.grid()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/410481.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[html] 对于rtl网站的适配有哪些方案?

[html] 对于rtl网站的适配有哪些方案? transform: scaleX(-1) 或 direction: ltr;个人简介 我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易, 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

测试sql语句的执行效率

测试数据库查询语句的执行效率declare d datetimeset dgetdate()select * from ordersselect [语句执行花费时间(毫秒)]datediff(ms,d,getdate())转载于:https://www.cnblogs.com/wangxiang/articles/777082.html

POJ 3621 Sightseeing Cows

http://poj.org/problem?id3621 这两天一直在复习代码,因为好久都不写东西了,而且转了语言,除了Dinic我什么都不会写…… 题目大意:给你一个有向图,边有权(T),点有权(F&…

LetCode-算法-整数反转

首先此题是要整数反转123就要翻转成321 ,23就是32 我们首先发现其中的规律 321 3X1022X1013X100 123反转成321 就是(123%10)X102(12%10)X102(1%10)X102 得出规律后我们就可以通过此规律写出方法了 如下: public class Solution {public int Reverse(int x) {int …

[html] 如何通过表单下载文件?

[html] 如何通过表单下载文件? form 表单的action设置为接口地址,设置method为post/getpost方法:根据需要传递的参数设置多个input:namekey, valuevalue如果请求的接口不需要参数,建议设置一个input,否则可能会引起报错。submit提…

怎样下载安装python_Windows系统上如何安装Python和pip

系统环境: Windows 7 Pyhton 2.7.12 pip-8.1.2 1、下载安装包 python2.7.12安装包下载地址:pip安装包下载地址:2、安装Python a、双击下载后的安装包,一直点下一步即可。 b、配置Python的环境变量,操作如下&#xff1a…

ast.literal_eval(转)

eval函数在Python中做数据类型的转换还是很有用的。它的作用就是把数据还原成它本身或者是能够转化成的数据类型。那么eval和ast.literal_val()的区别是什么呢?本文将大家介绍关于Python中函数eval和ast.literal_eval区别的相关资料,需要的朋友可以参考下…

高德地图-2D地图下区域遮掩(只显示固定区域里的内容)

最近遇到一个新的需求需用用到高德地图 公司需要只显示固定区域范围的地图,其余地方的地图都用透明遮罩覆盖 完成后如下图所示: 地图体验网址 刚开始的时候研究了半天高德地图的的JS API中只有一个区域遮掩符合条件 但是区域遮掩这个代码有一个很重要的前提是必须使用3D地图&…

数据结构之数组模拟栈

栈的特点即先进后出,采用数组模拟栈,实现栈的这一特性主要是靠定义一个指针(索引). 指针的初始位置指向的是-1 以下给出代码: package com.ebiz.stack;/*** author YHj* create 2019-07-20 14:20* 数组模拟栈*/public class ArrayStack {private int maxSize;private int [] …

C# 淘宝商品微信返利助手开发-(八)微信号对接

系列教程一目录:返利助手原理 系列教程二目录:返利助手开放文档以及帐号申请地址 系列教程三目录:返利助手开发(1)API介绍 系列教程四目录:返利助手开发(2)淘宝分享的内容如何只取…

C# 制作不规则窗体的两种解决方案

我的广告单元,有空点一下哦,谢谢! 冒着被拍砖的危险,投放到首页。C#制作不规则窗体应该又是一个老生常谈的问题了,可能很多老鸟会带BS的眼神,那么请老鸟们视该文章如浮云吧。 制作不规则窗体,本…

新概念英语第二册课文电子版_新概念英语第二册课文学生(Victoria)朗读

点击上"蓝字"关注我们专栏介绍【悦读时刻】是我们为中小学生在英语、语文朗读中的佼佼者开辟的专栏。我们会在优秀朗诵内容中进行优选之后上传发布。外研社新概念英语 II编者:何其莘 &L.G. AlexanderLONGMAN2简 介《新概念英语》(New Concept Engl…

HubbleDotNet使用备忘

Word格式下载转载于:https://www.cnblogs.com/wdfrog/archive/2011/07/30/2121817.html

C# 淘宝商品微信返利助手开发-(九)编写一个vue页面用于复制淘口令

系列教程一目录:返利助手原理 系列教程二目录:返利助手开放文档以及帐号申请地址 系列教程三目录:返利助手开发(1)API介绍 系列教程四目录:返利助手开发(2)淘宝分享的内容如何只取…

数据结构之中缀表达式实现计算器

栈还是用的上一篇的数组模拟栈,并在此之上增加了 判断是否是一个运算符的方法 获取运算符的优先级方法 计算结果方法 查看栈顶元素的方法 四个方法,具体代码如下: package com.ebiz.stack;/*** author YHj* create 2019-07-20 14:20* 数组模拟栈*/public class ArrayStack {pri…

python color属性_使用Python制作一个带GUI界面的词云自动生成工具(连载七)

前几篇向大家介绍了词云自动生成工具(GUI)的详解GUI词云自动生成工具中词云属性设置界面的实现(连载六)。通过前面内容我们基本构建出了词云自动生成工具的主要框架。本篇结合tkinter中的filedialog和colorchooser的使用&#xff…

com 名字对象(3)使用IMoniker

一.名字对象比较 Hash和IsEqual方法 IMoniker* moniker2NULL; CreateFileMoniker(OLESTR("F:\\test.xlsx"),&moniker2); DWORD dw; moniker2->Hash(&dw); IMoniker* moniker3NULL; CreateFileMoniker(OLESTR("F:\\test2.xlsx"),&moniker3);…

python爬取微博评论_用 python 爬取微博评论并手动分词制作词云

最近上海好像有举行个什么维吾尔族的秘密时装秀,很好看的样子,不过我还没时间看。但是微博上已经吵翻了天,原因是好吧,这不是我们关心的,我的心里只有学习我爱学习 Python 爬虫 本次爬取的是这条微博这条微博 微博的移…

公众号出现该公众号提供的服务出现故障分析

近日公众号出现了 出现该公众号提供的服务出现故障的错误提示 百度了一下这种错误的可能性 在这里插入图片描述 1. 程序后台未回复微信success 2. 5秒内无响应 3. 授权给了多个第三方平台,其中一个不可用。 4. ToUserName和 FromUserName 参数不正确无法找到接收…

数据结构之栈对逆BoLand表达式的计算

一. 后缀表达式: 后缀表达式,逆波兰表达式,是指运算符位于操作符之后,计算机对该式是从做到右进行计算,计算过程如下例子 二.计算思路 对于后缀表达式的计算,需要一个栈即可, 即遇见数字压栈,遇见运算符从栈中取出两个数,根据运算进行操作, 需要注意的是,减法以及除法都是后出栈…