Created
February 6, 2026 16:11
-
-
Save stanichor/481ad2f63f46f8e5e1ed1d6d9639ec7f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import numpy as np | |
| # Variable names. | |
| # The first variable is a latent sleep-quality factor. | |
| # The remaining variables are observed sleep trackers. | |
| names = [ | |
| 'latent', | |
| 'Whoop', | |
| '8Sleep', | |
| 'Autosleep' | |
| ] | |
| # Correlation matrix. | |
| # - The first row/column gives correlations between the latent factor | |
| # and each sleep tracker. These values are interpreted as factor loadings. | |
| # - The remaining entries are raw correlations between sleep trackers. | |
| correlation_matrix = np.array([ | |
| [1.00, 0.64, 0.60, 0.46], | |
| [0.64, 1.00, 0.38, 0.14], | |
| [0.60, 0.38, 1.00, 0.42], | |
| [0.46, 0.14, 0.42, 1.00] | |
| ]) | |
| # Iteratively include the top k sleep trackers as predictors of the latent factor | |
| for i in range(1, 3 + 1): | |
| num_predictors = i | |
| # Report which sleep trackers are being used | |
| print(f"Using top {num_predictors} predictor(s): {', '.join(names[1:num_predictors+1])}") | |
| # Subset the correlation matrix to include: | |
| # - the latent factor (index 0) | |
| # - the first k sleep trackers | |
| num_variables = num_predictors + 1 | |
| corr = correlation_matrix[:num_variables, :num_variables] | |
| # Invert the correlation matrix to obtain the precision matrix | |
| # The precision matrix encodes conditional independencies | |
| precision_matrix = np.linalg.inv(corr) | |
| # The reciprocal of each diagonal element of the precision matrix | |
| # gives the conditional variance of that variable given the others | |
| partial_variances = 1 / np.diag(precision_matrix) | |
| # For the latent variable (index 0), the conditional variance | |
| # is the unexplained variance after regressing it on the sleep trackers | |
| explained_variance = 1 - partial_variances[0] | |
| # The square root gives the multiple correlation between | |
| # the latent sleep score and the included sleep trackers | |
| print(f"Estimated Correlation: {np.sqrt(explained_variance):.2f}") | |
| print() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment