{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"pip install tensorflow-io","metadata":{"execution":{"iopub.status.busy":"2023-06-10T16:48:06.916813Z","iopub.execute_input":"2023-06-10T16:48:06.917223Z","iopub.status.idle":"2023-06-10T16:48:40.202183Z","shell.execute_reply.started":"2023-06-10T16:48:06.917182Z","shell.execute_reply":"2023-06-10T16:48:40.200904Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:14.992084Z","iopub.execute_input":"2023-06-10T18:03:14.992377Z","iopub.status.idle":"2023-06-10T18:03:14.997392Z","shell.execute_reply.started":"2023-06-10T18:03:14.992352Z","shell.execute_reply":"2023-06-10T18:03:14.996213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport json\nimport os\nimport cv2\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Input\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.models import load_model","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:15.003007Z","iopub.execute_input":"2023-06-10T18:03:15.003323Z","iopub.status.idle":"2023-06-10T18:03:15.320353Z","shell.execute_reply.started":"2023-06-10T18:03:15.003298Z","shell.execute_reply":"2023-06-10T18:03:15.319233Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set the paths to the dataset folders\nannotations_folder = '/kaggle/input/benetech-making-graphs-accessible/train/annotations'\nimages_folder = '/kaggle/input/benetech-making-graphs-accessible/train/images'","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:15.322118Z","iopub.execute_input":"2023-06-10T18:03:15.322468Z","iopub.status.idle":"2023-06-10T18:03:15.326783Z","shell.execute_reply.started":"2023-06-10T18:03:15.322443Z","shell.execute_reply":"2023-06-10T18:03:15.325745Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Initialize lists to store the image paths and corresponding annotations\nimage_paths = []","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:15.328305Z","iopub.execute_input":"2023-06-10T18:03:15.328924Z","iopub.status.idle":"2023-06-10T18:03:15.336985Z","shell.execute_reply.started":"2023-06-10T18:03:15.328893Z","shell.execute_reply":"2023-06-10T18:03:15.336004Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Extract the required information from the annotations\nsources = []\nchart_types = []\nx_dataseries = []\ny_dataseries = []","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:15.340298Z","iopub.execute_input":"2023-06-10T18:03:15.340649Z","iopub.status.idle":"2023-06-10T18:03:15.347613Z","shell.execute_reply.started":"2023-06-10T18:03:15.340620Z","shell.execute_reply":"2023-06-10T18:03:15.346685Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Iterate over the annotations and load the images\ncount = 0  # Counter variable to keep track of the number of files read\nfor annotation_file in os.listdir(annotations_folder):\n    if count >= 2000:\n        break  # Exit the loop after reading 5000 files\n    \n    # Load the annotation file\n    with open(os.path.join(annotations_folder, annotation_file)) as f:\n        annotation = json.load(f)\n        \n    # Get the image file name from the annotation file\n    image_file = annotation_file.replace('.json', '.jpg')\n    image_path = os.path.join(images_folder, image_file)\n    image_paths.append(image_path)\n    \n    # Extract the necessary information from the annotation\n    sources.append(annotation['source'])\n    chart_types.append(annotation['chart-type'])\n    x_dataseries.append(str(annotation['data-series'][0]['x']) + \n                        ' : ' + \n                        str(annotation['data-series'][len(annotation['data-series'])-1]['x']))  # Fix the indexing here\n    y_dataseries.append(str(annotation['data-series'][0]['y']) + \n                        ' : ' + \n                        str(annotation['data-series'][len(annotation['data-series'])-1]['y']))  # Fix the indexing here\n    \n    count += 1  # Increment the counter variable\n","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:15.349077Z","iopub.execute_input":"2023-06-10T18:03:15.349474Z","iopub.status.idle":"2023-06-10T18:03:16.209013Z","shell.execute_reply.started":"2023-06-10T18:03:15.349444Z","shell.execute_reply":"2023-06-10T18:03:16.208013Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create a DataFrame from the collected data\nannotations_df = pd.DataFrame({\n    'image_path': image_paths,\n    'source': sources,\n    'chart-type': chart_types,\n    'x_dataseries': x_dataseries,\n    'y_dataseries': y_dataseries\n})","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:16.210952Z","iopub.execute_input":"2023-06-10T18:03:16.211258Z","iopub.status.idle":"2023-06-10T18:03:16.221824Z","shell.execute_reply.started":"2023-06-10T18:03:16.211230Z","shell.execute_reply":"2023-06-10T18:03:16.220684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Split the dataset into training and validation sets\ntrain_paths, val_paths, train_annotations, val_annotations = train_test_split(\n    annotations_df['image_path'], annotations_df.drop('image_path', axis=1),\n    test_size=0.2, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:16.223578Z","iopub.execute_input":"2023-06-10T18:03:16.224271Z","iopub.status.idle":"2023-06-10T18:03:16.244121Z","shell.execute_reply.started":"2023-06-10T18:03:16.224237Z","shell.execute_reply":"2023-06-10T18:03:16.243168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the desired image size\nimage_size = (256, 256)  # Adjust the size according to your needs","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:16.248233Z","iopub.execute_input":"2023-06-10T18:03:16.248499Z","iopub.status.idle":"2023-06-10T18:03:16.252672Z","shell.execute_reply.started":"2023-06-10T18:03:16.248476Z","shell.execute_reply":"2023-06-10T18:03:16.251801Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the function to load and preprocess the images with data augmentation\ndef load_image(image_path):\n    try:\n        # Load the image\n        image = cv2.imread(image_path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        \n        # Resize the image to the desired size\n        image = cv2.resize(image, image_size)\n        \n        # Apply data augmentation\n        # Example: Random horizontal flip\n        if np.random.rand() < 0.5:\n            image = cv2.flip(image, 1)\n        \n        # Normalize pixel values to [0, 1]\n        image = image / 255.0\n        \n        return image\n    except Exception as e:\n        print(f\"Error loading image: {image_path}\")\n        print(e)\n        return None","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:16.253901Z","iopub.execute_input":"2023-06-10T18:03:16.254672Z","iopub.status.idle":"2023-06-10T18:03:16.264242Z","shell.execute_reply.started":"2023-06-10T18:03:16.254640Z","shell.execute_reply":"2023-06-10T18:03:16.263326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load and preprocess the training images with data augmentation\ntrain_images = np.array([load_image(path) for path in train_paths])","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:16.265529Z","iopub.execute_input":"2023-06-10T18:03:16.265989Z","iopub.status.idle":"2023-06-10T18:03:16.745663Z","shell.execute_reply.started":"2023-06-10T18:03:16.265957Z","shell.execute_reply":"2023-06-10T18:03:16.744691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load and preprocess the validation images\nval_images = np.array([load_image(path) for path in val_paths])","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:16.750353Z","iopub.execute_input":"2023-06-10T18:03:16.753062Z","iopub.status.idle":"2023-06-10T18:03:16.883205Z","shell.execute_reply.started":"2023-06-10T18:03:16.753025Z","shell.execute_reply":"2023-06-10T18:03:16.881942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Convert the labels to one-hot encoded vectors\nchart_type_labels = pd.get_dummies(annotations_df['chart-type'])\nx_dataseries_labels = pd.get_dummies(annotations_df['x_dataseries'])\ny_dataseries_labels = pd.get_dummies(annotations_df['y_dataseries'])\n","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:16.887114Z","iopub.execute_input":"2023-06-10T18:03:16.887545Z","iopub.status.idle":"2023-06-10T18:03:16.901827Z","shell.execute_reply.started":"2023-06-10T18:03:16.887509Z","shell.execute_reply":"2023-06-10T18:03:16.900329Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Split the labels into training and validation sets\ntrain_chart_type_labels = chart_type_labels.loc[train_annotations.index]\nval_chart_type_labels = chart_type_labels.loc[val_annotations.index]\n\ntrain_x_dataseries_labels = x_dataseries_labels.loc[train_annotations.index]\nval_x_dataseries_labels = x_dataseries_labels.loc[val_annotations.index]\n\ntrain_y_dataseries_labels = y_dataseries_labels.loc[train_annotations.index]\nval_y_dataseries_labels = y_dataseries_labels.loc[val_annotations.index]","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:16.903894Z","iopub.execute_input":"2023-06-10T18:03:16.904947Z","iopub.status.idle":"2023-06-10T18:03:16.919268Z","shell.execute_reply.started":"2023-06-10T18:03:16.904916Z","shell.execute_reply":"2023-06-10T18:03:16.918149Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the number of classes for chart type prediction\nnum_chart_types = len(chart_type_labels.columns)\n\n# Define the number of classes for x and y data series prediction\nnum_x_dataseries = len(x_dataseries_labels.columns)\nnum_y_dataseries = len(y_dataseries_labels.columns)","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:16.922705Z","iopub.execute_input":"2023-06-10T18:03:16.922979Z","iopub.status.idle":"2023-06-10T18:03:16.930647Z","shell.execute_reply.started":"2023-06-10T18:03:16.922957Z","shell.execute_reply":"2023-06-10T18:03:16.928387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the input layer\ninput_layer = Input(shape=train_images[0].shape)","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:16.932281Z","iopub.execute_input":"2023-06-10T18:03:16.932672Z","iopub.status.idle":"2023-06-10T18:03:16.941149Z","shell.execute_reply.started":"2023-06-10T18:03:16.932641Z","shell.execute_reply":"2023-06-10T18:03:16.940256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the shared convolutional layers\nconv1 = Conv2D(32, (3, 3), activation='relu')(input_layer)\npool1 = MaxPooling2D((2, 2))(conv1)\nconv2 = Conv2D(64, (3, 3), activation='relu')(pool1)\npool2 = MaxPooling2D((2, 2))(conv2)\nconv3 = Conv2D(128, (3, 3), activation='relu')(pool2)\npool3 = MaxPooling2D((2, 2))(conv3)\nflatten = Flatten()(pool3)","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:16.942853Z","iopub.execute_input":"2023-06-10T18:03:16.943177Z","iopub.status.idle":"2023-06-10T18:03:17.015303Z","shell.execute_reply.started":"2023-06-10T18:03:16.943148Z","shell.execute_reply":"2023-06-10T18:03:17.014181Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the chart type output branch\nchart_type_dense = Dense(128, activation='relu')(flatten)\nchart_type_output = Dense(num_chart_types, activation='softmax', \n                          name='chart_type_output')(chart_type_dense)\n\n# Define the x data series output branch\nx_dataseries_dense = Dense(128, activation='relu')(flatten)\nx_dataseries_output = Dense(num_x_dataseries, activation='softmax', \n                            name='x_dataseries_output')(x_dataseries_dense)\n\n# Define the y data series output branch\ny_dataseries_dense = Dense(128, activation='relu')(flatten)\ny_dataseries_output = Dense(num_y_dataseries, activation='softmax', \n                            name='y_dataseries_output')(y_dataseries_dense)","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:17.016754Z","iopub.execute_input":"2023-06-10T18:03:17.017080Z","iopub.status.idle":"2023-06-10T18:03:17.117325Z","shell.execute_reply.started":"2023-06-10T18:03:17.017048Z","shell.execute_reply":"2023-06-10T18:03:17.116339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create the model with multiple outputs\nmodel = Model(inputs=input_layer, outputs=[chart_type_output, x_dataseries_output, y_dataseries_output])\n\n# Compile the model\nmodel.compile(optimizer='adam',\n              loss={'chart_type_output': 'categorical_crossentropy',\n                    'x_dataseries_output': 'categorical_crossentropy',\n                    'y_dataseries_output': 'categorical_crossentropy'},\n              metrics={'chart_type_output': 'accuracy',\n                      'x_dataseries_output': 'accuracy',\n                      'y_dataseries_output': 'accuracy'})","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:17.122686Z","iopub.execute_input":"2023-06-10T18:03:17.123373Z","iopub.status.idle":"2023-06-10T18:03:17.148642Z","shell.execute_reply.started":"2023-06-10T18:03:17.123332Z","shell.execute_reply":"2023-06-10T18:03:17.147785Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train the model\nhistory = model.fit(train_images, {'chart_type_output': train_chart_type_labels,\n                                   'x_dataseries_output': train_x_dataseries_labels,\n                                   'y_dataseries_output': train_y_dataseries_labels},\n                    batch_size=32, epochs=10,\n                    validation_data=(val_images, {'chart_type_output': val_chart_type_labels,\n                                                  'x_dataseries_output': val_x_dataseries_labels,\n                                                  'y_dataseries_output': val_y_dataseries_labels}))","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:17.150220Z","iopub.execute_input":"2023-06-10T18:03:17.150851Z","iopub.status.idle":"2023-06-10T18:03:32.142598Z","shell.execute_reply.started":"2023-06-10T18:03:17.150818Z","shell.execute_reply":"2023-06-10T18:03:32.141594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Evaluate the model\ntrain_metrics = model.evaluate(train_images, {'chart_type_output': train_chart_type_labels,\n                                              'x_dataseries_output': train_x_dataseries_labels,\n                                              'y_dataseries_output': train_y_dataseries_labels}, verbose=0)\nval_metrics = model.evaluate(val_images, {'chart_type_output': val_chart_type_labels,\n                                          'x_dataseries_output': val_x_dataseries_labels,\n                                          'y_dataseries_output': val_y_dataseries_labels}, verbose=0)","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:32.144584Z","iopub.execute_input":"2023-06-10T18:03:32.144922Z","iopub.status.idle":"2023-06-10T18:03:32.433204Z","shell.execute_reply.started":"2023-06-10T18:03:32.144880Z","shell.execute_reply":"2023-06-10T18:03:32.432238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Extract the accuracy and loss values\ntrain_loss = train_metrics[0]\ntrain_accuracy = train_metrics[1]\nval_loss = val_metrics[0]\nval_accuracy = val_metrics[1]","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:32.434535Z","iopub.execute_input":"2023-06-10T18:03:32.434864Z","iopub.status.idle":"2023-06-10T18:03:32.440594Z","shell.execute_reply.started":"2023-06-10T18:03:32.434834Z","shell.execute_reply":"2023-06-10T18:03:32.439692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Print the accuracy and error\nprint(f\"Train Accuracy: {train_accuracy:.4f}\")\nprint(f\"Validation Accuracy: {val_accuracy:.4f}\")\n\nprint(f\"Train Error: {1 - train_accuracy:.4f}\")\nprint(f\"Validation Error: {1 - val_accuracy:.4f}\")","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:03:32.441871Z","iopub.execute_input":"2023-06-10T18:03:32.442708Z","iopub.status.idle":"2023-06-10T18:03:32.453457Z","shell.execute_reply.started":"2023-06-10T18:03:32.442677Z","shell.execute_reply":"2023-06-10T18:03:32.452386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> Saves the trained model to a file named `trained_model.h5`.","metadata":{}},{"cell_type":"code","source":"# Save the trained model\nmodel.save('/kaggle/working/trained_model.h5')","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:24:19.295793Z","iopub.execute_input":"2023-06-10T18:24:19.296166Z","iopub.status.idle":"2023-06-10T18:24:20.965823Z","shell.execute_reply.started":"2023-06-10T18:24:19.296135Z","shell.execute_reply":"2023-06-10T18:24:20.964498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load the trained model\nmodel = load_model('/kaggle/working/trained_model.h5')","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:24:20.972129Z","iopub.execute_input":"2023-06-10T18:24:20.973184Z","iopub.status.idle":"2023-06-10T18:24:23.515344Z","shell.execute_reply.started":"2023-06-10T18:24:20.973136Z","shell.execute_reply":"2023-06-10T18:24:23.514374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set the path to the folder containing the images\nfolder_path = '/kaggle/input/benetech-making-graphs-accessible/test/images'","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:26:02.410804Z","iopub.execute_input":"2023-06-10T18:26:02.411163Z","iopub.status.idle":"2023-06-10T18:26:02.415633Z","shell.execute_reply.started":"2023-06-10T18:26:02.411134Z","shell.execute_reply":"2023-06-10T18:26:02.414578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Initialize lists to store the image paths and predictions\nimage_ids = []\nchart_types = []\nx_dataseries = []\ny_dataseries = []","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:26:03.229792Z","iopub.execute_input":"2023-06-10T18:26:03.230266Z","iopub.status.idle":"2023-06-10T18:26:03.235623Z","shell.execute_reply.started":"2023-06-10T18:26:03.230187Z","shell.execute_reply":"2023-06-10T18:26:03.234537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Iterate over the images in the folder\nfor image_file in os.listdir(folder_path):\n    image_path = os.path.join(folder_path, image_file)\n    image = cv2.imread(image_path)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    image = cv2.resize(image, (256, 256))\n    image = image / 255.0\n    image = np.expand_dims(image, axis=0)\n    \n    # Make predictions\n    predictions = model.predict(image)\n    \n    # Get the image id\n    image_id = image_file.split('.')[0]\n    \n    # Get the predicted chart type\n    chart_type_prediction = np.argmax(predictions[0])\n    chart_type = chart_type_labels.columns[chart_type_prediction]\n    \n    # Get the predicted x and y data series\n    x_dataseries_prediction = np.argmax(predictions[1])\n    y_dataseries_prediction = np.argmax(predictions[2])\n    x_dataseries_value = x_dataseries_labels.columns[x_dataseries_prediction]\n    y_dataseries_value = y_dataseries_labels.columns[y_dataseries_prediction]\n    \n    # Store the image id and predictions\n    image_ids.append(image_id)\n    x_dataseries.append(x_dataseries_value)\n    y_dataseries.append(y_dataseries_value)\n    chart_types.append(chart_type)","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:26:04.321658Z","iopub.execute_input":"2023-06-10T18:26:04.322031Z","iopub.status.idle":"2023-06-10T18:26:04.633542Z","shell.execute_reply.started":"2023-06-10T18:26:04.322001Z","shell.execute_reply":"2023-06-10T18:26:04.632630Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create a DataFrame with the predicted output\noutput_df = pd.DataFrame({\n    'id': [f\"{image_id}_x\" for image_id in image_ids] + [f\"{image_id}_y\" for image_id in image_ids],\n    'data_series': x_dataseries + y_dataseries,\n    'chart_type': chart_types + chart_types\n})\n","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:26:06.866613Z","iopub.execute_input":"2023-06-10T18:26:06.866969Z","iopub.status.idle":"2023-06-10T18:26:06.873156Z","shell.execute_reply.started":"2023-06-10T18:26:06.866941Z","shell.execute_reply":"2023-06-10T18:26:06.872283Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"output_df","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:26:37.351771Z","iopub.execute_input":"2023-06-10T18:26:37.352142Z","iopub.status.idle":"2023-06-10T18:26:37.362426Z","shell.execute_reply.started":"2023-06-10T18:26:37.352113Z","shell.execute_reply":"2023-06-10T18:26:37.361352Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Reorder the columns\noutput_df = output_df[['id', 'data_series', 'chart_type']]","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:26:32.722733Z","iopub.execute_input":"2023-06-10T18:26:32.723098Z","iopub.status.idle":"2023-06-10T18:26:32.728728Z","shell.execute_reply.started":"2023-06-10T18:26:32.723069Z","shell.execute_reply":"2023-06-10T18:26:32.727674Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(output_df)\n# Save the DataFrame as a CSV file\noutput_df.to_csv('/kaggle/working/submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-06-10T18:09:50.779993Z","iopub.execute_input":"2023-06-10T18:09:50.780373Z","iopub.status.idle":"2023-06-10T18:09:50.792365Z","shell.execute_reply.started":"2023-06-10T18:09:50.780334Z","shell.execute_reply":"2023-06-10T18:09:50.791076Z"},"trusted":true},"execution_count":null,"outputs":[]}]}