{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"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":"none","dataSources":[{"sourceId":81933,"databundleVersionId":9643020,"sourceType":"competition"}],"dockerImageVersionId":30761,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Starter Notebook: Multi-Target Prediction Using CatBoost\n\nSee [this discussion](https://www.kaggle.com/competitions/child-mind-institute-problematic-internet-use/discussion/535121) for more information.","metadata":{}},{"cell_type":"code","source":"import warnings\nfrom functools import partial\nfrom pathlib import Path\nfrom scipy.optimize import minimize\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport optuna\nimport pandas as pd\npd.set_option('display.max_columns', None)\nimport polars as pl\nimport polars.selectors as cs\nfrom catboost import CatBoostRegressor, MultiTargetCustomMetric\nfrom numpy.typing import ArrayLike, NDArray\nfrom polars.testing import assert_frame_equal\nfrom sklearn.base import BaseEstimator\nfrom sklearn.metrics import cohen_kappa_score\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.metrics import mean_squared_error\n\nfrom colorama import Fore, Style, init;\ndef PrintColor(text:str, color = Fore.CYAN, style = Style.BRIGHT):\n    \"Prints color outputs using colorama using a text F-string\";\n    print(style + color + text + Style.RESET_ALL);\n\nwarnings.filterwarnings(\"ignore\", message=\"Failed to optimize method\")\n\nDATA_DIR = Path(\"/kaggle/input/child-mind-institute-problematic-internet-use\")\nTARGET_COLS = [\n    \"PCIAT-PCIAT_01\",\n    \"PCIAT-PCIAT_02\",\n    \"PCIAT-PCIAT_03\",\n    \"PCIAT-PCIAT_04\",\n    \"PCIAT-PCIAT_05\",\n    \"PCIAT-PCIAT_06\",\n    \"PCIAT-PCIAT_07\",\n    \"PCIAT-PCIAT_08\",\n    \"PCIAT-PCIAT_09\",\n    \"PCIAT-PCIAT_10\",\n    \"PCIAT-PCIAT_11\",\n    \"PCIAT-PCIAT_12\",\n    \"PCIAT-PCIAT_13\",\n    \"PCIAT-PCIAT_14\",\n    \"PCIAT-PCIAT_15\",\n    \"PCIAT-PCIAT_16\",\n    \"PCIAT-PCIAT_17\",\n    \"PCIAT-PCIAT_18\",\n    \"PCIAT-PCIAT_19\",\n    \"PCIAT-PCIAT_20\",\n    \"PCIAT-PCIAT_Total\",\n    \"sii\",\n]\n\nFEATURE_COLS = [\n    \"Basic_Demos-Enroll_Season\",\n    \"Basic_Demos-Age\",\n    \"Basic_Demos-Sex\",\n    \"CGAS-Season\",\n    \"CGAS-CGAS_Score\",\n    \"Physical-Season\",\n    \"Physical-BMI\",\n    \"Physical-Height\",\n    \"Physical-Weight\",\n    \"Physical-Waist_Circumference\",\n    \"Physical-Diastolic_BP\",\n    \"Physical-HeartRate\",\n    \"Physical-Systolic_BP\",\n    \"Fitness_Endurance-Season\",\n    \"Fitness_Endurance-Max_Stage\",\n    \"Fitness_Endurance-Time_Mins\",\n    \"Fitness_Endurance-Time_Sec\",\n    \"FGC-Season\",\n    \"FGC-FGC_CU\",\n    \"FGC-FGC_CU_Zone\",\n    \"FGC-FGC_GSND\",\n    \"FGC-FGC_GSND_Zone\",\n    \"FGC-FGC_GSD\",\n    \"FGC-FGC_GSD_Zone\",\n    \"FGC-FGC_PU\",\n    \"FGC-FGC_PU_Zone\",\n    \"FGC-FGC_SRL\",\n    \"FGC-FGC_SRL_Zone\",\n    \"FGC-FGC_SRR\",\n    \"FGC-FGC_SRR_Zone\",\n    \"FGC-FGC_TL\",\n    \"FGC-FGC_TL_Zone\",\n    \"BIA-Season\",\n    \"BIA-BIA_Activity_Level_num\",\n    \"BIA-BIA_BMC\",\n    \"BIA-BIA_BMI\",\n    \"BIA-BIA_BMR\",\n    \"BIA-BIA_DEE\",\n    \"BIA-BIA_ECW\",\n    \"BIA-BIA_FFM\",\n    \"BIA-BIA_FFMI\",\n    \"BIA-BIA_FMI\",\n    \"BIA-BIA_Fat\",\n    \"BIA-BIA_Frame_num\",\n    \"BIA-BIA_ICW\",\n    \"BIA-BIA_LDM\",\n    \"BIA-BIA_LST\",\n    \"BIA-BIA_SMM\",\n    \"BIA-BIA_TBW\",\n    \"PAQ_A-Season\",\n    \"PAQ_A-PAQ_A_Total\",\n    \"PAQ_C-Season\",\n    \"PAQ_C-PAQ_C_Total\",\n    \"SDS-Season\",\n    \"SDS-SDS_Total_Raw\",\n    \"SDS-SDS_Total_T\",\n    \"PreInt_EduHx-Season\",\n    \"PreInt_EduHx-computerinternet_hoursday\",\n] + [\n    'BMI_Age',\n    'Internet_Hours_Age',\n    'BMI_Internet_Hours',\n    'BFP_BMI',\n    'FFMI_BFP',\n    'FMI_BFP',\n    'LST_TBW',\n    'BFP_BMR',\n    'BFP_DEE',\n    'BMR_Weight',\n    'DEE_Weight',\n    'SMM_Height',\n    'Muscle_to_Fat',\n    'Hydration_Status',\n    'ICW_TBW'\n]\n\nFEATURE_COLS = [x for x in FEATURE_COLS if \"Season\" not in x]\nFEATURE_COLS = ['CGAS-CGAS_Score', 'PreInt_EduHx-computerinternet_hoursday', \"Basic_Demos-Age\", \"SDS-SDS_Total_Raw\", \"SDS-SDS_Total_T\", \"Basic_Demos-Sex\"]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T04:52:50.010393Z","iopub.execute_input":"2024-12-15T04:52:50.010862Z","iopub.status.idle":"2024-12-15T04:52:53.28954Z","shell.execute_reply.started":"2024-12-15T04:52:50.01082Z","shell.execute_reply":"2024-12-15T04:52:53.288153Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load data\ntrain = pl.read_csv(DATA_DIR / \"train.csv\")\ntest = pl.read_csv(DATA_DIR / \"test.csv\")\ntrain_test = pl.concat([train, test], how=\"diagonal\")\n\ndef feature_engineer(df: pl.DataFrame) -> pl.DataFrame:\n    \"\"\"\n    Perform feature engineering on the input DataFrame using Polars.\n    \n    Args:\n        df: Input Polars DataFrame\n        \n    Returns:\n        Polars DataFrame with engineered features\n    \"\"\"\n    # Drop season columns\n    season_cols = [col for col in df.columns if 'Season' in col]\n    df = df.drop(season_cols)\n    \n    # Create new features using Polars expressions\n    return df.with_columns([\n        (pl.col('Physical-BMI') * pl.col('Basic_Demos-Age')).alias('BMI_Age'),\n        (pl.col('PreInt_EduHx-computerinternet_hoursday') * pl.col('Basic_Demos-Age')).alias('Internet_Hours_Age'),\n        (pl.col('Physical-BMI') * pl.col('PreInt_EduHx-computerinternet_hoursday')).alias('BMI_Internet_Hours'),\n        (pl.col('BIA-BIA_Fat') / pl.col('BIA-BIA_BMI')).alias('BFP_BMI'),\n        (pl.col('BIA-BIA_FFMI') / pl.col('BIA-BIA_Fat')).alias('FFMI_BFP'),\n        (pl.col('BIA-BIA_FMI') / pl.col('BIA-BIA_Fat')).alias('FMI_BFP'),\n        (pl.col('BIA-BIA_LST') / pl.col('BIA-BIA_TBW')).alias('LST_TBW'),\n        (pl.col('BIA-BIA_Fat') * pl.col('BIA-BIA_BMR')).alias('BFP_BMR'),\n        (pl.col('BIA-BIA_Fat') * pl.col('BIA-BIA_DEE')).alias('BFP_DEE'),\n        (pl.col('BIA-BIA_BMR') / pl.col('Physical-Weight')).alias('BMR_Weight'),\n        (pl.col('BIA-BIA_DEE') / pl.col('Physical-Weight')).alias('DEE_Weight'),\n        (pl.col('BIA-BIA_SMM') / pl.col('Physical-Height')).alias('SMM_Height'),\n        (pl.col('BIA-BIA_SMM') / pl.col('BIA-BIA_FMI')).alias('Muscle_to_Fat'),\n        (pl.col('BIA-BIA_TBW') / pl.col('Physical-Weight')).alias('Hydration_Status'),\n        (pl.col('BIA-BIA_ICW') / pl.col('BIA-BIA_TBW')).alias('ICW_TBW')\n    ])\n\ntrain_test = feature_engineer(train_test)\n\nIS_TEST = False #test.height <= 100\n\n#assert_frame_equal(train, train_test[: train.height].select(train.columns))\n#assert_frame_equal(test, train_test[train.height :].select(test.columns))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T04:52:53.29225Z","iopub.execute_input":"2024-12-15T04:52:53.292926Z","iopub.status.idle":"2024-12-15T04:52:53.482223Z","shell.execute_reply.started":"2024-12-15T04:52:53.292872Z","shell.execute_reply":"2024-12-15T04:52:53.481177Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Cast string columns to categorical\ntrain_test = train_test.with_columns(cs.string().cast(pl.Categorical).fill_null(\"NAN\"))\ntrain = train_test[: train.height]\ntest = train_test[train.height :]\n\n#display(train)\n#display(test)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T04:52:53.483562Z","iopub.execute_input":"2024-12-15T04:52:53.483916Z","iopub.status.idle":"2024-12-15T04:52:53.545837Z","shell.execute_reply.started":"2024-12-15T04:52:53.483884Z","shell.execute_reply":"2024-12-15T04:52:53.544641Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ignore rows with null values in TARGET_COLS\ntrain_without_null = train_test.drop_nulls(subset=TARGET_COLS).to_pandas()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T04:52:53.548066Z","iopub.execute_input":"2024-12-15T04:52:53.548455Z","iopub.status.idle":"2024-12-15T04:52:53.607621Z","shell.execute_reply.started":"2024-12-15T04:52:53.548421Z","shell.execute_reply":"2024-12-15T04:52:53.606352Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_test = test[FEATURE_COLS].to_pandas()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T04:52:53.608848Z","iopub.execute_input":"2024-12-15T04:52:53.609271Z","iopub.status.idle":"2024-12-15T04:52:53.624641Z","shell.execute_reply.started":"2024-12-15T04:52:53.609218Z","shell.execute_reply":"2024-12-15T04:52:53.623058Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.impute import KNNImputer\n\n# Create and fit KNN imputer on training data\nimputer = KNNImputer(n_neighbors=5)\n\n# Impute and assign back to original training dataframe\ntrain_without_null[FEATURE_COLS] = imputer.fit_transform(train_without_null[FEATURE_COLS])\n\n# Transform and assign back to original test dataframe\nX_test[FEATURE_COLS] = imputer.transform(X_test[FEATURE_COLS])","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_without_null","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T04:52:53.626208Z","iopub.execute_input":"2024-12-15T04:52:53.626773Z","iopub.status.idle":"2024-12-15T04:52:53.729988Z","shell.execute_reply.started":"2024-12-15T04:52:53.626722Z","shell.execute_reply":"2024-12-15T04:52:53.728687Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_without_null[train_without_null.sii == 3]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T04:52:53.731654Z","iopub.execute_input":"2024-12-15T04:52:53.732132Z","iopub.status.idle":"2024-12-15T04:52:53.905418Z","shell.execute_reply.started":"2024-12-15T04:52:53.732061Z","shell.execute_reply":"2024-12-15T04:52:53.90397Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# EDA","metadata":{}},{"cell_type":"code","source":"models = {i: [] for i in range(1, 21)}\nfor tidx in range(1, 21):\n    # ignore rows with null values in TARGET_COLS\n    X = train_without_null[FEATURE_COLS]\n    y = train_without_null[f\"PCIAT-PCIAT_{str(tidx).zfill(2)}\"]\n    y_sii = train_without_null['sii']\n    cat_features = []\n\n    # setting catboost parameters\n    # Cross-validation\n    skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=52)\n    y_pred = np.zeros(len(X))\n    seeds = [42, 43, 44, 45, 46]\n    \n    for seed in seeds:\n        #params = dict(\n            #loss_function=\"RMSE\",\n            #eval_metric=\"RMSE\",\n            #iterations=100000,\n            #learning_rate=0.1,\n            #early_stopping_rounds=50,\n            #depth=5,\n            #random_state=seed,\n        #)\n\n        #params = {'iterations': 10000, 'depth': 3, 'learning_rate': 0.24625232085431073, 'l2_leaf_reg': 0.42465367950915395, 'random_strength': 0.13499449813680028, 'border_count': 64, 'bootstrap_type': 'Bayesian', 'loss_function': 'RMSE', 'eval_metric': 'RMSE', 'task_type': 'CPU', 'random_seed': seed, 'use_best_model': True, 'early_stopping_rounds': 50, 'bagging_temperature': 6.92996396534111}\n        params = {'iterations': 10000, 'depth': 4, 'learning_rate': 0.20597827850583297, 'l2_leaf_reg': 0.03481077044958598, 'random_strength': 2.0329330471327958, 'border_count': 182, 'bootstrap_type': 'MVS', 'loss_function': 'RMSE', 'eval_metric': 'RMSE', 'task_type': 'CPU', 'random_seed': seed, 'use_best_model': True, 'early_stopping_rounds': 50}\n        print(\"=\" * 30)\n        print(params)\n        \n        for train_idx, val_idx in skf.split(X, y_sii):\n            X_train: pl.DataFrame\n            X_val: pl.DataFrame\n            y_train: pl.DataFrame\n            y_val: pl.DataFrame\n            X_train, X_val = X.iloc[train_idx], X.iloc[val_idx]\n            y_train, y_val = y.iloc[train_idx], y.iloc[val_idx]\n        \n            # train model\n            print(X_train.shape)\n            model = CatBoostRegressor(**params)\n            model.fit(\n                X_train,\n                y_train,\n                eval_set=(X_val, y_val),\n                cat_features=cat_features,\n                verbose=False,\n            )\n            models[tidx].append(model)\n        \n            # predict\n            y_pred[val_idx] += model.predict(X_val) / len(seeds)\n\n    train_without_null[f\"PCIAT-PCIAT_{str(tidx).zfill(2)}_pred\"] = y_pred\n    #FEATURE_COLS.append(f\"PCIAT-PCIAT_{str(tidx).zfill(2)}_pred\")\n    PrintColor(f\"RMSE of PCIAT-PCIAT_{str(tidx).zfill(2)}: {mean_squared_error(train_without_null[f'PCIAT-PCIAT_{str(tidx).zfill(2)}_pred'], train_without_null[f'PCIAT-PCIAT_{str(tidx).zfill(2)}'], squared=False)}\", color=Fore.MAGENTA)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T04:52:53.908902Z","iopub.execute_input":"2024-12-15T04:52:53.909282Z","iopub.status.idle":"2024-12-15T04:53:47.944585Z","shell.execute_reply.started":"2024-12-15T04:52:53.909248Z","shell.execute_reply":"2024-12-15T04:53:47.94334Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def quadratic_weighted_kappa(y_true, y_pred):\n    return cohen_kappa_score(y_true, y_pred, weights='quadratic')\n    \ndef threshold_Rounder(oof_non_rounded, thresholds):\n    return np.where(oof_non_rounded < thresholds[0], 0,\n                    np.where(oof_non_rounded < thresholds[1], 1,\n                             np.where(oof_non_rounded < thresholds[2], 2, 3)))\n\ndef evaluate_predictions(thresholds, y_true, oof_non_rounded):\n    rounded_p = threshold_Rounder(oof_non_rounded, thresholds)\n    return -quadratic_weighted_kappa(y_true, rounded_p)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T04:53:47.946178Z","iopub.execute_input":"2024-12-15T04:53:47.946621Z","iopub.status.idle":"2024-12-15T04:53:47.954936Z","shell.execute_reply.started":"2024-12-15T04:53:47.946571Z","shell.execute_reply":"2024-12-15T04:53:47.953656Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_without_null[\"PCIAT-PCIAT_mean_pred\"] = train_without_null[[f\"PCIAT-PCIAT_{str(x).zfill(2)}_pred\" for x in range(1, 21)]].mean(axis=1)\n\n#display(train_without_null)\nassert np.isnan(y_pred).sum() == 0\n\ny_pred_total = train_without_null[\"PCIAT-PCIAT_mean_pred\"]\n#optimizer.fit(y_pred_total, y_sii)\n#y_pred_rounded = optimizer.predict(y_pred_total)\n\noof_mask = train_without_null[\"PCIAT-PCIAT_mean_pred\"].notna()\noof_initial_thresholds = train_without_null.loc[oof_mask].groupby('sii')[\"PCIAT-PCIAT_mean_pred\"].mean().iloc[1:].values.tolist()\nprint(oof_initial_thresholds)\n\noof_optimized_thresholds = minimize(\n    evaluate_predictions,\n    x0=oof_initial_thresholds,\n    args=(train_without_null.loc[oof_mask, 'sii'], train_without_null.loc[oof_mask, \"PCIAT-PCIAT_mean_pred\"]),\n    method='Nelder-Mead'\n).x\noof_optimized_thresholds = [x-0.05 for x in oof_optimized_thresholds]\nprint(oof_optimized_thresholds)\n\ntrain_without_null[\"PCIAT-PCIAT_mean_pred\"] = threshold_Rounder(train_without_null[\"PCIAT-PCIAT_mean_pred\"], oof_optimized_thresholds)\n#display(train_without_null)\n\ntrain_without_null[\"sii\"] = y_sii\ntrain_without_null.to_csv(\"oof.csv\", index=False)\n\n# Calculate QWK\nqwk = cohen_kappa_score(y_sii, train_without_null[\"PCIAT-PCIAT_mean_pred\"], weights=\"quadratic\")\nprint(f\"Cross-Validated QWK Score: {qwk}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T04:59:44.051069Z","iopub.execute_input":"2024-12-15T04:59:44.051514Z","iopub.status.idle":"2024-12-15T04:59:44.678285Z","shell.execute_reply.started":"2024-12-15T04:59:44.051476Z","shell.execute_reply":"2024-12-15T04:59:44.677187Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#train_without_null['sii'] = -1\n#train_without_null['sii'] = np.where((train_without_null['sum'] < 31), 0, train_without_null['sii'])\n#train_without_null['sii'] = np.where((train_without_null['sum'] >= 31) & (train_without_null['sum'] < 50), 1, train_without_null['sii'])\n#train_without_null['sii'] = np.where((train_without_null['sum'] >= 50) & (train_without_null['sum'] < 80), 2, train_without_null['sii'])\n#train_without_null['sii'] = np.where((train_without_null['sum'] >= 80), 3, train_without_null['sii'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T04:53:48.934347Z","iopub.status.idle":"2024-12-15T04:53:48.934729Z","shell.execute_reply.started":"2024-12-15T04:53:48.934545Z","shell.execute_reply":"2024-12-15T04:53:48.934563Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_without_null[\"PCIAT-PCIAT_mean_pred\"].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T04:59:50.007229Z","iopub.execute_input":"2024-12-15T04:59:50.00777Z","iopub.status.idle":"2024-12-15T04:59:50.022382Z","shell.execute_reply.started":"2024-12-15T04:59:50.007725Z","shell.execute_reply":"2024-12-15T04:59:50.020979Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class AvgModel:\n    def __init__(self, models: list[BaseEstimator]):\n        self.models = models\n\n    def predict(self, X: ArrayLike) -> NDArray[np.int_]:\n        preds: list[NDArray[np.int_]] = []\n        print(len(self.models))\n        print(X.shape)\n        for model in self.models:\n            pred = model.predict(X)\n            preds.append(pred)\n\n        return np.mean(preds, axis=0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T04:53:48.938345Z","iopub.status.idle":"2024-12-15T04:53:48.938724Z","shell.execute_reply.started":"2024-12-15T04:53:48.938549Z","shell.execute_reply":"2024-12-15T04:53:48.938567Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for tidx in range(1, 21):\n    avg_model = AvgModel(models[tidx])\n    test_pred = avg_model.predict(X_test[FEATURE_COLS])\n    X_test[f\"PCIAT-PCIAT_{str(tidx).zfill(2)}_pred\"] = test_pred\n\nX_test[\"PCIAT-PCIAT_mean_pred\"] = X_test[[f\"PCIAT-PCIAT_{str(x).zfill(2)}_pred\" for x in range(1, 21)]].mean(axis=1)\n#display(X_test)\nprint(oof_optimized_thresholds)\nX_test[\"PCIAT-PCIAT_mean_pred\"] = threshold_Rounder(X_test[\"PCIAT-PCIAT_mean_pred\"], oof_optimized_thresholds)\n\ntest.select(\"id\").with_columns(\n    pl.Series(\"sii\", pl.Series(\"sii\", X_test[\"PCIAT-PCIAT_mean_pred\"])),\n).write_csv(\"submission.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T04:53:48.939861Z","iopub.status.idle":"2024-12-15T04:53:48.940266Z","shell.execute_reply.started":"2024-12-15T04:53:48.940048Z","shell.execute_reply":"2024-12-15T04:53:48.940066Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pd.read_csv(\"submission.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T04:53:48.942266Z","iopub.status.idle":"2024-12-15T04:53:48.942662Z","shell.execute_reply.started":"2024-12-15T04:53:48.942475Z","shell.execute_reply":"2024-12-15T04:53:48.942495Z"}},"outputs":[],"execution_count":null}]}