多变量混合高斯模型绘图问题

using Distributions
import Plots
gmm = MixtureModel(
    Normal.([-1.0, 0.0, 3.0], # mean vector
    [0.3, 0.5, 1.0]), # std vector
    [0.25, 0.25, 0.5] # component weights
)
# xs = -2.0:0.01:6.0
# Plots.plot(xs, pdf.(gmm, xs))
Plots.plot(gmm)

这个代码是没问题的

using Distributions
import Plots

a = MvNormal([0,0.5], [0.2, 0.6])
b = MvNormal([0.5,0.5], [0.4, 1])
c = MixtureModel(MvNormal[a,b], [0.2, 0.8])

Plots.plot(c)

MethodError: no method matching iterate(::MvNormal{Float64,PDMats.PDiagMat{Float64,Array{Float64,1}},Array{Float64,1}})

plot 好像不支持多变量混合模型, 求助解决方案

暂时找到的方案是,

using PyCall
using Distributions
import Plots

@pyimport numpy as np

a = MvNormal([0,0.5], [0.2, 0.6])
b = MvNormal([0.5,0.5], [0.4, 1])
c = MixtureModel(MvNormal[a,b], [0.2, 0.8])

x = np.linspace(-3, 3, 1000)
y = np.linspace(-3, 3, 1000)
Z = [pdf(c,[i,j]) for i in x, j in y]

# plot(0:10,0:1,Z,st=:surface)
# Plots.plot(c)



surface(x, y, Z)
contour(x,y,Z)

你能把c打出来看看吗,应该是没有为这个类型设置迭代的函数,我想如果对这个c进行类型转换应该没问题

c就是个MIxtureModel, 调用的Distributions库里的,您说的这个类型转换,没思路啊, 不知道咋写

因为多元分布没有自然的图形表示吧,2元可以画等高线图之类的,3元什么的就不行了,而一般用多元分布时都不止二元。不过你也可以写个实现发个PR,既然类型MixtureModel{Multivariate,Continuous,MvNormal,Float64} 看不到元数就运行时@assert一下。

1 个赞

写了个包展示怎么写Recipes:

plot(MixtureModel([
            MvNormal([1., 1.], 1.), 
            MvNormal([2., 2.], 1.),
            MvNormal([5., 5.], 1.),
            MvNormal([2., 4.], 2.)
    ]),
    fmt=:png
)

image

1 个赞

:+1: 最近一直想着学一下 怎么写, 感谢

using Distributions
using Plots
theme(:wong)
gr()
a = MvNormal([2,0.5], [0.2, 0.6])
b = MvNormal([1,1], [0.4, 0.3])
c = MvNormal([1, 2],[0.2, 0.5] )
gmm1 = MixtureModel(MvNormal[a,b,c], [0.2, 0.3, 0.5])

x1 = -1:0.01:6
y1 = -1:0.01:6
Z1 = [pdf(gmm1,[j,i]) for i in y1, j in x1]

d = MvNormal([4.5,2], [0.5, 0.4])
e = MvNormal([4,3], [0.3, 0.6])
f = MvNormal([3, 3.5],[0.7, 0.4] )
gmm2 = MixtureModel(MvNormal[d,e,f], [0.1, 0.5, 0.4])

# x2 = 3:0.01:5
# y2 = 3:0.01:5

Z2 = [pdf(gmm2,[j,i]) for i in y1, j in x1]
# surface(x1, y1, Z1, showaxis=true)
contour(x1,y1,Z1,grid=0,fill=false)
contour!(x1,y1,Z2, grid=0,fill=false)



using Random
data1 = zeros(2,100)
# for i in 1:100
#     Random.seed!()
#     tmp = rand(gmm1,1)
#     data1[:,i] = tmp
# end
Random.seed!()
data1 = rand(gmm1, 100)

xx1 = data1[1,:]
yy1 = data1[2,:]
label1 = zeros(100,1)

plot!(xx1,yy1, seriestype = :scatter, label = "dddd", color = "red", legend = :bottomright)

需要注意的是 [pdf(gmm1,[j,i]) for i in y1, j in x1], 以前写的[i,j] ,导致最后采样画的图不对, 感谢群里几位朋友提醒,我倒过来发现是对的。
以前的图:
YROX8YK~BV8_UDC1XE1PLIG
现在的图:
QKV8P20Q)5`YVXOBO123~IO

可是为啥 [pdf(gmm1,[j,i]) for i in y1, j in x1] 就正过来了, 我还没想清楚

恩,想清楚了,contour 传入的(x1,y1, Z2) 中, contour 自己根据x1, y1计算的坐标矩阵应该和Z2计算的顺序一致。。