<jupyter_start><jupyter_text>Tutorial:   Statistics and Biomechanics  (ISB 2019, Calgary)&copy; <NAME>, 2019  Notebook 4:  Simulating multivariate 0D dataThe purpose of this notebook is to to demonstrate how to simulate multivariate Gaussian 0D data."Multivariate" means "vector", or "more than one variable", and "multivariate 0D data" implies that the vector does not change over some domain like space or time. An example of a multivariate 0D variable is: three-component ground reaction force 50 ms after impact. ___ Part 1: Generating standard normal multivariate dataThe [multivariate normal distribution](https://en.wikipedia.org/wiki/Multivariate_normal_distribution) can can be used to generate random, multivariate Gaussian data very similarly to the univariate (scalar) data from Notebook 1:<jupyter_code>import numpy as np
from matplotlib import pyplot
np.random.seed(1)
I   = 2             #number of vector components
J   = 25            #sample size
mu  = np.zeros(I)   #true population mean
W   = np.eye(I)     #true population covariance
y   = np.random.multivariate_normal(mu, W, J)


ybar = y.mean(axis=0)


ax  = pyplot.axes()
ax.plot(y[:,0], y[:,1], 'ko', ms=3, label='Random sample')
ax.plot(ybar[0], ybar[1], 'bo', ms=10, mfc='w', label='Sample mean')
ax.plot(mu[0], mu[1], 'ro', ms=15, mfc='w', markeredgewidth=3, label='Population mean')
ax.set_xlabel('Vector component 1')
ax.set_ylabel('Vector component 2')
ax.legend()
ax.axis('equal')
pyplot.show()<jupyter_output><empty_output><jupyter_text>The shape of the data distribution can be adjusted by adjusting the population [covariance](https://en.wikipedia.org/wiki/Covariance) to create positive correlation between the vector components like this:<jupyter_code>np.random.seed(1)
W   = np.array( [ [1,0.8], [0.8,1] ] )
y   = np.random.multivariate_normal(mu, W, J)


ybar = y.mean(axis=0)


ax  = pyplot.axes()
ax.plot(y[:,0], y[:,1], 'ko', ms=3, label='Random sample')
ax.plot(ybar[0], ybar[1], 'bo', ms=10, mfc='w', label='Sample mean')
ax.plot(mu[0], mu[1], 'ro', ms=15, mfc='w', markeredgewidth=3, label='Population mean')
ax.set_xlabel('Vector component 1')
ax.set_ylabel('Vector component 2')
ax.legend()
ax.axis('equal')
pyplot.show()<jupyter_output><empty_output><jupyter_text>or negative correlation between the vector components like this:<jupyter_code>np.random.seed(1)
W   = np.array( [ [1,-0.8], [-0.8,1] ] )
y   = np.random.multivariate_normal(mu, W, J)


ybar = y.mean(axis=0)


ax  = pyplot.axes()
ax.plot(y[:,0], y[:,1], 'ko', ms=3, label='Random sample')
ax.plot(ybar[0], ybar[1], 'bo', ms=10, mfc='w', label='Sample mean')
ax.plot(mu[0], mu[1], 'ro', ms=15, mfc='w', markeredgewidth=3, label='Population mean')
ax.set_xlabel('Vector component 1')
ax.set_ylabel('Vector component 2')
ax.legend()
ax.axis('equal')
pyplot.show()<jupyter_output><empty_output><jupyter_text>Note that, due to random sampling, the sample mean is different from the population mean, just like for the univariate case in Notebook 1. ___ Part 2:  Generating realistic multivariate datasetsJust like in Notebook 1, we can use more realistic population parameters to generate data that look more like what we might measure in an experiment. Let's try to simulate two-component ground reaction forces (GRF) during walking in the sagittal plane during early stance, when GRF is expected to be directed upward and rearward:<jupyter_code>np.random.seed(11)
I   = 2             #number of vector components
J   = 50            #sample size
mu  = [-200, 800]   #true population mean
W   = np.array( [ [50,-30], [-30,30] ] )    #true population covariance
y   = np.random.multivariate_normal(mu, W, J)


ybar = y.mean(axis=0)


ax  = pyplot.axes()
ax.plot(y[:,0], y[:,1], 'ko', ms=3, label='Random sample')
ax.plot(ybar[0], ybar[1], 'bo', ms=10, mfc='w', label='Sample mean')
ax.plot(mu[0], mu[1], 'ro', ms=15, mfc='w', markeredgewidth=3, label='Population mean')
ax.set_xlabel('Anterior GRF')
ax.set_ylabel('Vertical GRF')
ax.legend()
ax.axis('equal')
pyplot.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14711680630852636, 'fraction_numerical': 0.028339083292262198, 'mean_word_length': 5.206422018348624, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 18, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '358106', 'license': 'MIT', 'n_tokens_mistral': 1492, 'n_tokens_neox': 1373, 'n_words': 423, 'path': 'Notebooks/Python-nb/4_Simulating_MV_0D.ipynb', 'repo_name': '0todd0000/ISB2019StatisticsTutorial', 'size': '4063'}