{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":82611,"databundleVersionId":9553358,"sourceType":"competition"},{"sourceId":9990608,"sourceType":"datasetVersion","datasetId":6148575},{"sourceId":9990690,"sourceType":"datasetVersion","datasetId":6148623}],"dockerImageVersionId":30787,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom sklearn.preprocessing import MinMaxScaler, LabelEncoder\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import LSTM, Dense, Dropout\nfrom sklearn.model_selection import train_test_split\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-23T14:05:03.349300Z","iopub.execute_input":"2024-11-23T14:05:03.350287Z","iopub.status.idle":"2024-11-23T14:05:14.125564Z","shell.execute_reply.started":"2024-11-23T14:05:03.350250Z","shell.execute_reply":"2024-11-23T14:05:14.124647Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load train.csv\ntrain_file_path = '/kaggle/input/train-data/train.csv'\ntrain_data = pd.read_csv(train_file_path)\n\n# Select relevant columns (glucose and activity data)\nglucose_columns = [col for col in train_data.columns if col.startswith('bg-')]\nactivity_columns = [col for col in train_data.columns if col.startswith('activity-')]\nrelevant_columns = glucose_columns + activity_columns + ['bg+1:00']  # Include target column\n\n# Preprocess train data\nprocessed_train_data = train_data[relevant_columns].copy()\n\n# Handle missing values\nprocessed_train_data[glucose_columns] = processed_train_data[glucose_columns].fillna(method='ffill')  # Forward fill glucose\nprocessed_train_data[activity_columns] = processed_train_data[activity_columns].fillna(0)  # Replace missing activity with 0\nprocessed_train_data['bg+1:00'] = processed_train_data['bg+1:00'].fillna(method='bfill')  # Backward fill target\n\n# Encode categorical activity data\ncategorical_columns = [col for col in activity_columns if processed_train_data[col].dtype == 'object']\nlabel_encoder = LabelEncoder()\nfor col in categorical_columns:\n    processed_train_data[col] = label_encoder.fit_transform(processed_train_data[col].astype(str))\n\n# Drop rows with excessive missing data\nprocessed_train_data.dropna(inplace=True)\n\n# Scale features and target separately\nfeature_scaler = MinMaxScaler()\ntarget_scaler = MinMaxScaler()\n\n# Scale features (exclude the target column)\nfeatures = processed_train_data.drop(columns=['bg+1:00'])\nfeatures_scaled = pd.DataFrame(\n    feature_scaler.fit_transform(features),\n    columns=features.columns\n)\n\n# Scale target column\ntarget_scaled = target_scaler.fit_transform(processed_train_data[['bg+1:00']])\nfeatures_scaled['bg+1:00'] = target_scaled  # Add scaled target back to the data","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-23T14:05:14.126978Z","iopub.execute_input":"2024-11-23T14:05:14.127446Z","iopub.status.idle":"2024-11-23T14:05:30.241024Z","shell.execute_reply.started":"2024-11-23T14:05:14.127418Z","shell.execute_reply":"2024-11-23T14:05:30.240034Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Function to create sequences\ndef create_sequences(data, target_column, time_steps):\n    X, y = [], []\n    for i in range(len(data) - time_steps):\n        X.append(data.iloc[i:i + time_steps].drop(target_column, axis=1).values)\n        y.append(data.iloc[i + time_steps][target_column])\n    return np.array(X), np.array(y)\n\n# Define time window (6 hours of data, e.g., 24 timesteps if data is sampled every 15 minutes)\nTIME_STEPS = 24\nTARGET_COLUMN = 'bg+1:00'\n\n# Generate sequences for training\nX_train, y_train = create_sequences(features_scaled, target_column=TARGET_COLUMN, time_steps=TIME_STEPS)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-23T14:05:30.242291Z","iopub.execute_input":"2024-11-23T14:05:30.243053Z","iopub.status.idle":"2024-11-23T14:06:53.037894Z","shell.execute_reply.started":"2024-11-23T14:05:30.243009Z","shell.execute_reply":"2024-11-23T14:06:53.037169Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load test.csv\ntest_file_path = '/kaggle/input/test-csv/test.csv'\ntest_data = pd.read_csv(test_file_path)\n\n\n# Check if the target column exists\nif 'bg+1:00' in test_data.columns:\n    # Preprocess test data with the target column\n    processed_test_data = test_data[relevant_columns].copy()\n\n    # Handle missing values\n    processed_test_data[glucose_columns] = processed_test_data[glucose_columns].ffill()\n    processed_test_data[activity_columns] = processed_test_data[activity_columns].fillna(0)\n    processed_test_data['bg+1:00'] = processed_test_data['bg+1:00'].bfill()\n\n    # Handle unseen labels in categorical activity columns\n    for col in categorical_columns:\n        processed_test_data[col] = processed_test_data[col].astype(str)\n        processed_test_data[col] = processed_test_data[col].apply(\n            lambda x: x if x in label_encoder.classes_ else \"unknown\"\n        )\n        if \"unknown\" not in label_encoder.classes_:\n            label_encoder.classes_ = np.append(label_encoder.classes_, \"unknown\")\n        processed_test_data[col] = label_encoder.transform(processed_test_data[col])\n\n    # Scale features and target using training scalers\n    features_test = processed_test_data.drop(columns=['bg+1:00'])\n    features_scaled_test = pd.DataFrame(\n        feature_scaler.transform(features_test),\n        columns=features_test.columns\n    )\n    target_scaled_test = target_scaler.transform(processed_test_data[['bg+1:00']])\n    features_scaled_test['bg+1:00'] = target_scaled_test\n\n    # Generate sequences for testing\n    X_test, y_test = create_sequences(features_scaled_test, target_column=TARGET_COLUMN, time_steps=TIME_STEPS)\nelse:\n    # Preprocess test data without the target column\n    processed_test_data = test_data[glucose_columns + activity_columns].copy()\n\n    # Handle missing values\n    processed_test_data[glucose_columns] = processed_test_data[glucose_columns].ffill()\n    processed_test_data[activity_columns] = processed_test_data[activity_columns].fillna(0)\n\n    # Handle unseen labels in categorical activity columns\n    for col in categorical_columns:\n        processed_test_data[col] = processed_test_data[col].astype(str)\n        processed_test_data[col] = processed_test_data[col].apply(\n            lambda x: x if x in label_encoder.classes_ else \"unknown\"\n        )\n        if \"unknown\" not in label_encoder.classes_:\n            label_encoder.classes_ = np.append(label_encoder.classes_, \"unknown\")\n        processed_test_data[col] = label_encoder.transform(processed_test_data[col])\n\n    # Scale features using the training feature scaler\n    features_scaled_test = pd.DataFrame(\n        feature_scaler.transform(processed_test_data),\n        columns=processed_test_data.columns\n    )\n\n    # Generate sequences for testing (no target column)\n    X_test = []\n    for i in range(len(features_scaled_test) - TIME_STEPS):\n        X_test.append(features_scaled_test.iloc[i:i + TIME_STEPS].values)\n    X_test = np.array(X_test)\n    y_test = None\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-23T14:06:53.039794Z","iopub.execute_input":"2024-11-23T14:06:53.040064Z","iopub.status.idle":"2024-11-23T14:06:54.954800Z","shell.execute_reply.started":"2024-11-23T14:06:53.040039Z","shell.execute_reply":"2024-11-23T14:06:54.954090Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Build the LSTM model\nmodel = Sequential([\n    LSTM(64, return_sequences=True, input_shape=(X_train.shape[1], X_train.shape[2])),\n    Dropout(0.2),\n    LSTM(32, return_sequences=False),\n    Dropout(0.2),\n    Dense(16, activation='relu'),\n    Dense(1)  # Single output for bg+1:00 prediction\n])\n\n# Compile the model\nmodel.compile(optimizer='adam', loss='mse', metrics=['mae'])\n\n# Train the model\nhistory = model.fit(\n    X_train, y_train,\n    validation_split=0.2,\n    epochs=50,\n    batch_size=32,\n    verbose=1\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-23T14:06:54.955791Z","iopub.execute_input":"2024-11-23T14:06:54.956056Z","iopub.status.idle":"2024-11-23T14:30:14.768050Z","shell.execute_reply.started":"2024-11-23T14:06:54.956032Z","shell.execute_reply":"2024-11-23T14:30:14.767310Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Evaluate the model if test data has the target\nif y_test is not None:\n    test_loss, test_mae = model.evaluate(X_test, y_test, verbose=1)\n    print(f\"Test Loss (MSE): {test_loss}, Test MAE: {test_mae}\")\n\n# Predict on the test set\ny_pred = model.predict(X_test)\n\n# Inverse transform the predictions\ny_pred_original = target_scaler.inverse_transform(y_pred)\n\n# If ground truth exists, inverse transform y_test\nif y_test is not None:\n    y_test_original = target_scaler.inverse_transform(np.expand_dims(y_test, axis=-1))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-23T14:30:14.769297Z","iopub.execute_input":"2024-11-23T14:30:14.769609Z","iopub.status.idle":"2024-11-23T14:30:15.444856Z","shell.execute_reply.started":"2024-11-23T14:30:14.769581Z","shell.execute_reply":"2024-11-23T14:30:15.444075Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Save predictions in the required format\nsubmission = pd.DataFrame({\n    'id': np.arange(len(y_pred)),  # Replace with actual test IDs if available\n    'bg+1:00': y_pred_original.flatten()\n})\n\n# Remove rows with NaN values from the submission DataFrame\nsubmission_cleaned = submission.dropna()\nnan_check = submission_cleaned.isnull().sum()\n\n\nsubmission_cleaned.to_csv('submission_cleaned.csv',index=False)\n\n\n \nprint(submission_cleaned.head())  # Display the first few rows of the cleaned data\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-23T14:35:50.181134Z","iopub.execute_input":"2024-11-23T14:35:50.181461Z","iopub.status.idle":"2024-11-23T14:35:50.197322Z","shell.execute_reply.started":"2024-11-23T14:35:50.181431Z","shell.execute_reply":"2024-11-23T14:35:50.196524Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(submission_cleaned)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-23T14:35:55.246687Z","iopub.execute_input":"2024-11-23T14:35:55.247023Z","iopub.status.idle":"2024-11-23T14:35:55.254886Z","shell.execute_reply.started":"2024-11-23T14:35:55.246994Z","shell.execute_reply":"2024-11-23T14:35:55.253686Z"}},"outputs":[],"execution_count":null}]}