{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":102335,"databundleVersionId":12518947,"sourceType":"competition"}],"dockerImageVersionId":31040,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\npd.set_option('display.max_rows',None)\ndf=pd.read_csv(\"/kaggle/input/cmi-detect-behavior-with-sensor-data/train.csv\")\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T08:38:41.263500Z","iopub.execute_input":"2025-06-13T08:38:41.263809Z","iopub.status.idle":"2025-06-13T08:39:15.992563Z","shell.execute_reply.started":"2025-06-13T08:38:41.263787Z","shell.execute_reply":"2025-06-13T08:39:15.991872Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"demo = pd.read_csv(\"/kaggle/input/cmi-detect-behavior-with-sensor-data/train_demographics.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T08:40:24.183929Z","iopub.execute_input":"2025-06-13T08:40:24.184242Z","iopub.status.idle":"2025-06-13T08:40:24.191861Z","shell.execute_reply.started":"2025-06-13T08:40:24.184219Z","shell.execute_reply":"2025-06-13T08:40:24.191189Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport numpy as np\nimport torch\nimport torch.nn as nn\nimport pytorch_lightning as pl\nfrom torch.utils.data import Dataset, DataLoader\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.model_selection import train_test_split","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T08:40:26.403968Z","iopub.execute_input":"2025-06-13T08:40:26.404455Z","iopub.status.idle":"2025-06-13T08:40:40.736912Z","shell.execute_reply.started":"2025-06-13T08:40:26.404436Z","shell.execute_reply":"2025-06-13T08:40:40.735937Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.shape[1]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T08:40:46.989015Z","iopub.execute_input":"2025-06-13T08:40:46.989680Z","iopub.status.idle":"2025-06-13T08:40:46.994696Z","shell.execute_reply.started":"2025-06-13T08:40:46.989655Z","shell.execute_reply":"2025-06-13T08:40:46.993938Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T08:40:49.293363Z","iopub.execute_input":"2025-06-13T08:40:49.293692Z","iopub.status.idle":"2025-06-13T08:40:56.178495Z","shell.execute_reply.started":"2025-06-13T08:40:49.293672Z","shell.execute_reply":"2025-06-13T08:40:56.177772Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Orientation Data✅","metadata":{}},{"cell_type":"code","source":" import seaborn as sns\nimport matplotlib.pyplot as plt\n\nplt.figure(figsize=(12,6))\nsns.heatmap(df[['rot_x','rot_y','rot_z','rot_w']].isnull(),cbar=False,cmap='viridis')\nplt.title(\"missing values\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T08:41:01.203502Z","iopub.execute_input":"2025-06-13T08:41:01.203828Z","iopub.status.idle":"2025-06-13T08:41:03.664550Z","shell.execute_reply.started":"2025-06-13T08:41:01.203806Z","shell.execute_reply":"2025-06-13T08:41:03.663781Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"⚠️ ⚠️ The missing values are present in the middle, as our data is time series we will be using interpolation, and if the missing values are at the middle then method will be linear for interpolation","metadata":{}},{"cell_type":"code","source":"df[['rot_x','rot_y','rot_z','rot_w']]=df[['rot_x','rot_y','rot_z','rot_w']].interpolate(method=\"linear\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T08:41:06.643638Z","iopub.execute_input":"2025-06-13T08:41:06.644291Z","iopub.status.idle":"2025-06-13T08:41:06.780405Z","shell.execute_reply.started":"2025-06-13T08:41:06.644268Z","shell.execute_reply":"2025-06-13T08:41:06.779793Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Thermopile sensors✅","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(12,6))\nsns.heatmap(df[['thm_1','thm_2','thm_3','thm_4','thm_5']].isnull(),cbar=False,cmap='viridis')\nplt.title(\"missing values\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T08:41:09.123217Z","iopub.execute_input":"2025-06-13T08:41:09.124001Z","iopub.status.idle":"2025-06-13T08:41:11.721446Z","shell.execute_reply.started":"2025-06-13T08:41:09.123977Z","shell.execute_reply":"2025-06-13T08:41:11.720653Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df[['thm_1', 'thm_2', 'thm_3', 'thm_4', 'thm_5']] = df[['thm_1', 'thm_2', 'thm_3', 'thm_4', 'thm_5']].interpolate(method='linear')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T08:41:11.763528Z","iopub.execute_input":"2025-06-13T08:41:11.764104Z","iopub.status.idle":"2025-06-13T08:41:11.931507Z","shell.execute_reply.started":"2025-06-13T08:41:11.764085Z","shell.execute_reply":"2025-06-13T08:41:11.930901Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Time of Flight Sensor✅ ","metadata":{}},{"cell_type":"markdown","source":"😥😥Time of flight sensor: 320 columns, visualization is not helpful","metadata":{}},{"cell_type":"code","source":"tof_cols = [col for col in df.columns if col.startswith('tof_')]\ndf[tof_cols].corr().abs().mean().mean()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T08:41:17.343879Z","iopub.execute_input":"2025-06-13T08:41:17.344140Z","iopub.status.idle":"2025-06-13T08:43:34.572881Z","shell.execute_reply.started":"2025-06-13T08:41:17.344124Z","shell.execute_reply":"2025-06-13T08:43:34.571957Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"😇😇Low correlation mean suggests that time of flight sensors have values independent of each other, so we cannot use knn imputer.","metadata":{}},{"cell_type":"code","source":"df[tof_cols] = df[tof_cols].interpolate(method='linear', axis=0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T08:43:34.574325Z","iopub.execute_input":"2025-06-13T08:43:34.575036Z","iopub.status.idle":"2025-06-13T08:43:45.867528Z","shell.execute_reply.started":"2025-06-13T08:43:34.575015Z","shell.execute_reply":"2025-06-13T08:43:45.866952Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Imputation completed successfully✅","metadata":{}},{"cell_type":"code","source":"null=df.isnull().sum()\nprint(null)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Feature Engineering","metadata":{}},{"cell_type":"markdown","source":"**So I  will be using shared encoder, so I will perform normalization of all features, creating minimal features, encoding categorical columns**","metadata":{}},{"cell_type":"code","source":"meta=df[['sequence_id','gesture','sequence_type','subject']].drop_duplicates()\nle_gest=LabelEncoder().fit(meta['gesture'])\nle_type=LabelEncoder().fit(meta['sequence_type'])\nmeta['gesture_id']=le_gest.transform(meta['gesture'])\nmeta['binary_id']=le_type.transform(meta['sequence_type'])\nmeta=meta.merge(demo,on=\"subject\",how=\"left\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T08:43:45.868484Z","iopub.execute_input":"2025-06-13T08:43:45.868979Z","iopub.status.idle":"2025-06-13T08:43:46.087857Z","shell.execute_reply.started":"2025-06-13T08:43:45.868953Z","shell.execute_reply":"2025-06-13T08:43:46.087227Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"np.save(\"le_gest_classes.npy\", le_gest.classes_) \nnp.save(\"le_type_classes.npy\", le_type.classes_)  ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T09:45:22.951147Z","iopub.execute_input":"2025-06-13T09:45:22.951463Z","iopub.status.idle":"2025-06-13T09:45:22.956402Z","shell.execute_reply.started":"2025-06-13T09:45:22.951443Z","shell.execute_reply":"2025-06-13T09:45:22.955641Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(df.columns)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T08:46:59.465048Z","iopub.execute_input":"2025-06-13T08:46:59.465812Z","iopub.status.idle":"2025-06-13T08:46:59.470183Z","shell.execute_reply.started":"2025-06-13T08:46:59.465789Z","shell.execute_reply":"2025-06-13T08:46:59.469431Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"non_numeric_cols = ['row_id', 'sequence_id', 'sequence_counter', 'gesture', \n                    'sequence_type', 'subject', 'orientation', 'behavior']\nseqs = {}\nfor sid, grp in df.groupby('sequence_id'):\n    X = grp.drop(columns=[col for col in non_numeric_cols if col in grp.columns])\n    X = X.select_dtypes(include=np.number).values.astype(np.float32)\n    seqs[sid] = X","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T08:51:48.723844Z","iopub.execute_input":"2025-06-13T08:51:48.724451Z","iopub.status.idle":"2025-06-13T08:53:34.296054Z","shell.execute_reply.started":"2025-06-13T08:51:48.724428Z","shell.execute_reply":"2025-06-13T08:53:34.295251Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"MAX_LEN=300","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T08:54:39.769338Z","iopub.execute_input":"2025-06-13T08:54:39.770000Z","iopub.status.idle":"2025-06-13T08:54:39.773457Z","shell.execute_reply.started":"2025-06-13T08:54:39.769973Z","shell.execute_reply":"2025-06-13T08:54:39.772730Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class SeqDataset(Dataset):\n    def __init__(self,sdict,meta,max_len=MAX_LEN):\n        self.sids=list(sdict.keys())\n        self.sdict,self.meta,self.max_len=sdict,meta.set_index('sequence_id'),max_len\n    def __len__(self): return len(self.sids)\n    def __getitem__(self,idx):\n        sid=self.sids[idx]; x=self.sdict[sid]\n        L,D=x.shape\n        if L>self.max_len:\n            x=x[:self.max_len]\n        else:\n            pad=np.zeros((self.max_len-L,D),dtype=np.float32)\n            x=np.vstack([x,pad])\n        m=self.meta.loc[sid]\n        return {\n            'x':torch.tensor(x),\n            'y_bin':torch.tensor(m['binary_id'],dtype=torch.long),\n            'y_gest':torch.tensor(m['gesture_id'],dtype=torch.long),\n            'sequence_id':sid\n        }","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T09:07:04.268721Z","iopub.execute_input":"2025-06-13T09:07:04.269888Z","iopub.status.idle":"2025-06-13T09:07:04.277979Z","shell.execute_reply.started":"2025-06-13T09:07:04.269759Z","shell.execute_reply":"2025-06-13T09:07:04.277058Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sids=list(seqs)\ntr,val=train_test_split(sids,test_size=0.2,random_state=42)\ntrain_ds=SeqDataset({s:seqs[s] for s in tr},meta)\nval_ds=SeqDataset({s:seqs[s] for s in val},meta)\ntrain_loader=DataLoader(train_ds,batch_size=32,shuffle=True,num_workers=32)\nval_loader=DataLoader(val_ds,batch_size=32,num_workers=2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T09:07:07.376859Z","iopub.execute_input":"2025-06-13T09:07:07.377157Z","iopub.status.idle":"2025-06-13T09:07:07.402041Z","shell.execute_reply.started":"2025-06-13T09:07:07.377139Z","shell.execute_reply":"2025-06-13T09:07:07.401374Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Model","metadata":{}},{"cell_type":"code","source":"import torch.nn as nn\nimport pytorch_lightning as pl\n\nclass SharedTrans(pl.LightningModule):\n    def __init__(self, feat_dim, n_gest, bin_w=0.7, lr=1e-3):\n        super().__init__()\n        self.save_hyperparameters()\n\n        self.encoder = nn.TransformerEncoder(\n            nn.TransformerEncoderLayer(d_model=feat_dim, nhead=4),\n            num_layers=2\n        )\n        self.pool = nn.AdaptiveAvgPool1d(1)\n        self.head_bin = nn.Linear(feat_dim, 2)\n        self.head_gest = nn.Linear(feat_dim, n_gest)\n        self.ce = nn.CrossEntropyLoss()\n\n    def forward(self, x):\n        x = x.permute(1, 0, 2)             \n        x = self.encoder(x)\n        x = x.permute(1, 2, 0)            \n        x = self.pool(x).squeeze(-1)       \n        return self.head_bin(x), self.head_gest(x)\n\n    def training_step(self, batch, batch_idx):\n        xb, yb, yg = batch['x'], batch['y_bin'], batch['y_gest']\n        lb, lg = self(xb)\n        loss = self.hparams.bin_w * self.ce(lb, yb) + (1 - self.hparams.bin_w) * self.ce(lg, yg)\n        self.log('tr_loss', loss, prog_bar=True)\n        return loss\n\n    def validation_step(self, batch, batch_idx):\n        xb, yb, yg = batch['x'], batch['y_bin'], batch['y_gest']\n        lb, lg = self(xb)\n        loss = self.hparams.bin_w * self.ce(lb, yb) + (1 - self.hparams.bin_w) * self.ce(lg, yg)\n        self.log('val_loss', loss, prog_bar=True)\n        return loss\n\n    def configure_optimizers(self):\n        return torch.optim.Adam(self.parameters(), lr=self.hparams.lr)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T09:07:10.057266Z","iopub.execute_input":"2025-06-13T09:07:10.057554Z","iopub.status.idle":"2025-06-13T09:07:10.066748Z","shell.execute_reply.started":"2025-06-13T09:07:10.057523Z","shell.execute_reply":"2025-06-13T09:07:10.065944Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"n_gest = meta['gesture_id'].nunique() ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T09:07:13.317181Z","iopub.execute_input":"2025-06-13T09:07:13.317454Z","iopub.status.idle":"2025-06-13T09:07:13.322178Z","shell.execute_reply.started":"2025-06-13T09:07:13.317436Z","shell.execute_reply":"2025-06-13T09:07:13.321356Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"feat_dim = next(iter(seqs.values())).shape[1]\nmodel = SharedTrans(feat_dim,n_gest)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T09:07:15.187403Z","iopub.execute_input":"2025-06-13T09:07:15.187761Z","iopub.status.idle":"2025-06-13T09:07:15.234617Z","shell.execute_reply.started":"2025-06-13T09:07:15.187739Z","shell.execute_reply":"2025-06-13T09:07:15.233966Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"trainer=pl.Trainer(max_epochs=10,accelerator=\"auto\",devices=1)\ntrainer.fit(model,train_loader,val_loader)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T09:07:17.386791Z","iopub.execute_input":"2025-06-13T09:07:17.387073Z","iopub.status.idle":"2025-06-13T09:11:45.941438Z","shell.execute_reply.started":"2025-06-13T09:07:17.387054Z","shell.execute_reply":"2025-06-13T09:11:45.940632Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"trainer.save_checkpoint(\"model.ckpt\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T09:25:21.312498Z","iopub.execute_input":"2025-06-13T09:25:21.313130Z","iopub.status.idle":"2025-06-13T09:25:21.498591Z","shell.execute_reply.started":"2025-06-13T09:25:21.313102Z","shell.execute_reply":"2025-06-13T09:25:21.498029Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":" ","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_test=pd.read_csv(\"/kaggle/input/cmi-detect-behavior-with-sensor-data/test.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T09:13:53.093864Z","iopub.execute_input":"2025-06-13T09:13:53.094470Z","iopub.status.idle":"2025-06-13T09:13:53.110281Z","shell.execute_reply.started":"2025-06-13T09:13:53.094448Z","shell.execute_reply":"2025-06-13T09:13:53.109522Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_test[['rot_x','rot_y','rot_z','rot_w']] = df_test[['rot_x','rot_y','rot_z','rot_w']].interpolate(method='linear')\ndf_test[['thm_1','thm_2','thm_3','thm_4','thm_5']] = df_test[['thm_1','thm_2','thm_3','thm_4','thm_5']].interpolate(method='linear')\ntof_cols = [col for col in df_test.columns if col.startswith('tof_')]\ndf_test[tof_cols] = df_test[tof_cols].interpolate(method='linear', axis=0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T09:13:55.207676Z","iopub.execute_input":"2025-06-13T09:13:55.207957Z","iopub.status.idle":"2025-06-13T09:13:55.261833Z","shell.execute_reply.started":"2025-06-13T09:13:55.207936Z","shell.execute_reply":"2025-06-13T09:13:55.261275Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"non_numeric_cols = ['row_id', 'sequence_id', 'sequence_counter', 'gesture', \n                    'sequence_type', 'subject', 'orientation', 'behavior']\nseqs_test = {}\nfor sid, grp in df_test.groupby('sequence_id'):\n    X = grp.drop(columns=[col for col in non_numeric_cols if col in grp.columns])\n    X = X.select_dtypes(include=np.number).values.astype(np.float32)\n    seqs_test[sid] = X","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T09:16:46.989856Z","iopub.execute_input":"2025-06-13T09:16:46.990157Z","iopub.status.idle":"2025-06-13T09:16:47.193838Z","shell.execute_reply.started":"2025-06-13T09:16:46.990136Z","shell.execute_reply":"2025-06-13T09:16:47.192995Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Submission","metadata":{}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport torch\nimport torch.nn.functional as F\nfrom torch.utils.data import DataLoader\nfrom sklearn.preprocessing import LabelEncoder\nimport sys\nsys.path.append(\"/kaggle/input/cmi-detect-behavior-with-sensor-data\")\nfrom kaggle_evaluation.cmi_inference_server import CMIInferenceServer\nimport polars as pl\nle_gest = LabelEncoder()\nle_gest.classes_ = np.load(\"/kaggle/working/le_gest_classes.npy\", allow_pickle=True)\nmodel = SharedTrans.load_from_checkpoint(\"/kaggle/working/model.ckpt\")\nmodel.eval()\nmodel.to(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nMAX_LEN = 300\ndef predict(sequence: pl.DataFrame, demographics: pl.DataFrame) -> str:\n    df = sequence.to_pandas()\n    if \"sequence_id\" not in df.columns:\n        raise ValueError(\"Expected 'sequence_id' in sequence but not found.\")\n    sequence_id = df[\"sequence_id\"].iloc[0]  \n    for cols in [['rot_x','rot_y','rot_z','rot_w'], ['thm_1','thm_2','thm_3','thm_4','thm_5']]:\n        df[cols] = df[cols].interpolate(method='linear')\n    tof_cols = [col for col in df.columns if col.startswith('tof_')]\n    df[tof_cols] = df[tof_cols].interpolate(method='linear')\n    feat_cols = df.drop(columns=['row_id','sequence_id','sequence_counter','orientation'], errors='ignore')\n    feat = feat_cols.select_dtypes(include=np.number).values.astype(np.float32)\n    if feat.shape[0] >= MAX_LEN:\n        xs = feat[:MAX_LEN]\n    else:\n        pad = np.zeros((MAX_LEN - feat.shape[0], feat.shape[1]), dtype=np.float32)\n        xs = np.vstack([feat, pad])\n    x = torch.tensor(xs[None], dtype=torch.float32).to(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n    _, logits = model(x)\n    y_preds = F.softmax(logits, dim=-1).detach().cpu().numpy()\n    pred_idx = np.argmax(y_preds)\n    gesture = le_gest.inverse_transform([pred_idx])[0]\n    return gesture","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T10:29:18.795937Z","iopub.execute_input":"2025-06-13T10:29:18.796579Z","iopub.status.idle":"2025-06-13T10:29:18.905234Z","shell.execute_reply.started":"2025-06-13T10:29:18.796557Z","shell.execute_reply":"2025-06-13T10:29:18.904460Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"inference_server = CMIInferenceServer(predict)\n\nif os.getenv('KAGGLE_IS_COMPETITION_RERUN'):\n    inference_server.serve()\nelse:\n    inference_server.run_local_gateway(\n        data_paths=(\n            '/kaggle/input/cmi-detect-behavior-with-sensor-data/test.csv',\n            '/kaggle/input/cmi-detect-behavior-with-sensor-data/test_demographics.csv',\n        )\n    )\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-13T10:29:22.265334Z","iopub.execute_input":"2025-06-13T10:29:22.265587Z","iopub.status.idle":"2025-06-13T10:29:54.127526Z","shell.execute_reply.started":"2025-06-13T10:29:22.265570Z","shell.execute_reply":"2025-06-13T10:29:54.126661Z"}},"outputs":[],"execution_count":null}]}