Generating 2-dimensional sample dataset from a mixture Guassian distribution

Viewed 75

I wanted to generate a 2-dimensional sample dataset. I copied the code stated in this link and doubled it to generate vectors X,Y to scatter them as 2-dimensional dataset as the following. But the result was not favourable. In fact I wanted something like the picture below.

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

mu = [1,4]
sigma = [2, 1]
p_i = [0.3, 0.7]
n = 1000

x = []
y=[]
for i in range(n):
    z_i = np.argmax(np.random.multinomial(1, p_i)) #np.random.multinomial(1,[0.3,0.5,0.2]) returns the result of an experiment
    #of rolling a dice. the result is as this: [1,0,0]. this means that the side one occurs in the experiment and the others 
    #not. the goal is choosing mu[i] in a random way
    x_i = np.random.normal(mu[z_i], sigma[z_i])
    x.append(x_i)

    
mu = [3,6]
sigma = [1, 2]
p_i = [0.6, 0.4]    

for i in range(n):
    z_i = np.argmax(np.random.multinomial(1, p_i)) #np.random.multinomial(1,[0.3,0.5,0.2]) returns the result of an experiment
    #of rolling a dice. the result is as this: [1,0,0]. this means that the side one occurs in the experiment and the others 
    #not. the goal is choosing mu[i] in a random way
    y_i = np.random.normal(mu[z_i], sigma[z_i])
    y.append(y_i)

plt.scatter(x, y)
plt.show()

` enter image description here

Can any one help me?

1 Answers

It looks like what you're trying to plot is data sampled from 2 distinct 2D gaussians. Here is code that can plot mock data that looks like this. Feel free to adjust the mean and covariance matrix to suit your needs.

from numpy.random import multivariate_normal

# First 2D gaussian:
mu = [1, 3]
cov = [[0.07, 0],[0, 1.8]]
x, y = np.random.multivariate_normal(mu, cov, 200).T

plt.figure(figsize=(10,6))
plt.scatter(x, y, s=5, color='blue')
ax = plt.gca()

# Second 2D gaussian:
mu = [2, 1]
cov = [[0.8, -0.4],[-0.4, 0.5]]
x, y = np.random.multivariate_normal(mu, cov, 200).T
plt.scatter(x, y, s=5, color='red')

plt.xlim([-2, 8])
plt.ylim([-6, 10]);

This produces something like the plot below (different colors so you can see the pattern):

enter image description here

Related