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

Spike: Classify sleep windows as non-wear or sleep #106

Open
3 tasks
Asanto32 opened this issue Sep 18, 2024 · 9 comments
Open
3 tasks

Spike: Classify sleep windows as non-wear or sleep #106

Asanto32 opened this issue Sep 18, 2024 · 9 comments
Assignees
Labels
blocked Can't be moved forward low-priority Issues of low priority Spike Time boxed investigations

Comments

@Asanto32
Copy link
Collaborator

Asanto32 commented Sep 18, 2024

Description

Currently, the detection of sleep will also serve as non-wear detection (most non-wear periods will also be detected as sleep, as from an accelerometer point of view they are the same, the inverse is of course-not true, not all sleep periods are detected as non-wear). The current implementation of the Van Hees algorithm for sleep only relies on angle-z (looking the changes in the rolling std of angle-z metric, essentially). As a solution to separate sleep windows from non-wear times, a simple filtering method has been implemented in analytics.remove_nonwear_from_sleep.

However, what if we were to apply some simple classification looking at a few features of both enmo and angle-z during a defined sleep window. Notably:

  • mean(enmo)
  • std(enmo)
  • std(anglez)
  • max(enmo)
  • range(anglez)
  • FFT(enmo) -> high frequency noise indicative of movement that doesn't appear in non-wear
  • FFT(anglez)

Some examples highlighting the differences between sleep and non-wear are shown below (blue indicates sleep, red enmo, green anglez, black non-wear)

Screenshot 2024-09-18 at 12 29 35 PM

This is an especially difficult case, non-wear immediately before bed with only a very short window of activity separating the two. Merged into one sleep window (but it has two distinct sleep periods, SIBs) since the activity time is less than the threshold.
Screenshot 2024-09-18 at 12 29 04 PM

Screenshot 2024-09-18 at 12 28 48 PM
Screenshot 2024-09-18 at 12 28 25 PM

Tasks

  • Find features
  • Test if they work (how many, train, test, validate, etc.). In the interest of time it can be a simple voting scheme from a list of features not really training a binary classifier.
  • Get the ok to spend time on this

Freeform Notes

No response

@Asanto32 Asanto32 added the task A development task intended for Github Projects label Sep 18, 2024
@Asanto32
Copy link
Collaborator Author

No rush on this but just some thoughts I had as we go through the Kaggle comp implementation. Since our current sleep detection is actually pretty good, the more time-sensitive, simple question is separating non-wear time from it.
@gkiar @vitoetc @frey-perez @ReinderVosDeWael @nx10 @clane9

@nx10
Copy link
Contributor

nx10 commented Sep 18, 2024

If the goal is not to mimick GGIR, I think conceptually non-wear should be regarded as missing data and (if necessary) either imputed or processed by a model that can handle missing data.

@Asanto32
Copy link
Collaborator Author

I also realize this falls more in the "analysis" branch and not really "wristpy for processing actigraphy data"

@Asanto32
Copy link
Collaborator Author

If the goal is not to mimick GGIR, I think conceptually non-wear should be regarded as missing data and (if necessary) either imputed or processed by a model that can handle missing data.

I should start looking into using the capsense data and see how we can take advantage of that.

@clane9
Copy link

clane9 commented Sep 19, 2024

I agree that the capsense/temperature data would be very useful for distinguishing non-wear from sleep. Otherwise, I agree the two seem hard to distinguish.

I think the ideal approach would be a model/algorithm that takes as input all available raw data, and produces separate predictions for sleep and non-wear. Any pre-processing/feature-engineering/heuristics would be internal to the model. Ofc, it is also fine to have simple heuristics for detecting non-wear/sleep that work fine in most cases. But I would discourage having any of these be upstream of a sleep detection model. Anything you do upstream of the model removes information and limits the model's performance.

In particular, I would discourage trying to detect and code non-wear as missing/NaN before feeding to a sleep detection model. I agree with @nx10 that non-wear is fundamentally missing data. I just think it should be the model's job to detect it.

@Asanto32
Copy link
Collaborator Author

Just to clarify: non-wear and sleep are currently completely separate algorithms (see detect_non_wear and run_sleep_detection. I just have an additional function that filters out sleep windows (already detected) that have any overlap with detected non-wear periods (basically, I agree that if we detect that the watch isn't being worn, we shouldn't say that someone is sleeping).

Basically the point of my thought process is essentially a second stage that would try to filter out false-positives. But I agree an all-encompassing model would be better. This is almost more of a stop gap idea that I thought is both easier and quicker to implement while we wait for something more robust/nicer.

Does that help clarify a bit? I guess this was better for a meeting and not a forum discussion ha

@ReinderVosDeWael ReinderVosDeWael changed the title [Draft] Task: (simple) Classify sleep windows as non-wear or sleep Spike: (simple) Classify sleep windows as non-wear or sleep Oct 30, 2024
@ReinderVosDeWael
Copy link
Contributor

Reclassified to spike, time-boxed to 3 days.

@ReinderVosDeWael ReinderVosDeWael added Spike Time boxed investigations and removed task A development task intended for Github Projects labels Oct 30, 2024
@ReinderVosDeWael ReinderVosDeWael changed the title Spike: (simple) Classify sleep windows as non-wear or sleep Spike: Classify sleep windows as non-wear or sleep Oct 30, 2024
@Asanto32 Asanto32 self-assigned this Dec 4, 2024
@Asanto32
Copy link
Collaborator Author

Asanto32 commented Dec 10, 2024

UPDATE:

After the agreed 3 days these are my current thoughts:

  • There are minimal false positive sleep windows and all false-positive sleep windows are true non-wear
  • False-positive non-wear times are more prevalent than sleep (even with new temperature algorithms and majority vote implementation)

I have created methods to move SleepWindow to a Measurement, which allows us to easily remove the non-wear overlap and then remove any short sleep windows that may be left over (less than 15min). This functionality can be called in the future after we have improved non-wear detection/ after the non-wear classification project, it is in this branch.

I will leave this task up in case there is a further desire to investigate using other features to re-classify sleep, but at the moment I do not see the benefit. Improved non-wear detection and, potentially, improved sleep detection would solve all these issue without adding a second classification stage.

@Asanto32 Asanto32 added low-priority Issues of low priority blocked Can't be moved forward labels Dec 10, 2024
@ReinderVosDeWael
Copy link
Contributor

@vitoetc This issue is blocked until annotated data exists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked Can't be moved forward low-priority Issues of low priority Spike Time boxed investigations
Projects
None yet
Development

No branches or pull requests

4 participants