{"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":30787,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"from tqdm import tqdm\nfrom itertools import product\n\nimport numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom sklearn.model_selection import GroupKFold\nfrom sklearn.impute import SimpleImputer, KNNImputer\n\n# Import necessary libraries\nfrom sklearn.linear_model import Ridge  # Meta-learner\nfrom sklearn.ensemble import StackingRegressor\nimport warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-24T14:22:24.357126Z","iopub.execute_input":"2024-11-24T14:22:24.357498Z","iopub.status.idle":"2024-11-24T14:22:25.680078Z","shell.execute_reply.started":"2024-11-24T14:22:24.357460Z","shell.execute_reply":"2024-11-24T14:22:25.679089Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install -qq pytorch_tabnet\n\nfrom pytorch_tabnet.tab_model import TabNetRegressor","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-24T14:22:25.681394Z","iopub.execute_input":"2024-11-24T14:22:25.681786Z","iopub.status.idle":"2024-11-24T14:22:38.389259Z","shell.execute_reply.started":"2024-11-24T14:22:25.681758Z","shell.execute_reply":"2024-11-24T14:22:38.388232Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Define the hour and minute ranges for constructing feature column names\nhours = range(0, 6, 1)\nminutes = range(0, 60, 5)\n\ntarget_col = \"bg+1-00\"  # Target column name for prediction\ngroup_col = \"p_num\"  # Column name for grouping (e.g., participant number)\ndate_col = \"time\"  # Column name for time data\n\n# We only need the last 12 time intervals (1 hour)\nbg_cols = [f\"bg-{i}-{j:02d}\" for i, j in product(hours, minutes)][:12]\ninsu_cols = [f\"insulin-{i}-{j:02d}\" for i, j in product(hours, minutes)][:12]\ncarb_cols = [f\"carbs-{i}-{j:02d}\" for i, j in product(hours, minutes)][:12]\nhr_cols = [f\"hr-{i}-{j:02d}\" for i, j in product(hours, minutes)][:12]\nstep_cols = [f\"steps-{i}-{j:02d}\" for i, j in product(hours, minutes)][:12]\ncals_cols = [f\"cals-{i}-{j:02d}\" for i, j in product(hours, minutes)][:12]\n\nfeature_cols = bg_cols + insu_cols + carb_cols + hr_cols + step_cols + cals_cols\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-24T14:22:38.390488Z","iopub.execute_input":"2024-11-24T14:22:38.390937Z","iopub.status.idle":"2024-11-24T14:22:38.397742Z","shell.execute_reply.started":"2024-11-24T14:22:38.390875Z","shell.execute_reply":"2024-11-24T14:22:38.396819Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train = pd.read_csv(\n    '/kaggle/input/brist1d/train.csv', \n    index_col='id', \n    parse_dates=['time'],\n)\n\ndf_test = pd.read_csv(\n    '/kaggle/input/brist1d/test.csv', \n    index_col='id', \n    parse_dates=['time'],\n)\n\ndf_subm = pd.read_csv(\n    \"/kaggle/input/brist1d/sample_submission.csv\",\n    index_col='id',\n)\n\n# Some frameworks may not handle column names with special characters like colons properly\ndf_train.columns = df_train.columns.str.replace(':', '-')\ndf_test.columns = df_test.columns.str.replace(':', '-')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-24T14:22:38.400023Z","iopub.execute_input":"2024-11-24T14:22:38.400380Z","iopub.status.idle":"2024-11-24T14:22:49.197630Z","shell.execute_reply.started":"2024-11-24T14:22:38.400343Z","shell.execute_reply":"2024-11-24T14:22:49.196843Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import random\nimport os\nimport numpy as np\nimport torch\n\n\ndef seed_everything(seed):\n    random.seed(seed)\n    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = True","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-24T14:22:49.198609Z","iopub.execute_input":"2024-11-24T14:22:49.198846Z","iopub.status.idle":"2024-11-24T14:22:49.203940Z","shell.execute_reply.started":"2024-11-24T14:22:49.198824Z","shell.execute_reply":"2024-11-24T14:22:49.203074Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"seed = 43  #\nThr_NAN = 49\nseed_everything(seed)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-24T14:22:49.205084Z","iopub.execute_input":"2024-11-24T14:22:49.205336Z","iopub.status.idle":"2024-11-24T14:22:49.223751Z","shell.execute_reply.started":"2024-11-24T14:22:49.205312Z","shell.execute_reply":"2024-11-24T14:22:49.223045Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Some frameworks may not handle column names with special characters like colons properly\ndf_train.columns = df_train.columns.str.replace(\":\", \"-\")\ndf_test.columns = df_test.columns.str.replace(\":\", \"-\")\n\n\nfor colset in [bg_cols, insu_cols, carb_cols, hr_cols, step_cols, cals_cols]:\n    df_train[colset] = (\n        df_train[colset]\n        .interpolate(axis=1)\n        .fillna(method=\"bfill\", axis=1)\n        .fillna(method=\"ffill\", axis=1)\n    )\n    df_test[colset] = (\n        df_test[colset]\n        .interpolate(axis=1)\n        .fillna(method=\"bfill\", axis=1)\n        .fillna(method=\"ffill\", axis=1)\n    )\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-24T14:22:49.224971Z","iopub.execute_input":"2024-11-24T14:22:49.225325Z","iopub.status.idle":"2024-11-24T14:23:02.662174Z","shell.execute_reply.started":"2024-11-24T14:22:49.225291Z","shell.execute_reply":"2024-11-24T14:23:02.661301Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"mask = df_train[feature_cols].isna().sum(axis=1) <= Thr_NAN\n# Apply the mask to filter the rows\ndf_train = df_train[mask]\n\n\nimputer = SimpleImputer()  \n\ndf_train[feature_cols] = imputer.fit_transform(df_train[feature_cols])\ndf_test[feature_cols] = imputer.transform(df_test[feature_cols])\n\n\ndf_train[\"sin_hour\"] = np.sin(np.pi * df_train[date_col].dt.hour / 12)\ndf_train[\"cos_hour\"] = np.cos(np.pi * df_train[date_col].dt.hour / 12)\n\ndf_test[\"sin_hour\"] = np.sin(np.pi * df_test[date_col].dt.hour / 12)\ndf_test[\"cos_hour\"] = np.cos(np.pi * df_test[date_col].dt.hour / 12)\n\nfeature_cols.extend([\"sin_hour\", \"cos_hour\"])\n\n\ngrouped_features = []\n\n# Iterate through each set of related columns (e.g., blood glucose, insulin, etc.)\nfor colset in [bg_cols, insu_cols, carb_cols, hr_cols, step_cols, cals_cols]:\n    group_idxs = [idx for idx, col in enumerate(feature_cols) if col in colset]\n    grouped_features.append(group_idxs)\n\n\ndf_train_final = df_train[feature_cols]\ngroups = df_train[group_col]\n\ny_target = df_train[[target_col]]\n\ndf_test_final = df_test[feature_cols]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-24T14:23:02.663332Z","iopub.execute_input":"2024-11-24T14:23:02.663699Z","iopub.status.idle":"2024-11-24T14:23:03.662088Z","shell.execute_reply.started":"2024-11-24T14:23:02.663660Z","shell.execute_reply":"2024-11-24T14:23:03.661367Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Meta-learner\n\nfrom lightgbm import LGBMRegressor\nfrom xgboost import XGBRegressor\nfrom catboost import CatBoostRegressor\n\n# Define a common random seed for reproducibility\nRANDOM_SEED = 42\nN_ESTIMATORS = 3500  # Number of estimators for the ensemble models\n\n# Define base estimators with random seed and number of estimators\nestimators = [\n    ('lgbm', LGBMRegressor(\n        random_state=RANDOM_SEED,\n        n_estimators=N_ESTIMATORS,\n        device='gpu',  # LightGBM GPU 支持\n        gpu_platform_id=0,  # 如果有多个 GPU，可指定平台 ID\n        gpu_device_id=0,     # 指定具体的 GPU\n        verbose = -1\n    )),\n    ('xgb', XGBRegressor(\n        random_state=RANDOM_SEED,\n        n_estimators=N_ESTIMATORS,\n        tree_method='gpu_hist',  # XGBoost GPU 支持\n        predictor='gpu_predictor',  # 使用 GPU 预测\n        device='cuda',\n        verbosity=0\n    )),\n    ('catboost', CatBoostRegressor(\n        random_seed=RANDOM_SEED,\n        iterations=N_ESTIMATORS,\n        task_type='GPU',  # CatBoost GPU 支持\n        devices='0',  # 指定 GPU 设备\n        verbose = 0\n    ))\n]\n\nmeta_model = Ridge(alpha=0.1)\n\n# Create StackingRegressor\nstacking_model = StackingRegressor(estimators=estimators, final_estimator=meta_model)\n\n# Fit the StackingRegressor\nstacking_model.fit(df_train_final, y_target)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-24T14:23:03.663168Z","iopub.execute_input":"2024-11-24T14:23:03.663510Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nfinal_res_0 = stacking_model.predict(df_test_final)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X = df_train_final\ny = y_target\ncv = GroupKFold(5)\nfinal_res_1 = 0.0\n\nfor idx_train, idx_valid in cv.split(X, y, groups=groups):\n    \n    # Split the data into training and validation sets for the current fold\n    X_train, y_train = X.iloc[idx_train].to_numpy(), y.iloc[idx_train].to_numpy()\n    X_valid, y_valid = X.iloc[idx_valid].to_numpy(), y.iloc[idx_valid].to_numpy()\n    \n    # Initialize the TabNet Regressor model\n    reg = TabNetRegressor(\n        grouped_features=grouped_features, \n    )\n    \n    # Train the model using the training set and validate using the validation set\n    reg.fit(\n        X_train, y_train,\n        eval_set=[(X_valid, y_valid)],\n        eval_metric=['rmse'],\n        batch_size=10000,\n        patience=40,\n        max_epochs=200,\n        num_workers=4,\n    )\n    \n    # Prepare the test data and make predictions\n    X_test = df_test[feature_cols].to_numpy()\n    \n    # Aggregate the predictions across the 5 folds (averaging for ensemble)\n    final_res_1 += reg.predict(X_test)[:, 0] / 5\n    \n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# apply limit for the result here!! \ndf_subm[\"bg+1:00\"] = (final_res_0 + final_res_1)/2.\ndf_subm.to_csv(\"submission.csv\")\ndf_subm","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}