Spaces:
Build error
Build error
| import streamlit as st | |
| import pandas as pd | |
| import seaborn as sns | |
| import matplotlib.pyplot as plt | |
| from Utility.data_loader import load_train_series,load_train_events,load_sample_submission,load_test_series | |
| from sklearn.model_selection import train_test_split | |
| from sklearn.preprocessing import LabelEncoder, StandardScaler | |
| from xgboost import XGBClassifier # or XGBRegressor depending on your task | |
| import xgboost as xgb | |
| import numpy as np | |
| def load_sampled_data(): | |
| # df3 = pd.read_parquet("train_series.parquet", columns=['series_id', 'step', 'anglez', 'enmo']) | |
| # df4 = pd.read_parquet("test_series.parquet", columns=['series_id', 'step', 'anglez', 'enmo']) | |
| df2 = pd.read_csv("train_events.csv") | |
| # Sample safely based on available data | |
| # df3_sample = df3.sample(n=min(5_000_000, len(df3)), random_state=42) | |
| # df4_sample = df4.sample(n=min(1_000_000, len(df4)), random_state=42) | |
| return df2 | |
| # Load | |
| # df3, df4, df2 = load_sampled_data() | |
| df2 = load_sampled_data() | |
| # df = pd.concat([df3, df4], axis=0, ignore_index=True) | |
| # merged_df = pd.merge(df, df2, on=['series_id', 'step'], how='inner') | |
| merged_df = pd.read_csv("merged_df.csv") | |
| # Rename timestamp columns if they exist | |
| if 'timestamp_x' in merged_df.columns: | |
| merged_df.rename(columns={'timestamp_x': 'sensor_timestamp'}, inplace=True) | |
| if 'timestamp_y' in merged_df.columns: | |
| merged_df.rename(columns={'timestamp_y': 'event_timestamp'}, inplace=True) | |
| st.title("π Step Distribution Analysis") | |
| # Layout: 2 columns | |
| col1, col2 = st.columns([1, 1]) # Equal width | |
| # ----- Column 1: Boxplot ----- | |
| with col1: | |
| st.subheader("π¦ Boxplot of Step") | |
| fig, ax = plt.subplots(figsize=(6, 4)) # Adjusted for better visibility | |
| sns.boxplot(x=df2['step'], ax=ax, color='steelblue') | |
| ax.set_title("Distribution of Step Count", fontsize=14) | |
| ax.set_xlabel("Step", fontsize=12) | |
| st.pyplot (fig) | |
| # ----- Column 2: Insights ----- | |
| with col2: | |
| st.subheader("π§ Insights from the Boxplot") | |
| st.markdown(""" | |
| <small> | |
| <b>Central Tendency:</b><br> | |
| - The <b>median</b> is close to the center of the box, suggesting a fairly symmetric distribution within the interquartile range (IQR).<br> | |
| <b>Spread:</b><br> | |
| - A <b>wide IQR</b> indicates significant variability in the step counts across sessions.<br> | |
| <b>Outliers:</b><br> | |
| - The <b>dots on the right</b> are outliers β representing very high step counts.<br> | |
| - These could reflect either:<br> | |
| - <b>Legitimate long-duration recordings</b><br> | |
| - Or <b>data quality issues</b> (e.g., duplication or sensor errors) | |
| <b>Distribution Shape:</b><br> | |
| - A <b>longer left whisker</b> implies a <b>left-skewed</b> distribution.<br> | |
| - Most sessions have <b>lower step values</b>, with a few very high outliers. | |
| </small> | |
| """, unsafe_allow_html=True) | |
| #st.write("1. Data Visualization - Scatter Plot (feature vs feature or vs target)") | |
| # Assume merged_df is already defined or loaded | |
| df_sample = merged_df # or use df_sample = merged_df.sample(n=50000) to downsample | |
| st.subheader("Scatter Plot: anglez vs enmo") | |
| col1, col2 = st.columns([1, 1]) | |
| with col1: | |
| #st.subheader("Scatter Plot: anglez vs enmo") | |
| # fig, ax = plt.subplots(figsize=(6, 4)) | |
| # sns.scatterplot(x=df['anglez'], y=df['enmo'], ax=ax) | |
| # ax.set_title("Scatter Plot: anglez vs enmo") | |
| # st.pyplot(fig) | |
| # Create the plot | |
| fig, ax = plt.subplots(figsize=(6, 4)) | |
| sns.scatterplot(x='anglez', y='enmo', data=df_sample, ax=ax) | |
| ax.set_title("Scatter Plot: anglez vs enmo") | |
| # Display in Streamlit | |
| st.pyplot(fig) | |
| with col2: | |
| st.markdown(""" | |
| <small> | |
| <b>1. Clustered Points:</b> Most `enmo` values are near 0, suggesting low movement.<br> | |
| <b>2. Symmetry:</b> Spread is balanced on both sides of anglez (Β±), indicating no directional bias.<br> | |
| <b>3. Weak Correlation:</b> No visible trend, suggesting independence between `anglez` and `enmo`.<br> | |
| <b>4. Outliers:</b> A few high `enmo` points may indicate sudden or intense movement.<br> | |
| <b>5. Interpretation:</b> Most data reflects light activity or rest, regardless of body orientation. | |
| </small> | |
| """, unsafe_allow_html=True) | |
| # df_sample = merged_df.sample(n=10000) # adjust sample size for performance | |
| # # Subheader | |
| # st.subheader("Pair Plot of Features") | |
| # # Create pairplot | |
| # fig = sns.pairplot(df_sample[['anglez', 'enmo', 'step']]) | |
| # fig.fig.suptitle("Pair Plot of Features", y=1.02) | |
| # # Display in Streamlit | |
| # st.pyplot(fig) | |
| # Define columns to plot | |
| col1, col2 = st.columns([1, 1]) # Equal width | |
| # Column 1: Pair Plot | |
| with col1: | |
| st.subheader("π Pair Plot of Features") | |
| fig = sns.pairplot(merged_df[['anglez', 'enmo', 'step']]) | |
| st.pyplot(fig) | |
| # Column 2: Insights | |
| with col2: | |
| st.subheader("π§ Insights from Pair Plot") | |
| st.markdown(""" | |
| <div style='font-size: 14px'> | |
| ### π Distribution Insights: | |
| - **anglez**: Symmetric distribution peaking near -50 to 0. | |
| - **enmo**: Right-skewed, most values below 0.1. | |
| - **step**: Right-skewed, with a few large outliers. | |
| ### π Pairwise Relationships: | |
| - **anglez vs enmo**: No clear trend; cone-like shape. | |
| - **anglez vs step**: No correlation; looks uniformly scattered. | |
| - **enmo vs step**: Clustered at low values. High steps sometimes with low enmo. | |
| ### π‘ Summary: | |
| - Features appear largely **uncorrelated**. | |
| - Helps identify **data distributions** and potential **outliers**. | |
| - Can assist in **feature selection/engineering**. | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # plot_columns = ['anglez', 'enmo', 'step'] | |
| # # Safety check: make sure required columns exist | |
| # if all(col in merged_df.columns for col in plot_columns): | |
| # # Check data size and sample accordingly | |
| # max_rows = len(merged_df) | |
| # sample_size = min(10000, max_rows) # Don't exceed available rows | |
| # df_sample = merged_df.sample(n=sample_size) | |
| # # Subheader | |
| # st.subheader("Pair Plot of Features") | |
| # # Create pairplot | |
| # fig = sns.pairplot(df_sample[plot_columns]) | |
| # fig.fig.suptitle("Pair Plot of Features", y=1.02) | |
| # # Display in Streamlit | |
| # st.pyplot(fig) | |
| # else: | |
| # st.error("One or more required columns ('anglez', 'enmo', 'step') are missing in the dataset.") | |
| # Plot | |
| fig, axes = plt.subplots(1, 2, figsize=(14, 5)) | |
| sns.histplot(df_sample['anglez'], kde=True, bins=50, ax=axes[0]) | |
| axes[0].set_title("Distribution of anglez") | |
| sns.histplot(df_sample['enmo'], kde=True, bins=50, ax=axes[1]) | |
| axes[1].set_title("Distribution of enmo") | |
| plt.tight_layout() | |
| st.pyplot(fig) | |
| # Show insights side by side | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| st.markdown(""" | |
| <div style='font-size: 14px'> | |
| <h3> π Distribution of `anglez`: </h3> | |
| - The distribution is **roughly symmetric**, centered around **-50 to 0**. | |
| - It resembles a **left-heavy bell shape**, suggesting: | |
| - Most sensor angles were **tilted negatively**. | |
| - Indicates a **natural resting position** or specific posture. | |
| </div> | |
| """, unsafe_allow_html=True) | |
| with col2: | |
| st.markdown(""" | |
| <div style='font-size: 14px'> | |
| <h3> π Distribution of `enmo`: </h3> | |
| - Highly **right-skewed** (sharp peak near zero). | |
| - The majority of `enmo` values are **very small** (< 0.05), indicating: | |
| - **Minimal movement or low activity** in most sessions. | |
| - Few data points reflect **moderate to high movement**. | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # st.write("Multicollinearity Check - Correlation Matrix") | |
| # features = ['anglez', 'enmo', 'step', 'night'] | |
| # df_subset = merged_df[features] | |
| # # Streamlit title | |
| # st.subheader("Multicollinearity Check - Correlation Matrix") | |
| # # Calculate correlation matrix | |
| # corr_matrix = df_subset.corr() | |
| # # Plot heatmap | |
| # fig, ax = plt.subplots(figsize=(6, 4)) | |
| # sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', ax=ax) | |
| # ax.set_title("Correlation Matrix") | |
| # # Display in Streamlit | |
| # st.pyplot(fig) | |
| st.subheader("Multicollinearity Check - Correlation Matrix") | |
| # Select relevant features | |
| features = ['anglez', 'enmo', 'step', 'night'] | |
| df_subset = merged_df[features] | |
| # Calculate correlation matrix | |
| corr_matrix = df_subset.corr() | |
| # Create plot | |
| fig, ax = plt.subplots(figsize=(6, 4)) | |
| sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0, fmt=".3f", ax=ax) | |
| ax.set_title("Correlation Matrix") | |
| # Layout in two columns | |
| col1, col2 = st.columns(2) | |
| # Column 1: Heatmap | |
| with col1: | |
| st.pyplot(fig) | |
| # Column 2: Textual Insights | |
| with col2: | |
| st.markdown(""" | |
| ### π Insights from Correlation Matrix | |
| - **`anglez` & `enmo`**: | |
| πΈ Weak negative correlation (**-0.11**) β suggests minimal linear relationship. | |
| - **`step` & `night`**: | |
| β οΈ Perfect correlation (**1.00**) β indicates **redundancy**, likely representing the same event in different forms. | |
| - **Overall**: | |
| β Low multicollinearity across most features β safe for modeling. | |
| π Recommend removing either `step` or `night` to reduce feature duplication. | |
| """) | |
| # Encode | |
| le = LabelEncoder() | |
| merged_df['series_id'] = le.fit_transform(merged_df['series_id']) | |
| merged_df['event'] = le.fit_transform(merged_df['event']) | |
| # Drop columns with string or datetime values | |
| drop_cols = ['sensor_timestamp', 'event_timestamp', 'night', 'step', 'sleep_duration_hrs', 'series_id'] | |
| df_cleaned = merged_df.drop(columns=[col for col in drop_cols if col in merged_df.columns]) | |
| # Ensure only numeric features in X | |
| X = df_cleaned.drop('event', axis=1).select_dtypes(include=[np.number]) | |
| y = merged_df['event'] | |
| # Split and scale | |
| X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=27) | |
| st.subheader("Feature Importance") | |
| # Create model instance | |
| xgb_model = XGBClassifier(use_label_encoder=False, eval_metric='logloss') # example for classification | |
| # Fit the model | |
| xgb_model.fit(X_train, y_train) | |
| # Plot feature importance | |
| fig, ax = plt.subplots(figsize=(6, 4)) | |
| xgb.plot_importance(xgb_model, ax=ax) | |
| ax.set_title("XGBoost Feature Importance") | |
| # Show in Streamlit | |
| st.subheader("XGBoost Feature Importance") | |
| col1, col2 = st.columns(2) | |
| # Column 1: Plot | |
| with col1: | |
| st.pyplot(fig) | |
| st.markdown(""" | |
| #### π« Low-Impact Features: | |
| - Features like `step` and `night` (excluded in this plot) showed **minimal or redundant contribution**. | |
| - π You may consider **removing** them to simplify the model. | |
| """) | |
| # Column 2: Insights | |
| with col2: | |
| st.markdown(""" | |
| <small> | |
| <h3> π XGBoost Feature Importance: Key Insights </h3> | |
| #### π Top Features: | |
| - πΉ **`anglez`** β Highest importance score (**1557**) | |
| - πΉ **`enmo`** β Close second with score (**1546**) | |
| #### β Summary: | |
| - Both `anglez` and `enmo` contribute **significantly** to the model. | |
| - Their high scores reflect **strong influence** in predicting the target variable. | |
| #### π‘ Interpretation: | |
| - These features likely capture **activity level** or **sleep posture** patterns. | |
| - Keeping both is **recommended** for accurate classification. | |
| </small> | |
| """, unsafe_allow_html=True) | |