Files
matti_jms_collabs/covid19/uni_maryland_fb_covid19_windowed_PCA.ipynb
T

4.2 MiB
Raw Blame History

Windowed PCA and fluctuation intensity in COVID19 data

In [67]:
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from jmspack.utils import apply_scaling, JmsColors
from jmspack.NLTSA import (fluctuation_intensity,
                            distribution_uniformity,
                            complexity_resonance,
                            complexity_resonance_diagram,
                            cumulative_complexity_peaks,
                            cumulative_complexity_peaks_plot)
from sklearn import decomposition
from sklearn.linear_model import LinearRegression
from scipy.stats import norm
import time
In [68]:
start = time.time()
In [69]:
if "jms_style_sheet" in plt.style.available:
    plt.style.use("jms_style_sheet")
In [70]:
country_choice="Finland"
filepath=f"../shield-complexity/data/{country_choice}_worldsurvey_nonmissing_c_of_v_since_2021-06-08_to_2022-01-21.csv"
In [71]:
df = pd.read_csv(filepath)
In [72]:
df["date"] = pd.to_datetime(df["date"]).dt.date
In [73]:
display(df.head()); df.shape
<style scoped=""> .dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </style>
date pct_covid pct_flu percent_mc percent_hf percent_anos pct_twodoses pct_community_cli pct_activity_work_outside_home pct_activity_shop ... pct_want_info_covid_variants pct_want_info_children_education pct_want_info_economic_impact pct_want_info_mental_health pct_want_info_relationships pct_want_info_employment pct_want_info_none pct_delayed_care_cost pct_mask_shop_1d pct_mask_spent_time_1d
0 2021-06-09 9.039486 9.039486 0.612679 2.813836 6.958875 2.033529 4.412780 1.701158 0.408198 ... 1.796540 3.263608 3.377915 2.276444 2.927897 3.459269 1.471821 2.490908 0.552925 1.417980
1 2021-06-10 11.782998 11.782998 0.512932 2.422617 8.330548 2.013005 5.110684 1.874262 0.391850 ... 1.617688 3.455750 4.811816 2.227195 2.701875 3.445995 1.478371 2.153090 0.386451 1.578405
2 2021-06-11 19.488523 15.235526 2.173259 2.121825 7.898911 3.045827 4.672163 2.991276 2.263277 ... 1.611505 3.279128 5.133363 2.492608 2.942794 4.426361 1.449034 2.251560 0.236805 1.628893
3 2021-06-12 13.118015 13.118015 1.162009 2.543860 8.630301 1.826629 5.658765 2.148999 0.995366 ... 1.701548 3.803658 3.688413 2.070748 2.775816 3.189387 1.242110 2.605254 0.580646 2.399832
4 2021-06-13 10.705081 12.118662 0.782932 2.329260 8.237337 2.684727 5.455478 2.414263 0.566504 ... 1.922228 3.769134 3.916612 2.752952 3.658005 3.275252 1.477509 2.832298 0.449128 2.521729

5 rows × 64 columns

Out[73]:
(207, 64)
In [74]:
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 207 entries, 0 to 206
Data columns (total 64 columns):
 #   Column                             Non-Null Count  Dtype  
---  ------                             --------------  -----  
 0   date                               207 non-null    object 
 1   pct_covid                          207 non-null    float64
 2   pct_flu                            207 non-null    float64
 3   percent_mc                         207 non-null    float64
 4   percent_hf                         207 non-null    float64
 5   percent_anos                       207 non-null    float64
 6   pct_twodoses                       207 non-null    float64
 7   pct_community_cli                  207 non-null    float64
 8   pct_activity_work_outside_home     207 non-null    float64
 9   pct_activity_shop                  207 non-null    float64
 10  pct_activity_restaurant_bar        207 non-null    float64
 11  pct_activity_spent_time            207 non-null    float64
 12  pct_activity_large_event           207 non-null    float64
 13  pct_activity_public_transit        207 non-null    float64
 14  pct_food_security                  207 non-null    float64
 15  pct_anxious_7d                     207 non-null    float64
 16  pct_depressed_7d                   207 non-null    float64
 17  pct_symp_fever                     207 non-null    float64
 18  pct_symp_cough                     207 non-null    float64
 19  pct_symp_diff_breathing            207 non-null    float64
 20  pct_symp_fatigue                   207 non-null    float64
 21  pct_symp_stuffy_nose               207 non-null    float64
 22  pct_symp_aches                     207 non-null    float64
 23  pct_symp_sore_throat               207 non-null    float64
 24  pct_symp_chest_pain                207 non-null    float64
 25  pct_symp_nausea                    207 non-null    float64
 26  pct_symp_headache                  207 non-null    float64
 27  pct_symp_chills                    207 non-null    float64
 28  pct_testing_rate                   207 non-null    float64
 29  pct_avoid_contact                  207 non-null    float64
 30  pct_worried_catch_covid            207 non-null    float64
 31  pct_belief_distancing_effective    207 non-null    float64
 32  pct_belief_masking_effective       207 non-null    float64
 33  pct_others_distanced_public        207 non-null    float64
 34  pct_others_masked_public           207 non-null    float64
 35  pct_belief_children_immune         207 non-null    float64
 36  pct_belief_no_spread_hot_humid     207 non-null    float64
 37  pct_received_news_local_health     207 non-null    float64
 38  pct_received_news_experts          207 non-null    float64
 39  pct_received_news_who              207 non-null    float64
 40  pct_received_news_govt_health      207 non-null    float64
 41  pct_received_news_politicians      207 non-null    float64
 42  pct_received_news_journalists      207 non-null    float64
 43  pct_received_news_friends          207 non-null    float64
 44  pct_received_news_none             207 non-null    float64
 45  pct_trust_covid_info_local_health  207 non-null    float64
 46  pct_trust_covid_info_experts       207 non-null    float64
 47  pct_trust_covid_info_who           207 non-null    float64
 48  pct_trust_covid_info_govt_health   207 non-null    float64
 49  pct_trust_covid_info_politicians   207 non-null    float64
 50  pct_trust_covid_info_journalists   207 non-null    float64
 51  pct_trust_covid_info_friends       207 non-null    float64
 52  pct_trust_covid_info_religious     207 non-null    float64
 53  pct_want_info_covid_treatment      207 non-null    float64
 54  pct_want_info_covid_variants       207 non-null    float64
 55  pct_want_info_children_education   207 non-null    float64
 56  pct_want_info_economic_impact      207 non-null    float64
 57  pct_want_info_mental_health        207 non-null    float64
 58  pct_want_info_relationships        207 non-null    float64
 59  pct_want_info_employment           207 non-null    float64
 60  pct_want_info_none                 207 non-null    float64
 61  pct_delayed_care_cost              207 non-null    float64
 62  pct_mask_shop_1d                   207 non-null    float64
 63  pct_mask_spent_time_1d             207 non-null    float64
dtypes: float64(63), object(1)
memory usage: 103.6+ KB
In [75]:
shuffle_data=False
if shuffle_data:
    df = df.set_index("date").sample(frac=1, random_state=69420).set_index(df["date"])
else:
    df = df.set_index("date")
In [76]:
_ = plt.figure(figsize=(20, 10))
_ = sns.heatmap(df
# .set_index("date")
.T
)
No description has been provided for this image
In [77]:
_ = plt.figure(figsize=(20, 10))
_ = sns.heatmap(df
# .set_index("date")
.pipe(apply_scaling, method="Standard")
.T
)
No description has been provided for this image
In [78]:
df_melt = (df
# .set_index("date")
.pipe(apply_scaling, method="Standard")
.reset_index()
.melt(id_vars="date"))
In [79]:
_ = plt.figure(figsize=(30, 7))
_ = sns.lineplot(data=df_melt, x="date", y="value", hue="variable", legend=False)
No description has been provided for this image
In [80]:
g = sns.FacetGrid(df_melt, col="variable", col_wrap=3, aspect=2)
_ = g.map(sns.lineplot, "date", "value")
No description has been provided for this image
In [81]:
# def summary_window_FUN(x: pd.DataFrame, window_size: int = 7, user_func=decomposition.PCA, kwargs: dict = {}):
#     window_range = np.arange(0, len(x)-window_size, window_size)

#     cp_df = pd.DataFrame()
#     for window_begin in window_range:
#         current_cp_df = pd.DataFrame(user_func(n_components=None, **kwargs)
#                                      .fit_transform(x.iloc[window_begin: window_begin + window_size])).iloc[:, 0]
#         cp_df = pd.concat([cp_df, current_cp_df])

#     return cp_df.rename(columns={0: f"windowed_{user_func.__name__}"}).reset_index(drop=True)
In [82]:
def window_PCA(x: pd.DataFrame, window_size: int = 7, user_func=decomposition.PCA, kwargs: dict = {}):
    window_range = np.arange(0, len(x)-window_size)

    pca_list = list()
    for window_begin in window_range:
        current_pca = user_func(n_components=None, **kwargs).fit(x.iloc[window_begin: window_begin + window_size]).explained_variance_[0]
        pca_list.append(current_pca)

    pca_df = pd.DataFrame({f"windowed_{user_func.__name__}": pca_list})

    return pca_df
In [83]:
window=28
pca_df = window_PCA(x=df, window_size=window).set_index(df.reset_index().loc[:df.shape[0]-window-1, "date"])
In [84]:
pca_df.head()
Out[84]:
<style scoped=""> .dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </style>
windowed_PCA
date
2021-06-09 39.595692
2021-06-10 37.623526
2021-06-11 38.198733
2021-06-12 38.344276
2021-06-13 39.809786
In [85]:
_ = plt.figure(figsize=(15, 5))
_ = sns.lineplot(data=pca_df.reset_index(), x="date", y="windowed_PCA", legend=True)
_ = plt.title(f"Windowed PCA: {country_choice}")
_ = plt.ylabel("Explained Variance of\nfirst principal component")
No description has been provided for this image
In [86]:
tmp = apply_scaling(pca_df, 
method="Standard")
In [87]:
significance_level=0.1
sig_plot_df = tmp.mask(
        tmp > norm.ppf(1 - significance_level), 1
).mask(tmp <= norm.ppf(1 - significance_level), 0)
In [88]:
norm.ppf(1 - significance_level)
norm.ppf(1 - significance_level)
Out[88]:
1.2815515655446004
In [89]:
# _ = sns.heatmap(sig_plot_df.T)
In [90]:
_ = plt.figure(figsize=(15, 5))
_ = plt.plot(tmp)
_ = plt.title(f"Windowed PCA: {country_choice} (significant peaks in yellow based on z-test)")
_ = plt.ylabel("Scaled explained variance of\nfirst principal component")
for sig_date in sig_plot_df[sig_plot_df==True].dropna().index:
    _ = plt.axvline(sig_date, ls="--", c=JmsColors.YELLOW)
No description has been provided for this image
In [91]:
window_size=7
window_range = np.arange(0, len(tmp)-window_size, window_size)
coefs_list = []
for window_begin in window_range:
    win_df = tmp.iloc[window_begin: window_begin + window_size].iloc[:, 0]
    mod = LinearRegression()
    _ = mod.fit(X=win_df.reset_index().index.to_numpy().reshape(-1, 1), y=win_df)
    coefs_list.append(mod.coef_[0])
In [92]:
_ = plt.plot(pd.Series(coefs_list))
No description has been provided for this image
In [93]:
fi_df = fluctuation_intensity(df.pipe(apply_scaling, method="Standard"), 
win=28, 
xmin=0, 
xmax=1, 
col_first=1, 
col_last=df.shape[1])
In [94]:
_ = complexity_resonance_diagram(fi_df, plot_title=f"Fluctuation Intensity Plot: {country_choice}", figsize = (20, 15))
No description has been provided for this image
In [95]:
ccp_df, sig_ccps_df = cumulative_complexity_peaks(df=fi_df, significant_level_item=0.05, significant_level_time=0.05)
In [96]:
_ = cumulative_complexity_peaks_plot(cumulative_complexity_peaks_df=ccp_df, 
significant_peaks_df=sig_ccps_df, plot_title=f"Cumulative Fluctuation Peaks Plot: {country_choice}", figsize = (20, 15))
No description has been provided for this image
In [97]:
_ = plt.figure(figsize=(15, 5))
_ = plt.plot(fi_df.sum(axis=1).replace(0, np.nan))
_ = plt.title(f"Sum of Fluctuation Intensity: {country_choice} (significant fluctuation peaks in yellow)")
for sig_date in sig_ccps_df[sig_ccps_df==True].dropna().index:
    _ = plt.axvline(sig_date, ls="--", c=JmsColors.YELLOW)
No description has been provided for this image
In [98]:
print(f"time elapsed: {time.time()-start} seconds")
time elapsed: 62.09839630126953 seconds
In [ ]: