{"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":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":30822,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:12:34.071839Z","iopub.execute_input":"2025-04-02T03:12:34.072234Z","iopub.status.idle":"2025-04-02T03:12:34.517776Z","shell.execute_reply.started":"2025-04-02T03:12:34.072190Z","shell.execute_reply":"2025-04-02T03:12:34.516458Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Hello and welcome to the notebook.\n- ### In this notebook we will train a SVM classifer using one-versus-all learning to classify the ten handwritten digits in the MNIST dataset.\n- ### One-versus-all since SVM classifiers are binary classifiers.","metadata":{}},{"cell_type":"markdown","source":"# Let me shorlty summarize one-versus-all learning before we begin.\n-  Some algorithms (such as Random Forest classifiers or naive Bayes classifiers) are capable of handling multiple classes directly. Others (such as Support Vector Machine classifiers or Linear classifiers) are strictly binary classifiers. However, there are various strategies that you can use to perform multiclass classification using multiple binary classifiers.\n-  For example, one way to create a system that can classify the digit images into 10 classes (from 0 to 9) is to train 10 binary classifiers, one for each digit (a 0-detector, a 1-detector, a 2-detector, and so on). Then when you want to classify an image, you get the decision score from each classifier for that image and you select the class whose classifier outputs the highest score. This is called the one-versus-all (OvA) strategy (also called one-versus-the-rest).\n-  Another strategy is to train a binary classifier for every pair of digits: one to distinguish 0s and 1s, another to distinguish 0s and 2s, another for 1s and 2s, and so on. This is called the one-versus-one (OvO) strategy. If there are N classes, you need to train N × (N – 1) / 2 classifiers. For the MNIST problem, this means training 45 binary classifiers! When you want to classify an image, you have to run the image through all 45 classifiers and see which class wins the most duels. The main advantage of OvO is that each classifier only needs to be trained on the part of the training set for the two classes that it must distinguish.","metadata":{}},{"cell_type":"markdown","source":"# Let's quickly understand why SVMs are strictly binary classifiers\n\n- Support Vector Machines (SVMs) are inherently designed for binary classification tasks, aiming to distinguish between two distinct classes by constructing an optimal hyperplane that maximizes the margin between them. This optimal hyperplane is determined by the support vectors, which are the data points closest to the decision boundary. The primary objective is to find a hyperplane that not only separates the classes but does so with the maximum possible margin, enhancing the model's generalization capabilities.\n- In scenarios where data from different classes are not linearly separable, SVMs employ kernel functions. These functions transform the original feature space into a higher-dimensional space where a linear separation becomes feasible. Common kernels include polynomial, radial basis function (RBF), and sigmoid, each enabling the SVM to handle complex, non-linear relationships within the data.\n","metadata":{}},{"cell_type":"markdown","source":"# In this notebook I will introduce you to a new package by Sk-learn, `skore`.\n- `skore` is a Python open-source library designed to help data scientists apply recommended practices and avoid common methodological pitfalls in scikit-learn.\n\n### In this notebook we will be using the `skore.EstimatorReport`.\n- `skore.EstimatorReport`: feed your scikit-learn compatible estimator and dataset, and it generates recommended metrics, feature importance, and plots to help you evaluate and inspect your estimator. All these are computed and generated for you in 1 line of code. Under the hood, we use efficient caching to make the computations blazing fast.","metadata":{}},{"cell_type":"code","source":"!pip install --upgrade scikit-learn","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:26:48.744262Z","iopub.execute_input":"2025-04-02T03:26:48.744630Z","iopub.status.idle":"2025-04-02T03:27:00.406139Z","shell.execute_reply.started":"2025-04-02T03:26:48.744600Z","shell.execute_reply":"2025-04-02T03:27:00.404552Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Let's install an important package for evaluation\n! pip install -U skore -q","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:00.408043Z","iopub.execute_input":"2025-04-02T03:27:00.408390Z","iopub.status.idle":"2025-04-02T03:27:05.833063Z","shell.execute_reply.started":"2025-04-02T03:27:00.408360Z","shell.execute_reply":"2025-04-02T03:27:05.831746Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Let's now import the data\n\ntrain_data = pd.read_csv(\"/kaggle/input/digit-recognizer/train.csv\")\ntrain_data.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:05.835472Z","iopub.execute_input":"2025-04-02T03:27:05.835866Z","iopub.status.idle":"2025-04-02T03:27:09.723799Z","shell.execute_reply.started":"2025-04-02T03:27:05.835832Z","shell.execute_reply":"2025-04-02T03:27:09.722655Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"len(train_data)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:09.725490Z","iopub.execute_input":"2025-04-02T03:27:09.725802Z","iopub.status.idle":"2025-04-02T03:27:09.731734Z","shell.execute_reply.started":"2025-04-02T03:27:09.725773Z","shell.execute_reply":"2025-04-02T03:27:09.730558Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y = train_data[\"label\"]\nx = train_data.drop(columns=['label'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:09.732963Z","iopub.execute_input":"2025-04-02T03:27:09.733333Z","iopub.status.idle":"2025-04-02T03:27:09.887602Z","shell.execute_reply.started":"2025-04-02T03:27:09.733290Z","shell.execute_reply":"2025-04-02T03:27:09.886386Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:09.888963Z","iopub.execute_input":"2025-04-02T03:27:09.889420Z","iopub.status.idle":"2025-04-02T03:27:09.896829Z","shell.execute_reply.started":"2025-04-02T03:27:09.889381Z","shell.execute_reply":"2025-04-02T03:27:09.895663Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Let's have a look at the training data\nx.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:09.898127Z","iopub.execute_input":"2025-04-02T03:27:09.898406Z","iopub.status.idle":"2025-04-02T03:27:09.933220Z","shell.execute_reply.started":"2025-04-02T03:27:09.898383Z","shell.execute_reply":"2025-04-02T03:27:09.932089Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:09.935945Z","iopub.execute_input":"2025-04-02T03:27:09.936283Z","iopub.status.idle":"2025-04-02T03:27:10.481519Z","shell.execute_reply.started":"2025-04-02T03:27:09.936251Z","shell.execute_reply":"2025-04-02T03:27:10.480246Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# First, split into train (60%) and temp (40%)\nx_train, x_temp, y_train, y_temp = train_test_split(x, y, test_size=0.4, random_state=42)\n\n# Then, split temp into CV (20%) and test (20%)\nx_cv, x_test, y_cv, y_test = train_test_split(x_temp, y_temp, test_size=0.5, random_state=42)\n\n# Print dataset sizes\nprint(f\"Train size: {len(x_train)}, CV size: {len(x_cv)}, Test size: {len(x_test)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:10.482949Z","iopub.execute_input":"2025-04-02T03:27:10.483433Z","iopub.status.idle":"2025-04-02T03:27:10.872529Z","shell.execute_reply.started":"2025-04-02T03:27:10.483404Z","shell.execute_reply":"2025-04-02T03:27:10.871031Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Let's process the data\nfrom sklearn.preprocessing import StandardScaler","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:10.873873Z","iopub.execute_input":"2025-04-02T03:27:10.874339Z","iopub.status.idle":"2025-04-02T03:27:10.879268Z","shell.execute_reply.started":"2025-04-02T03:27:10.874297Z","shell.execute_reply":"2025-04-02T03:27:10.878087Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"std = StandardScaler()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:10.880385Z","iopub.execute_input":"2025-04-02T03:27:10.880672Z","iopub.status.idle":"2025-04-02T03:27:10.904572Z","shell.execute_reply.started":"2025-04-02T03:27:10.880648Z","shell.execute_reply":"2025-04-02T03:27:10.903301Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_train_transformed = std.fit_transform(x_train)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:10.905783Z","iopub.execute_input":"2025-04-02T03:27:10.906170Z","iopub.status.idle":"2025-04-02T03:27:11.332590Z","shell.execute_reply.started":"2025-04-02T03:27:10.906110Z","shell.execute_reply":"2025-04-02T03:27:11.331327Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_cv_transformed = std.transform(x_cv)\nx_test_transformed = std.transform(x_test)\n\nx_train_transformed.shape, x_cv_transformed.shape, x_test_transformed.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:11.334361Z","iopub.execute_input":"2025-04-02T03:27:11.334806Z","iopub.status.idle":"2025-04-02T03:27:11.435180Z","shell.execute_reply.started":"2025-04-02T03:27:11.334745Z","shell.execute_reply":"2025-04-02T03:27:11.433724Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.pipeline import Pipeline","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:11.436566Z","iopub.execute_input":"2025-04-02T03:27:11.436895Z","iopub.status.idle":"2025-04-02T03:27:11.445581Z","shell.execute_reply.started":"2025-04-02T03:27:11.436866Z","shell.execute_reply":"2025-04-02T03:27:11.444026Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.svm import SVC","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:11.447555Z","iopub.execute_input":"2025-04-02T03:27:11.448411Z","iopub.status.idle":"2025-04-02T03:27:11.617523Z","shell.execute_reply.started":"2025-04-02T03:27:11.448357Z","shell.execute_reply":"2025-04-02T03:27:11.616448Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.multiclass import OneVsRestClassifier","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:11.618572Z","iopub.execute_input":"2025-04-02T03:27:11.619044Z","iopub.status.idle":"2025-04-02T03:27:11.627312Z","shell.execute_reply.started":"2025-04-02T03:27:11.619009Z","shell.execute_reply":"2025-04-02T03:27:11.625837Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Wrap the SVC model inside OneVsRestClassifier\nrbf_kernel_svm_clf = OneVsRestClassifier(SVC(kernel=\"rbf\", gamma='scale', C=1))\n\n# Fit the model\nrbf_kernel_svm_clf.fit(x_train_transformed, y_train)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:27:11.628695Z","iopub.execute_input":"2025-04-02T03:27:11.629173Z","iopub.status.idle":"2025-04-02T03:34:30.644429Z","shell.execute_reply.started":"2025-04-02T03:27:11.629119Z","shell.execute_reply":"2025-04-02T03:34:30.643079Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Check how many classifiers were trained\nprint(f\"Number of classifiers trained: {len(rbf_kernel_svm_clf.estimators_)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:34:30.645652Z","iopub.execute_input":"2025-04-02T03:34:30.646313Z","iopub.status.idle":"2025-04-02T03:34:30.651952Z","shell.execute_reply.started":"2025-04-02T03:34:30.646274Z","shell.execute_reply":"2025-04-02T03:34:30.650533Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Let's use skore's estimator report to get the report for our `OneVsRestClassifier`","metadata":{}},{"cell_type":"code","source":"import skore","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:34:30.655520Z","iopub.execute_input":"2025-04-02T03:34:30.655827Z","iopub.status.idle":"2025-04-02T03:34:31.248378Z","shell.execute_reply.started":"2025-04-02T03:34:30.655801Z","shell.execute_reply":"2025-04-02T03:34:31.247305Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from skore import EstimatorReport","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:34:31.249821Z","iopub.execute_input":"2025-04-02T03:34:31.250466Z","iopub.status.idle":"2025-04-02T03:34:31.255534Z","shell.execute_reply.started":"2025-04-02T03:34:31.250432Z","shell.execute_reply":"2025-04-02T03:34:31.254224Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"report = EstimatorReport(rbf_kernel_svm_clf, X_train=x_train_transformed, X_test=x_cv_transformed,y_train=y_train, y_test=y_cv)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:34:31.256591Z","iopub.execute_input":"2025-04-02T03:34:31.256870Z","iopub.status.idle":"2025-04-02T03:34:31.348010Z","shell.execute_reply.started":"2025-04-02T03:34:31.256845Z","shell.execute_reply":"2025-04-02T03:34:31.346847Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"report.metrics.report_metrics()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:34:31.349123Z","iopub.execute_input":"2025-04-02T03:34:31.349404Z","iopub.status.idle":"2025-04-02T03:37:28.959289Z","shell.execute_reply.started":"2025-04-02T03:34:31.349380Z","shell.execute_reply":"2025-04-02T03:37:28.957617Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"report.metrics.accuracy()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:37:28.960438Z","iopub.execute_input":"2025-04-02T03:37:28.960827Z","iopub.status.idle":"2025-04-02T03:37:28.969624Z","shell.execute_reply.started":"2025-04-02T03:37:28.960788Z","shell.execute_reply":"2025-04-02T03:37:28.968417Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Ohh, we are getting 95% accuracy without any hyper-parameter tuning, Great!!\n\n## You can use the `report.metrics.help()` command to view all the available metrics methods.","metadata":{}},{"cell_type":"code","source":"report.metrics.help()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:37:28.970598Z","iopub.execute_input":"2025-04-02T03:37:28.970897Z","iopub.status.idle":"2025-04-02T03:37:28.997420Z","shell.execute_reply.started":"2025-04-02T03:37:28.970854Z","shell.execute_reply":"2025-04-02T03:37:28.996362Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Let's use the `report.metrics.roc()` command to plot the ROC-AUC curve.","metadata":{}},{"cell_type":"code","source":"roc_display = report.metrics.roc()\nroc_display.plot()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:37:28.998387Z","iopub.execute_input":"2025-04-02T03:37:28.998688Z","iopub.status.idle":"2025-04-02T03:40:37.574508Z","shell.execute_reply.started":"2025-04-02T03:37:28.998661Z","shell.execute_reply":"2025-04-02T03:40:37.573095Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Let's see the final statistics on the test data \nrbf_kernel_svm_clf.score(x_test_transformed, y_test)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:40:37.575697Z","iopub.execute_input":"2025-04-02T03:40:37.576052Z","iopub.status.idle":"2025-04-02T03:43:45.749226Z","shell.execute_reply.started":"2025-04-02T03:40:37.576021Z","shell.execute_reply":"2025-04-02T03:43:45.748005Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Let's see if a kernelized SVM will do better. We will use a default SVC and not the OvR classifier. Since SVC's are strictly binary classifiers ","metadata":{}},{"cell_type":"code","source":"from sklearn.svm import SVC","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:43:45.750419Z","iopub.execute_input":"2025-04-02T03:43:45.750839Z","iopub.status.idle":"2025-04-02T03:43:45.755558Z","shell.execute_reply.started":"2025-04-02T03:43:45.750800Z","shell.execute_reply":"2025-04-02T03:43:45.754515Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.pipeline import make_pipeline\nfrom sklearn.model_selection import cross_val_score","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:43:45.756796Z","iopub.execute_input":"2025-04-02T03:43:45.757172Z","iopub.status.idle":"2025-04-02T03:43:45.781290Z","shell.execute_reply.started":"2025-04-02T03:43:45.757123Z","shell.execute_reply":"2025-04-02T03:43:45.779932Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"svm_clf = make_pipeline(StandardScaler(), SVC(random_state=42))\ncross_val_score(svm_clf, x_train_transformed, y_train).mean()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:43:45.782490Z","iopub.execute_input":"2025-04-02T03:43:45.782779Z","iopub.status.idle":"2025-04-02T03:53:20.850553Z","shell.execute_reply.started":"2025-04-02T03:43:45.782755Z","shell.execute_reply":"2025-04-02T03:53:20.849502Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"report2 = EstimatorReport(svm_clf, X_train=x_train_transformed, X_test=x_cv_transformed,y_train=y_train, y_test=y_cv)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:53:20.851599Z","iopub.execute_input":"2025-04-02T03:53:20.851878Z","iopub.status.idle":"2025-04-02T03:55:15.072602Z","shell.execute_reply.started":"2025-04-02T03:53:20.851844Z","shell.execute_reply":"2025-04-02T03:55:15.071277Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"report2.metrics.report_metrics()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:55:15.073784Z","iopub.execute_input":"2025-04-02T03:55:15.074202Z","iopub.status.idle":"2025-04-02T03:56:19.145087Z","shell.execute_reply.started":"2025-04-02T03:55:15.074160Z","shell.execute_reply":"2025-04-02T03:56:19.143856Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"report2.metrics.accuracy()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:56:19.146287Z","iopub.execute_input":"2025-04-02T03:56:19.146654Z","iopub.status.idle":"2025-04-02T03:56:19.155554Z","shell.execute_reply.started":"2025-04-02T03:56:19.146625Z","shell.execute_reply":"2025-04-02T03:56:19.154406Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Let's see if we can do better with some hyper-param tuning\nfrom sklearn.model_selection import GridSearchCV","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T03:56:19.156580Z","iopub.execute_input":"2025-04-02T03:56:19.157007Z","iopub.status.idle":"2025-04-02T03:56:19.172895Z","shell.execute_reply.started":"2025-04-02T03:56:19.156962Z","shell.execute_reply":"2025-04-02T03:56:19.171675Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"param_distrib = {\n    \"svc__gamma\": [0.001, 0.01, 0.1],\n    \"svc__C\": [1, 3, 5]\n}\ngrd_search_cv = GridSearchCV(svm_clf, param_distrib, scoring='accuracy', cv=3, n_jobs=-1)\ngrd_search_cv.fit(x_train_transformed, y_train)\ngrd_search_cv.best_estimator_","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T04:29:55.206516Z","iopub.execute_input":"2025-04-02T04:29:55.206877Z","iopub.status.idle":"2025-04-02T05:37:44.576808Z","shell.execute_reply.started":"2025-04-02T04:29:55.206849Z","shell.execute_reply":"2025-04-02T05:37:44.575385Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Let's check the results of the best estimator!\n\ngrd_search_cv.best_estimator_.score(x_test_transformed, y_test)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-02T05:57:34.956604Z","iopub.execute_input":"2025-04-02T05:57:34.957076Z","iopub.status.idle":"2025-04-02T05:58:34.963682Z","shell.execute_reply.started":"2025-04-02T05:57:34.957043Z","shell.execute_reply":"2025-04-02T05:58:34.962248Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}