在Python中绘制两个多元高斯的决策边界

4 python matplotlib

我将从以下堆栈溢出问题中借用图像来帮助我描述我的问题: Drawing decision boundary of two multivariate gaussian

在此处输入图片说明

我有 2 个带有 2D 点的类,我感兴趣的是决策边界(或判别式)。

我编写了返回判别函数(浮点值)结果的函数,允许我将样本分类为这两种模式。

如果一个样本点是例如 x_i = [x, y]
我可以调用函数和

如果g1(x,y) > g2(x,y)是第 1 类,反之亦然,如果

g1(x,y) <= g2(x,y) 这是 2 级

所以决策边界应该在 g1(x,y) == g2(x,y)


编辑:

希望一个例子有帮助:

1)假设我x = [1, 2]从数据集中取1个样本


2)然后我将调用例如
g1(1,2)-->返回0.345
g2(1,2)-->返回0.453
-->样本x属于第2类,因为g2(1,2) > g1(1,2)


3)现在做决定边界,我有g2(x,y) == g1(x,y),
或
g1(x,y) - g2(x,y)== 0


4)我生成了一系列x值,例如,,1,2,3,4,5现在我想找到y产生g1(x,y) - g2(x,y) == 0


5)的相应值,然后我可以使用这些x,y对来绘制决策边界


在我上面链接的 StackOverflow 帖子中,建议是

您可以简单地绘制 f(x,y) := pdf1(x,y) > pdf2(x,y) 的等高线。所以你定义函数 f 为 1 iff pdf1(x,y)>pdf2(x,y)。这样,唯一的轮廓将沿着曲线放置,其中 pdf1(x,y)==pdf2(x,y) 是决策边界(判别式)。如果你想定义“不错”的函数,你可以简单地通过设置 f(x,y) = sgn( pdf1(x,y) - pdf2(x,y) ) 来完成,绘制它的等高线图将导致完全相同判别。

但是我将如何在 Python 和 matplotlib 中做到这一点,我真的迷失了设置代码来做到这一点。我很感激任何帮助!

编辑:

关于函数g()本身的更多信息:

def discr_func(x, y, cov_mat, mu_vec):
    """
    Calculates the value of the discriminant function for a dx1 dimensional
    sample given covariance matrix and mean vector.

    Keyword arguments:
        x_vec: A dx1 dimensional numpy array representing the sample.
        cov_mat: dxd numpy array of the covariance matrix.
        mu_vec: dx1 dimensional numpy array of the sample mean.

    Returns a float value as result of the discriminant function.

    """
    x_vec = np.array([[x],[y]])

    W_i = (-1/2) * np.linalg.inv(cov_mat)
    assert(W_i.shape[0] > 1 and W_i.shape[1] > 1), 'W_i must be a matrix'

    w_i = np.linalg.inv(cov_mat).dot(mu_vec)
    assert(w_i.shape[0] > 1 and w_i.shape[1] == 1), 'w_i must be a column vector'

    omega_i_p1 = (((-1/2) * (mu_vec).T).dot(np.linalg.inv(cov_mat))).dot(mu_vec)
    omega_i_p2 = (-1/2) * np.log(np.linalg.det(cov_mat))
    omega_i = omega_i_p1 - omega_i_p2
    assert(omega_i.shape == (1, 1)), 'omega_i must be a scalar'

    g = ((x_vec.T).dot(W_i)).dot(x_vec) + (w_i.T).dot(x_vec) + omega_i
    return float(g)
Run Code Online (Sandbox Code Playgroud)

当我执行它时,它会返回一个浮点数,例如,

discr_func(1, 2, cov_mat=cov_est_1, mu_vec=mu_est_1)
-3.726426544537969

如果我没记错的话,应该是这个等式: 在此处输入图片说明

非常感谢您对轮廓的建议,但是,我在实施它时遇到了问题:

import pylab as pl

X, Y = np.mgrid[-6:6:100j, -6:6:100j]
x = X.ravel()
y = Y.ravel()

p = (discr_func(x, y, cov_mat=cov_est_1, mu_vec=mu_est_1) -\
     discr_func(x, y, cov_mat=cov_est_2, mu_vec=mu_est_2)).reshape(X.shape)

#pl.scatter(X_train[:, 0], X_train[:, 1])
pl.contour(X, Y, p, levels=[0])

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-192-28c1c8787237> in <module>()
      5 y = Y.ravel()
      6 
----> 7 p = (discr_func(x, y, cov_mat=cov_est_1, mu_vec=mu_est_1) -     discr_func(x, y, cov_mat=cov_est_2, mu_vec=mu_est_2)).reshape(X.shape)
      8 
      9 #pl.scatter(X_train[:, 0], X_train[:, 1])

<ipython-input-184-fd2f8b7fad82> in discr_func(x, y, cov_mat, mu_vec)
     25     assert(omega_i.shape == (1, 1)), 'omega_i must be a scalar'
     26 
---> 27     g = ((x_vec.T).dot(W_i)).dot(x_vec) + (w_i.T).dot(x_vec) + omega_i
     28     return float(g)

ValueError: objects are not aligned
Run Code Online (Sandbox Code Playgroud)

我的感觉是.ravel()列表的传递与我设置此功能的方式不兼容......有什么建议吗?

HYR*_*YRY 5

g1(x, y) - g2(x, y)在 a 上计算mgrid[],然后通过 绘制线contour(..., levels=[0]),这是一个例子。由于您没有发布任何示例数据和代码,我使用 sklearn 生成示例数据。您只需要以下代码#plot code from here:

import numpy as np
import pylab as pl
from sklearn import mixture

np.random.seed(0)
C1 = np.array([[3, -2.7], [1.5, 2.7]])
C2 = np.array([[1, 2.0], [-1.5, 1.7]])

X_train = np.r_[
    np.random.multivariate_normal((-5, -5), C1, size=100),
    np.random.multivariate_normal((5, 5), C2, size=100),
]

clf = mixture.GMM(n_components=2, covariance_type='full')
clf.fit(X_train)

#define g1(x, y) and g2(x, y)

def g1(x, y):
    return clf.predict_proba(np.column_stack((x, y)))[:, 0]

def g2(x, y):
    return clf.predict_proba(np.column_stack((x, y)))[:, 1]

#plot code from here

X, Y = np.mgrid[-15:15:100j, -15:15:100j]
x = X.ravel()
y = Y.ravel()

p = (g1(x, y) - g2(x, y)).reshape(X.shape)

pl.scatter(X_train[:, 0], X_train[:, 1])
pl.contour(X, Y, p, levels=[0])
Run Code Online (Sandbox Code Playgroud)

这是输出:

在此处输入图片说明