{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":50160,"databundleVersionId":7921029,"sourceType":"competition"}],"dockerImageVersionId":30635,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Home Credit, САД 2024 ПМИ ВШЭ\n\nАнтон Андрущенко, группа 202\n\n## Загрузка данных + EDA + Feature Engineering\n\nВ этой секции создадим несколько новых, не имеющихся на данный момент признаков. Также здесь будет небольшой EDA для обоснования создания таких признаков. Рассмотрим не все таблицы и очень малое количество признаков, чтобы не распыляться","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"code","source":"!pip3 install optuna","metadata":{"execution":{"iopub.status.busy":"2024-03-18T20:04:52.609920Z","iopub.execute_input":"2024-03-18T20:04:52.610456Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import polars as pl\nimport numpy as np\nimport pandas as pd\nimport lightgbm as lgb\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import roc_auc_score \n\ndataPath = \"/kaggle/input/home-credit-credit-risk-model-stability/\"\ntrainPath = \"/kaggle/input/home-credit-credit-risk-model-stability/parquet_files/train/\"\ntestPath = \"/kaggle/input/home-credit-credit-risk-model-stability/parquet_files/test/\"","metadata":{"execution":{"iopub.status.busy":"2024-03-18T18:47:22.969322Z","iopub.execute_input":"2024-03-18T18:47:22.969678Z","iopub.status.idle":"2024-03-18T18:47:22.975996Z","shell.execute_reply.started":"2024-03-18T18:47:22.969649Z","shell.execute_reply":"2024-03-18T18:47:22.974892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# This is a helper function for converting columns to Polars dtypes\n# Based on this public kernel: https://www.kaggle.com/code/eliocordeiropereira/the-starter-notebook-thoroughly-explained\n\ndef set_table_dtypes(df: pl.DataFrame) -> pl.DataFrame:\n    df = df.with_columns(pl.col('case_id').cast(pl.Int64).alias('case_id'))\n\n    for col in df.columns:\n        if col[-1] in (\"P\", \"A\"):\n            df = df.with_columns(pl.col(col).cast(pl.Float64).alias(col))\n        if col[-1] in (\"M\"):\n            df = df.with_columns(pl.col(col).cast(pl.Categorical))\n        if col[-1] in (\"D\"):\n            df = df.with_columns(pl.col(col).cast(pl.Date))\n        if col[-1] in (\"L\", \"T\"):\n            if df.schema[col] == pl.String:\n                df = df.with_columns(pl.col(col).cast(pl.Categorical).alias(col))\n\n    return df\n\n\ndef fill_null_common(df: pl.DataFrame) -> pl.DataFrame:\n    for col, dtype in df.schema.items():\n        if dtype != pl.Categorical and dtype != pl.Date:\n            df = df.with_columns(pl.col(col).fill_null(0).alias(col))\n\n    return df\n\n\ndef drop_date_columns(df: pl.DataFrame) -> pl.DataFrame:\n    return df.select([\n        col for col in df.columns if col[-1] != 'D'\n    ])\n    \n    \ndef preprocess(df: pl.DataFrame) -> pl.DataFrame:\n    return fill_null_common(drop_date_columns(set_table_dtypes(df)))\n\n\n# This is a helper function for printing descriptions for table columns\n\nfeature_definitions = pl.read_csv(dataPath + 'feature_definitions.csv')\n\ndef explain_table(df: pl.DataFrame, transform_types: tuple[str] = tuple()) -> pl.DataFrame:\n    transforms = {\n        'P': 'Transform DPD (days past due)',\n        'M': 'Masking categories',\n        'A': 'Transform amount',\n        'D': 'Transform date',\n        'T': 'Unspecified transform',\n        'L': 'Unspecified transform',\n    }\n\n    explanation = pl.DataFrame({\n        'Variable': df.columns,\n        'Dtype': df.dtypes,\n    }).join(\n        feature_definitions, how='left', on='Variable'\n    ).filter(~pl.col('Description').is_null())\n    \n    with pl.Config(fmt_str_lengths=100, tbl_rows=-1, tbl_formatting=\"UTF8_FULL\"):\n        if transform_types:\n            print(explanation.filter(pl.col('Variable').str.slice(-1).is_in(transform_types)))\n        else:\n            print(explanation)","metadata":{"execution":{"iopub.status.busy":"2024-03-18T18:47:22.978156Z","iopub.execute_input":"2024-03-18T18:47:22.978632Z","iopub.status.idle":"2024-03-18T18:47:23.068474Z","shell.execute_reply.started":"2024-03-18T18:47:22.978585Z","shell.execute_reply":"2024-03-18T18:47:23.067391Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Гипотеза 1 - зависимость таргета от возраста на момент принятия решения","metadata":{}},{"cell_type":"code","source":"train_basetable = pl.read_parquet(dataPath + \"parquet_files/train/train_base.parquet\")\n\ntrain_static = pl.concat(\n    [\n        pl.read_parquet(trainPath + \"train_static_0_0.parquet\").pipe(set_table_dtypes),\n        pl.read_parquet(trainPath+ \"train_static_0_1.parquet\").pipe(set_table_dtypes),\n    ],\n    how=\"vertical_relaxed\",\n)","metadata":{"execution":{"iopub.status.busy":"2024-03-18T12:56:02.549584Z","iopub.execute_input":"2024-03-18T12:56:02.552504Z","iopub.status.idle":"2024-03-18T12:56:11.060342Z","shell.execute_reply.started":"2024-03-18T12:56:02.552355Z","shell.execute_reply":"2024-03-18T12:56:11.058661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_person_1 = pl.read_parquet(trainPath + \"train_person_1.parquet\").pipe(set_table_dtypes)","metadata":{"execution":{"iopub.status.busy":"2024-03-18T13:15:42.193773Z","iopub.execute_input":"2024-03-18T13:15:42.194246Z","iopub.status.idle":"2024-03-18T13:15:46.443551Z","shell.execute_reply.started":"2024-03-18T13:15:42.194212Z","shell.execute_reply":"2024-03-18T13:15:46.442136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bd_df = train_person_1.join(train_basetable, how='left', on='case_id').with_columns(\n    (pl.col('date_decision').cast(pl.Date).dt.year().mean() - pl.col('birth_259D').dt.year()).alias('years_on_decision_date')\n).group_by('years_on_decision_date').agg(\n    pl.col('target').mean().alias('tgt_mean'),\n)","metadata":{"execution":{"iopub.status.busy":"2024-03-18T15:59:11.833974Z","iopub.execute_input":"2024-03-18T15:59:11.834486Z","iopub.status.idle":"2024-03-18T15:59:13.198913Z","shell.execute_reply.started":"2024-03-18T15:59:11.834451Z","shell.execute_reply":"2024-03-18T15:59:13.197817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"_, ax = plt.subplots(figsize=(9, 6))\nax.set_title('Зависимость вероятности дефолта от среднего возраста кредитуемых')\nax.set_xlabel('Количество полных лет на момент совершения сделки')\nax.set_ylabel('Доля дефолтов')\n\nsns.lineplot(bd_df,x='years_on_decision_date', y='tgt_mean', ax=ax)","metadata":{"execution":{"iopub.status.busy":"2024-03-18T15:59:13.684928Z","iopub.execute_input":"2024-03-18T15:59:13.685848Z","iopub.status.idle":"2024-03-18T15:59:14.146472Z","shell.execute_reply.started":"2024-03-18T15:59:13.685805Z","shell.execute_reply":"2024-03-18T15:59:14.144762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Видим достаточно существенное и при этом стабильное снижение вероятности дефолта с возрастом кредитуемого примерно до 65 лет, а затем небольшой рост. Рост после 65 лет можно достаточно легко объяснить утратой трудоспособности, а снижение вероятности дефолта до этого возраста - ростом доходов и накоплений. При этом возраст на момент совершения сделки - более стабильная метрика, чем дата рождения, применительно к данным в будущем. Возьмем такой признак.","metadata":{}},{"cell_type":"markdown","source":"## Загрузка и предобработка данных","metadata":{}},{"cell_type":"markdown","source":"### Обучающая выборка","metadata":{}},{"cell_type":"code","source":"train_basetable = pl.read_parquet(trainPath + 'train_base.parquet').with_columns(\n    pl.col('case_id').cast(pl.Int64).alias('case_id'),\n    pl.col('date_decision').cast(pl.Date).alias('date_decision')\n)\n\ntrain_static = pl.concat(\n    [\n        pl.read_parquet(trainPath + \"train_static_0_0.parquet\"),\n        pl.read_parquet(trainPath+ \"train_static_0_1.parquet\"),\n    ],\n    how=\"vertical_relaxed\",\n).pipe(preprocess)\n\ntrain_static_cb = pl.read_parquet(trainPath + 'train_static_cb_0.parquet').pipe(preprocess)\n\ntrain_other = pl.read_parquet(trainPath + 'train_other_1.parquet').pipe(preprocess)\ntrain_other = train_other.group_by('case_id').agg(*[\n    pl.col(col).sum().alias(col) for col in train_other.columns if col[-1] == 'A'\n])\n\ntrain_tax_registry_a = pl.read_parquet(trainPath + 'train_tax_registry_a_1.parquet').pipe(preprocess).group_by('case_id').agg(\n    pl.col('amount_4527230A').mean().alias('amount_4527230A')\n)\ntrain_tax_registry_b = pl.read_parquet(trainPath + 'train_tax_registry_b_1.parquet').pipe(preprocess).group_by('case_id').agg(\n    pl.col('amount_4917619A').mean().alias('amount_4917619A')\n)\ntrain_tax_registry_c = pl.read_parquet(trainPath + 'train_tax_registry_c_1.parquet').pipe(preprocess).group_by('case_id').agg(\n    pl.col('pmtamount_36A').mean().alias('pmtamount_36A')\n)\n\ntrain_debitcard = pl.read_parquet(trainPath + 'train_debitcard_1.parquet').pipe(preprocess)\ntrain_debitcard = train_debitcard.group_by('case_id').agg(*[\n    pl.col(col).sum().alias(col) for col in train_debitcard.columns if col[-1] == 'A'\n])\n\ntrain_deposit = pl.read_parquet(trainPath + 'train_deposit_1.parquet').pipe(set_table_dtypes).pipe(fill_null_common).join(\n    train_basetable.select(['case_id', 'date_decision']), how='left', on='case_id'\n)\ntrain_deposit = train_deposit.group_by('case_id').agg(\n    pl.col('amount_416A').sum().alias('amount_416A'),\n    (pl.col('contractenddate_991D').fill_null(pl.col('date_decision')) - pl.col('openingdate_313D')).dt.total_days().floordiv(30).max().alias('months_active'),\n    (pl.col('amount_416A') * (pl.col('contractenddate_991D').fill_null(pl.col('date_decision')) - pl.col('openingdate_313D')).dt.total_days().floordiv(30)).sum().alias('duration_by_amount')\n)\n\ntrain_person_1 = pl.read_parquet(trainPath + \"train_person_1.parquet\").pipe(set_table_dtypes)\ntrain_person_1 = train_person_1.filter(pl.col('num_group1') == 0).join(\n    train_basetable, how='left', on='case_id'\n).select([\n    'case_id',\n    (pl.col('date_decision') - pl.col('birth_259D')).dt.total_days().floordiv(365).alias('full_years_by_decision_date')\n])\n\ndata = train_basetable.join(\n    train_static, how='left', on='case_id'\n).join(\n    train_static_cb, how='left', on='case_id'\n).join(\n    train_person_1, how='left', on='case_id'\n).join(\n    train_tax_registry_a, how='left', on='case_id'\n).join(\n    train_tax_registry_b, how='left', on='case_id'\n).join(\n    train_tax_registry_c, how='left', on='case_id'\n).join(\n    train_other, how='left', on='case_id'\n).join(\n    train_debitcard, how='left', on='case_id'\n).join(\n    train_deposit, how='left', on='case_id'\n)","metadata":{"execution":{"iopub.status.busy":"2024-03-18T18:47:41.761506Z","iopub.execute_input":"2024-03-18T18:47:41.761971Z","iopub.status.idle":"2024-03-18T18:48:08.334185Z","shell.execute_reply.started":"2024-03-18T18:47:41.761938Z","shell.execute_reply":"2024-03-18T18:48:08.333129Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Тестовая выборка","metadata":{}},{"cell_type":"code","source":"test_basetable = pl.read_parquet(testPath + 'test_base.parquet').with_columns(\n    pl.col('case_id').cast(pl.Int64).alias('case_id'),\n    pl.col('date_decision').cast(pl.Date).alias('date_decision')\n)\n\ntest_static = pl.concat(\n    [\n        pl.read_parquet(testPath + \"test_static_0_0.parquet\"),\n        pl.read_parquet(testPath + \"test_static_0_1.parquet\"),\n        pl.read_parquet(testPath + \"test_static_0_2.parquet\"),\n    ],\n    how=\"vertical_relaxed\",\n).pipe(preprocess)\n\ntest_static_cb = pl.read_parquet(testPath + 'test_static_cb_0.parquet').pipe(preprocess)\n\ntest_other = pl.read_parquet(testPath + 'test_other_1.parquet').pipe(preprocess)\ntest_other = test_other.group_by('case_id').agg(*[\n    pl.col(col).sum().alias(col) for col in test_other.columns if col[-1] == 'A'\n])\n\ntest_tax_registry_a = pl.read_parquet(testPath + 'test_tax_registry_a_1.parquet').pipe(preprocess).group_by('case_id').agg(\n    pl.col('amount_4527230A').mean().alias('amount_4527230A')\n)\ntest_tax_registry_b = pl.read_parquet(testPath + 'test_tax_registry_b_1.parquet').pipe(preprocess).group_by('case_id').agg(\n    pl.col('amount_4917619A').mean().alias('amount_4917619A')\n)\ntest_tax_registry_c = pl.read_parquet(testPath + 'test_tax_registry_c_1.parquet').pipe(preprocess).group_by('case_id').agg(\n    pl.col('pmtamount_36A').mean().alias('pmtamount_36A')\n)\n\ntest_debitcard = pl.read_parquet(testPath + 'test_debitcard_1.parquet').pipe(preprocess)\ntest_debitcard = test_debitcard.group_by('case_id').agg(*[\n    pl.col(col).sum().alias(col) for col in test_debitcard.columns if col[-1] == 'A'\n])\n\ntest_deposit = pl.read_parquet(testPath + 'test_deposit_1.parquet').pipe(set_table_dtypes).pipe(fill_null_common).join(\n    test_basetable.select(['case_id', 'date_decision']), how='left', on='case_id'\n)\ntest_deposit = test_deposit.group_by('case_id').agg(\n    pl.col('amount_416A').sum().alias('amount_416A'),\n    (pl.col('contractenddate_991D').fill_null(pl.col('date_decision')) - pl.col('openingdate_313D')).dt.total_days().floordiv(30).max().alias('months_active'),\n    (pl.col('amount_416A') * (pl.col('contractenddate_991D').fill_null(pl.col('date_decision')) - pl.col('openingdate_313D')).dt.total_days().floordiv(30)).sum().alias('duration_by_amount')\n)\n\ntest_person_1 = pl.read_parquet(testPath + \"test_person_1.parquet\").pipe(set_table_dtypes)\ntest_person_1 = test_person_1.filter(pl.col('num_group1') == 0).join(\n    test_basetable, how='left', on='case_id'\n).select([\n    'case_id',\n    (pl.col('date_decision') - pl.col('birth_259D')).dt.total_days().floordiv(365).alias('full_years_by_decision_date')\n])\n\ntest_data = test_basetable.join(\n    test_static, how='left', on='case_id'\n).join(\n    test_static_cb, how='left', on='case_id'\n).join(\n    test_person_1, how='left', on='case_id'\n).join(\n    test_tax_registry_a, how='left', on='case_id'\n).join(\n    test_tax_registry_b, how='left', on='case_id'\n).join(\n    test_tax_registry_c, how='left', on='case_id'\n).join(\n    test_other, how='left', on='case_id'\n).join(\n    test_debitcard, how='left', on='case_id'\n).join(\n    test_deposit, how='left', on='case_id'\n)","metadata":{"execution":{"iopub.status.busy":"2024-03-18T18:48:08.336381Z","iopub.execute_input":"2024-03-18T18:48:08.336824Z","iopub.status.idle":"2024-03-18T18:48:08.595486Z","shell.execute_reply.started":"2024-03-18T18:48:08.336785Z","shell.execute_reply":"2024-03-18T18:48:08.594125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Обучение модели","metadata":{}},{"cell_type":"code","source":"def convert_strings(df: pd.DataFrame) -> pd.DataFrame:\n    for col in df.columns:  \n        if df[col].dtype.name in ['object', 'string']:\n            df[col] = df[col].astype(\"string\").astype('category')\n            current_categories = df[col].cat.categories\n            new_categories = current_categories.to_list() + [\"Unknown\"]\n            new_dtype = pd.CategoricalDtype(categories=new_categories, ordered=True)\n            df[col] = df[col].astype(new_dtype)\n    return df\n\ncase_ids = data[\"case_id\"].unique().shuffle(seed=1)\ncase_ids_train, case_ids_test = train_test_split(case_ids, train_size=0.6, random_state=1)\ncase_ids_valid, case_ids_hyp = train_test_split(case_ids_test, train_size=0.5, random_state=1)\n\ncols_pred = []\nfor col in data.columns:\n    if col[-1].isupper() and col[:-1].islower():\n        cols_pred.append(col)\n\nprint(cols_pred)\n\ndef from_polars_to_pandas(case_ids: pl.DataFrame) -> pl.DataFrame:\n    return (\n        data.filter(pl.col(\"case_id\").is_in(case_ids))[[\"case_id\", \"WEEK_NUM\", \"target\"]].to_pandas(),\n        data.filter(pl.col(\"case_id\").is_in(case_ids))[cols_pred].to_pandas(),\n        data.filter(pl.col(\"case_id\").is_in(case_ids))[\"target\"].to_pandas()\n    )\n\nbase_train, X_train, y_train = from_polars_to_pandas(case_ids_train)\nbase_valid, X_valid, y_valid = from_polars_to_pandas(case_ids_valid)\nbase_test, X_hyp, y_hyp = from_polars_to_pandas(case_ids_hyp)\n\nfor df in [X_train, X_valid, X_hyp]:\n    df = convert_strings(df)","metadata":{"execution":{"iopub.status.busy":"2024-03-18T19:52:33.411095Z","iopub.execute_input":"2024-03-18T19:52:33.412585Z","iopub.status.idle":"2024-03-18T19:52:41.345280Z","shell.execute_reply.started":"2024-03-18T19:52:33.412523Z","shell.execute_reply":"2024-03-18T19:52:41.343880Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Train: {X_train.shape}\")\nprint(f\"Valid: {X_valid.shape}\")\nprint(f\"Hyp: {X_hyp.shape}\")","metadata":{"execution":{"iopub.status.busy":"2024-03-18T19:52:58.556264Z","iopub.execute_input":"2024-03-18T19:52:58.556755Z","iopub.status.idle":"2024-03-18T19:52:58.563972Z","shell.execute_reply.started":"2024-03-18T19:52:58.556718Z","shell.execute_reply":"2024-03-18T19:52:58.562597Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import optuna\n\nlgb_train = lgb.Dataset(X_train, label=y_train)\nlgb_valid = lgb.Dataset(X_valid, label=y_valid, reference=lgb_train)\nlgb_hyp = lgb.Dataset(X_hyp, label=y_hyp, reference=lgb_train)\n\ndef objective(trial):\n    params = {\n        \"boosting_type\": \"gbdt\",\n        \"objective\": \"binary\",\n        \"metric\": \"auc\",\n        \"max_depth\": trial.suggest_int(\"max_depth\", 2, 5),\n        \"num_leaves\": trial.suggest_int(\"num_leaves\", 10, 51),\n        \"learning_rate\": trial.suggest_float(\"learning_rate\", 0.03, 0.06, log=True),\n        \"feature_fraction\": trial.suggest_float(\"feature_fraction\", 0.7, 0.99, log=True),\n        \"bagging_fraction\": trial.suggest_float(\"bagging_fraction\", 0.7, 0.9, log=True),\n        \"bagging_freq\": trial.suggest_int(\"bagging_freq\", 3, 7),\n        \"n_estimators\": 1000,\n        \"verbose\": -1,\n    }\n\n    gbm = lgb.train(\n        params,\n        lgb_hyp,\n        valid_sets=lgb_valid,\n        callbacks=[lgb.log_evaluation(50), lgb.early_stopping(10)]\n    )\n    preds = gbm.predict(X_valid, num_iteration=gbm.best_iteration)\n    return roc_auc_score(base_valid[\"target\"], preds)\n\nstudy = optuna.create_study(direction=\"maximize\")\nstudy.optimize(objective, n_trials=5)","metadata":{"execution":{"iopub.status.busy":"2024-03-18T19:54:06.778634Z","iopub.execute_input":"2024-03-18T19:54:06.779164Z","iopub.status.idle":"2024-03-18T19:57:33.091103Z","shell.execute_reply.started":"2024-03-18T19:54:06.779123Z","shell.execute_reply":"2024-03-18T19:57:33.089817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"params = {\n    \"boosting_type\": \"gbdt\",\n    \"objective\": \"binary\",\n    \"metric\": \"auc\",\n    \"n_estimators\": 1000,\n    \"verbose\": -1,\n}\nparams.update(**study.best_trial.params)\n\ngbm = lgb.train(\n    params,\n    lgb_train,\n    valid_sets=lgb_valid,\n    callbacks=[lgb.log_evaluation(50), lgb.early_stopping(10)]\n)","metadata":{"execution":{"iopub.status.busy":"2024-03-18T19:59:25.125535Z","iopub.execute_input":"2024-03-18T19:59:25.126040Z","iopub.status.idle":"2024-03-18T20:01:43.772039Z","shell.execute_reply.started":"2024-03-18T19:59:25.125986Z","shell.execute_reply":"2024-03-18T20:01:43.770646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Сабмит","metadata":{}},{"cell_type":"code","source":"X_submission = test_data[cols_pred].to_pandas()\nX_submission = convert_strings(X_submission)\ncategorical_cols = X_train.select_dtypes(include=['category']).columns\n\nfor col in categorical_cols:\n    X_submission[col] = X_submission[col].astype('string').astype('category')\n    X_submission[col] = X_submission[col].astype(pd.CategoricalDtype(categories=(X_submission[col].cat.categories.to_list() + ['Unknown']), ordered=True))\n    train_categories = set(X_train[col].cat.categories)\n    submission_categories = set(X_submission[col].cat.categories)\n    new_categories = submission_categories - train_categories\n    X_submission.loc[X_submission[col].isin(new_categories), col] = \"Unknown\"\n    new_dtype = pd.CategoricalDtype(categories=train_categories, ordered=True)\n    X_train[col] = X_train[col].astype(new_dtype)\n    X_submission[col] = X_submission[col].astype(new_dtype)\n        \n\ny_submission_pred = gbm.predict(X_submission, num_iteration=gbm.best_iteration)","metadata":{"execution":{"iopub.status.busy":"2024-03-18T20:01:43.774557Z","iopub.execute_input":"2024-03-18T20:01:43.775656Z","iopub.status.idle":"2024-03-18T20:01:43.999813Z","shell.execute_reply.started":"2024-03-18T20:01:43.775607Z","shell.execute_reply":"2024-03-18T20:01:43.998832Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.DataFrame({\n    \"case_id\": test_data[\"case_id\"].to_numpy(),\n    \"score\": y_submission_pred\n}).set_index('case_id')\nsubmission.to_csv(\"./submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2024-03-18T20:01:44.001311Z","iopub.execute_input":"2024-03-18T20:01:44.002377Z","iopub.status.idle":"2024-03-18T20:01:44.013447Z","shell.execute_reply.started":"2024-03-18T20:01:44.002328Z","shell.execute_reply":"2024-03-18T20:01:44.012362Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}