{"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":"gpu","dataSources":[{"sourceId":82611,"databundleVersionId":9553358,"sourceType":"competition"}],"dockerImageVersionId":30786,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install pytorch-tabnet torch\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-11-12T15:26:01.294371Z","iopub.execute_input":"2024-11-12T15:26:01.295014Z","iopub.status.idle":"2024-11-12T15:26:14.190070Z","shell.execute_reply.started":"2024-11-12T15:26:01.294953Z","shell.execute_reply":"2024-11-12T15:26:14.189025Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom pytorch_tabnet.tab_model import TabNetRegressor\nfrom sklearn.preprocessing import LabelEncoder, StandardScaler\nfrom sklearn.model_selection import train_test_split\nimport torch\nfrom sklearn.metrics import mean_squared_error, r2_score\nimport warnings\nwarnings.filterwarnings('ignore')\n\ndef process_time(df):\n    df['time'] = pd.to_datetime(df['time'])\n    df['hour'] = df['time'].dt.hour\n    df['minute'] = df['time'].dt.minute\n    df['second'] = df['time'].dt.second\n    return df\n\ndef encode_activities(train_df, test_df, activity_cols):\n    le = LabelEncoder()\n    all_activities = ['missing']\n    for col in activity_cols:\n        all_activities.extend(train_df[col].dropna().unique())\n        if test_df is not None:\n            all_activities.extend(test_df[col].dropna().unique())\n    \n    le.fit(list(set(all_activities)))\n    \n    for col in activity_cols:\n        train_df[col] = train_df[col].fillna('missing')\n        train_df[col] = le.transform(train_df[col])\n        if test_df is not None:\n            test_df[col] = test_df[col].fillna('missing')\n            test_df[col] = le.transform(test_df[col])\n    \n    return train_df, test_df\n\ndef prepare_data(train_path, test_path=None):\n    train_df = pd.read_csv(train_path)\n    test_df = pd.read_csv(test_path) if test_path else None\n    train_df = process_time(train_df)\n    if test_df is not None:\n        test_df = process_time(test_df)\n    \n    # Identify column types\n    bg_cols = [col for col in train_df.columns if col.startswith('bg-')]\n    insulin_cols = [col for col in train_df.columns if col.startswith('insulin-')]\n    carbs_cols = [col for col in train_df.columns if col.startswith('carbs-')]\n    hr_cols = [col for col in train_df.columns if col.startswith('hr-')]\n    steps_cols = [col for col in train_df.columns if col.startswith('steps-')]\n    cals_cols = [col for col in train_df.columns if col.startswith('cals-')]\n    activity_cols = [col for col in train_df.columns if col.startswith('activity-')]\n    \n    print(\"Handling missing values...\")\n    # Handle missing numerical values\n    numerical_cols = bg_cols + insulin_cols + carbs_cols + hr_cols + steps_cols + cals_cols\n    for col in numerical_cols:\n        train_df[col] = train_df[col].fillna(train_df[col].mean())\n        if test_df is not None:\n            test_df[col] = test_df[col].fillna(train_df[col].mean())\n    \n    print(\"Encoding activities...\")\n    # Encode activities\n    train_df, test_df = encode_activities(train_df, test_df, activity_cols)\n    \n    print(\"Scaling features...\")\n    # Scale numerical features\n    scaler = StandardScaler()\n    train_df[numerical_cols] = scaler.fit_transform(train_df[numerical_cols])\n    if test_df is not None:\n        test_df[numerical_cols] = scaler.transform(test_df[numerical_cols])\n    \n    #feature columns\n    feature_cols = (bg_cols + insulin_cols + carbs_cols + hr_cols + steps_cols + \n                   cals_cols + activity_cols + ['hour', 'minute', 'second'])\n    \n    X_train = train_df[feature_cols].values\n    y_train = train_df['bg+1:00'].values.reshape(-1, 1)  \n    \n    if test_df is not None:\n        X_test = test_df[feature_cols].values\n        return X_train, y_train, X_test, feature_cols\n    else:\n        return X_train, y_train, None, feature_cols\n\ndef train_tabnet(X_train, y_train, patience=20, max_epochs=300):\n    # Split data for validation\n    X_train_split, X_val, y_train_split, y_val = train_test_split(\n        X_train, y_train, test_size=0.2, random_state=42\n    )\n    \n    # Initialize tabnet\n    model = TabNetRegressor(\n        n_d=64,\n        n_a=64,\n        n_steps=5,\n        gamma=1.5,\n        n_independent=2,\n        n_shared=2,\n        optimizer_fn=torch.optim.Adam,\n        optimizer_params=dict(lr=1e-2),\n        mask_type='entmax',\n        lambda_sparse=1e-3,\n        scheduler_params=dict(\n            mode=\"min\",\n            patience=patience//2,\n            min_lr=1e-5,\n            factor=0.5,\n        ),\n        scheduler_fn=torch.optim.lr_scheduler.ReduceLROnPlateau,\n        verbose=10\n    )\n    \n    # Train \n    model.fit(\n        X_train_split, y_train_split,\n        eval_set=[(X_val, y_val)],\n        max_epochs=max_epochs,\n        patience=patience,\n        batch_size=1024,\n        virtual_batch_size=128,\n        num_workers=0,\n        drop_last=False\n    )\n    \n    return model\n\ndef main():\n  \n    X_train, y_train, X_test, feature_cols = prepare_data('/kaggle/input/brist1d/train.csv', '/kaggle/input/brist1d/test.csv')\n    \n    print(f\"Data shapes: X_train: {X_train.shape}, y_train: {y_train.shape}\")\n    \n    model = train_tabnet(X_train, y_train)\n    \n    print(\"Making predictions...\")\n    #predictions\n    preds = model.predict(X_test)\n    \n  \n    test_df = pd.read_csv('/kaggle/input/brist1d/test.csv')\n    submission = pd.DataFrame({\n        'id': test_df['id'],\n        'bg+1:00': preds.squeeze()  # Convert back to 1D array for submission\n    })\n    submission.to_csv('submission.csv', index=False)\n    \n    # Evaluate on validation set\n    X_train_split, X_val, y_train_split, y_val = train_test_split(\n        X_train, y_train, test_size=0.2, random_state=42\n    )\n    val_preds = model.predict(X_val)\n    \n    print(\"\\nValidation Metrics:\")\n    print(\"RMSE:\", np.sqrt(mean_squared_error(y_val, val_preds)))\n    print(\"R2 Score:\", r2_score(y_val, val_preds))\n\nif __name__ == \"__main__\":\n    main()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-12T17:08:36.470219Z","iopub.execute_input":"2024-11-12T17:08:36.470659Z","iopub.status.idle":"2024-11-12T18:03:16.682128Z","shell.execute_reply.started":"2024-11-12T17:08:36.470616Z","shell.execute_reply":"2024-11-12T18:03:16.681116Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}