In [1]:
# Scientific Python libraries
import numpy as np
import matplotlib.pyplot as plt
import mpld3
import seaborn as sn
mpld3.enable_notebook()
import sys
sys.path.append("../")
# Nexa in-house libraries
from signals.time_series_class import MixAr
from signals.aux_functions import sidekick
from input.sensors import PerceptualSpace, Sensor
from nexa.nexa import Nexa
Now we have a couple of imports here. I will explain what al libraries does:
This is the module to put time series. In this case I am importing a class that allows us to build an autoregressive process (MixAr) that can be mix in space with a simpler series (sidekick) as Pawell suggested.
This module takes care of the input sides to Nexa, that is a group of sensors. Here I created some classes that allow easy organization and implementation of data with a time dimension. In particular the class Sensor represents a single receptive unit that reads a time series from the exterior whereas Perceptual Space allows us to deal with a group of them and their interactions.
Finally, Nexa. Building in Benjaminsson's previous work I implemented (in far more simpler terms, there is still of testing and optimization to be done) a Nexa framework. The Nexa object contains here a perceptual space which represents a -as stated before- a group of sensors with information on time. The Object contains all the operations that allow the creation of vector codes from the ground up:
So first we declare and discuss the parameters and setup requiered for a run of Nexa. We declare the time resoultion of the system and the total amount of time that our system will be simulated. In a real data analysis task this will be determined from the domain of the problem but given that we are in the development, toy example phase we determine those quantites by ourselves.
In [2]:
dt = 0.1
Tmax = 100
In [3]:
# Let's get the sideckick function
amplitude = 1
w1 = 1
w2 = 5
beta = sidekick(w1, w2, dt, Tmax, amplitude)
# Now we will get the AR proccess mixed with the sidekick
# First we need the phi's vector
phi0 = 0.0
phi1 = -0.8
phi2 = 0.3
phi = np.array((phi0, phi1, phi2))
# Now we need the initial conditions
x0 = 1
x1 = 1
x2 = 0
initial_conditions = np.array((x0, x1, x2))
# Second we construct the series with the mix
A = MixAr(phi, dt=dt, Tmax=Tmax, beta=beta)
A.initial_conditions(initial_conditions)
mix_series = A.construct_series()
# mix_series = beta
time = A.time
First we describe the sideckick function, it is specified by two frquencies and the amplitude. Under the hood it is simple a the mix of two sine waves with the given frequency. We visualize it bellow.
In [4]:
%matplotlib inline
plt.plot(time, beta)
plt.show()
Now we will visualiza the Auto Regresive process which is a little bit more complicated. In order to specify an autoregresive process we need as many initial conditions as the order of the process. In concrete our AR is:
$$x(t) = \phi_0 + x(t - 1) * \phi_1 + x(t - 2) * \phi_2 $$It is easy to imagine how to generalize this to any order. Now, the particularity that we introduce is to add also an spatial term to this equation.
$$x(t) = \phi_0 + x(t - 1) * \phi_1 + x(t - 2) * \phi_2 + \beta(t)$$Where beta is our sidekick function.
Our AR class therefore takes in its constructor three initial conditions and the corresponding values of phi. We show the plot below and we see the characteristic plot of an AR process.
In [5]:
plt.plot(time, mix_series)
Out[5]:
In [6]:
# Here we will calculate correlations
Nlags = 100
Nspatial_clusters = 2 # Number of spatial clusters
Ntime_clusters = 2 # Number of time clusters
Nembedding = 3 # Dimension of the embedding space
In [7]:
# We create the here perceptual space
aux_sensors = [Sensor(mix_series, dt), Sensor(beta, dt)]
perceptual_space = PerceptualSpace(aux_sensors, Nlags)
# Now the Nexa object
nexa_object = Nexa(perceptual_space, Nlags, Nspatial_clusters,
Ntime_clusters, Nembedding)
We execute the whole nexa workflow with a single routine
In [8]:
# Calculate all the quantities
nexa_object.calculate_all()
I decided to implement the routine to calculate the code vectors separte however (discuss this!)
In [9]:
# Build the code vectors
code_vectors = nexa_object.build_code_vectors()
In [10]:
from visualization.sensor_clustering import visualize_cluster_matrix
from visualization.sensors import visualize_SLM
from visualization.sensors import visualize_STDM_seaborn
from visualization.time_cluster import visualize_time_cluster_matrix
from visualization.code_vectors import visualize_code_vectors
In [11]:
%matplotlib inline
fig = visualize_SLM(nexa_object)
plt.show(fig)
In [12]:
%matplotlib qt
# fig = visualize_STDM(nexa_object)
fig = visualize_STDM_seaborn(nexa_object)
plt.show(fig)
In [13]:
%matplotlib inline
fig = visualize_cluster_matrix(nexa_object)
In [14]:
%matplotlib inline
cluster = 0
time_center = 1
fig = visualize_time_cluster_matrix(nexa_object, cluster, time_center,
cmap='coolwarm', inter='none',
origin='upper', fontsize=16)
In [15]:
%matplotlib inline
fig = visualize_code_vectors(code_vectors)
In [16]:
np.corrcoef(code_vectors, rowvar=0)
Out[16]: