Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Follow Up and possible Bug concerning: Multi-class conditions and previous feature request #1 #8

Closed
JensBlack opened this issue Jul 2, 2024 · 4 comments

Comments

@JensBlack
Copy link

JensBlack commented Jul 2, 2024

Hi @lposani,

I really enjoyed going through your material and trying out your package.

Running it on a test case of my data, I stumbled across a previous post #1 where you clarified that the current (past?) version is not capable of handling multiple classes in the conditions. However, if I put in multiple classes, the decoding runs without any issues and returns a result.
Am I assuming that this is not the intended behavior? Or has there been an update that now integrates multi-class conditions?

Code-snippet:

data = {
    "raster": ca_z # z-scored calcium imaging data 
    ,"trial": np.arange(ca_z.shape[0]) # trial number for each time point
    ,"action": sleep_labels
}

conditions = {
    "action": list(np.unique(sleep_labels).flatten())
    }
}

# create a model
dec = Decodanda(data = data
                , conditions = conditions)

where:

ca_z is z-scored calcium imaging traces of N neurons across time.

sleep_labels is a 1D array of sleep/awake stages including 4 classes [0,1,2,3]

Running the decoding, gives me the following output:

decoding_params = {
    'training_fraction': 0.7,       # fraction of trials used for training during cross validation
    'cross_validations': 10,        # number of different training-testing separations
    'nshuffles': 10,                # number of null model repetitions to compute significance
    'plot': True,                   # this generates a recap plot with performance, null model bars, and significance
}


data, null = dec.decode(**decoding_params)

grafik

Further questions:

The underlying assumption is that sleep stages are encoded in my neuronal data (or not).

  1. With the package as is, do I need to binarize my condition and then filter my session data in order to discriminate for major classes (awake vs sleep) and minor classes (e.g., NREM vs REM sleep)?

  2. As there is no trial structure in my data, because the animal is freely moving and not stimulated, is the package actually capable to investigate my use case?

@JensBlack
Copy link
Author

PS: Your documentation seems to be broken:
https://decodanda.readthedocs.io

@lposani
Copy link
Owner

lposani commented Jul 4, 2024

Hey @JensBlack, thanks for your comments! A few points below

  • The multiclass feature has not been added yet, but I have it in development and will eventually take care of it. What most likely happens in your case is that you are decoding the first vs. the second class (0 vs 1). To be sure, you can add verbose=True in the decodanda constructor and see what classes it is creating from its prompt.

  • In the meantime, given your design, I might suggest you ask separate binary questions such as: can I decode sleep from awake? Does it improve when I only use REM vs NREM sleep? Can I decode NREM vs REM during sleep? Etc. The simplest way would be to input labels that are already binarized as per each of the questions you are asking. Alternatively, you could use the lambda language in the conditions argument. For example, assuming you want to decode class 0 & 1 (let's assume they correspond to sleep) vs. class 2&3 (awake), you could use

conditions = {
   'sleep stage': {
       'sleep': lambda x: x < 2,
       'awake': lambda x: x >= 2
   }
}

beware that this will not balance internal classes (e.g. 0 and 1 might have a different number of bins within the 'sleep' class).

  • For the trial structure, I strongly suggest using pseudo trials that span longer periods of continuous behavior (e.g. REM vs NREM sleep) so you avoid the possible confound of decoding time-close points. You can do it by explicitly setting trial_attr=None in the Decodanda constructor. This will take all contiguous sections of the same label (or combination of labels if you use multiple variables) and treat them as pseudo trials - i.e. time bins from the same trial will either go into training or testing data. If these periods are too long, you can use trial_chunk=n to chunk them off in multiple n-long pseudo-trials. Finally, you can use squeeze_trials=True if you want to use the average activity within pseudo-trials as features (instead of time bins).

  • Thanks for the heads up on the docs; I'll take a look ASAP.

@lposani
Copy link
Owner

lposani commented Jul 4, 2024

The docs should be fixed - check it out!

@JensBlack
Copy link
Author

Thank you for the wholesome answer. I will try this out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants