{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":70203,"databundleVersionId":8068726,"sourceType":"competition"},{"sourceId":8045887,"sourceType":"datasetVersion","datasetId":4744304},{"sourceId":26431,"sourceType":"modelInstanceVersion","modelInstanceId":22241}],"dockerImageVersionId":30673,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# **Bird Species Classification-(BirdCLEF 2024)**","metadata":{}},{"cell_type":"markdown","source":"![](https://www.wassupmate.com/wp-content/uploads/2015/07/Colorful-Parrots-Wallpaper.jpg)","metadata":{}},{"cell_type":"markdown","source":"# **Table of Contents**\n\n* **Introduction**\n* **Import Libraries**\n* **Data Collection and Processing**\n* **Exploratory Data Analysis (EDA)**\n* **Feature Engineering**\n    1. Feature Extraction\n    2. Label Encoding\n    3. Random sampling Data\n* **Model Training**\n* **Model Evaluation**\n* **Model Testing**","metadata":{}},{"cell_type":"markdown","source":"# **Introduction:**\n\nWelcome to the Indian Bird Species Identification Challenge, an innovative competition aimed at leveraging machine learning to advance avian biodiversity conservation efforts in the Western Ghats, India. Birds serve as invaluable indicators of ecosystem health and are pivotal in gauging the success of restoration initiatives. However, traditional observer-based surveys are often costly and logistically demanding, limiting the scope and frequency of biodiversity assessments.\n\nIn response to these challenges, this competition proposes a novel approach: harnessing the power of passive acoustic monitoring (PAM) coupled with cutting-edge machine learning algorithms. By analyzing continuous audio recordings, participants will develop computational solutions to identify under-studied Indian bird species by their distinct calls. This pioneering method allows for sampling across vast spatial scales with enhanced temporal resolution, facilitating a deeper understanding of the relationship between restoration interventions and avian biodiversity.\n\nThe Western Ghats, renowned for its rich biodiversity and unique ecosystems, serves as the focal point for this endeavor. Led by the esteemed V. V. Robin's Lab at the Indian Institute of Science Education and Research (IISER) Tirupati, ongoing conservation initiatives in this region stand to benefit significantly from the insights garnered through this competition.\n\nParticipants are tasked with training classifiers capable of accurately identifying bird species from audio data, even with limited training samples. Successful solutions will not only advance scientific knowledge but also inform conservation strategies, contributing to the preservation of avian biodiversity in one of the world's most biodiverse regions.\n\nJoin us in this collaborative effort to safeguard the diverse avifauna of the Western Ghats and propel forward the frontier of conservation science through the fusion of machine learning and ecological research. Together, we can make a meaningful difference in the protection of our natural heritage.","metadata":{}},{"cell_type":"markdown","source":"# **Import Libraries**","metadata":{}},{"cell_type":"code","source":"import os\nimport glob\nimport shutil\nimport zipfile\nimport json\nimport matplotlib.pyplot as plt\nplt.style.use('dark_background')\nimport seaborn as sns\nimport numpy as np\n!pip install plotly\nimport plotly.express as px\nimport librosa\nfrom IPython.display import Audio\nimport pandas as pd\nimport pickle\nfrom joblib import dump, load\nfrom pathlib import Path\n!pip install -U imbalanced-learn\nfrom imblearn.over_sampling import RandomOverSampler\nimport sklearn\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix","metadata":{"execution":{"iopub.status.busy":"2024-04-08T03:41:02.616739Z","iopub.execute_input":"2024-04-08T03:41:02.617318Z","iopub.status.idle":"2024-04-08T03:41:33.343511Z","shell.execute_reply.started":"2024-04-08T03:41:02.617275Z","shell.execute_reply":"2024-04-08T03:41:33.341762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Data Collection and Processing**","metadata":{}},{"cell_type":"code","source":"# meta_data = pd.read_csv('/kaggle/input/birdclef-2024/train_metadata.csv')\n# meta_data.head(4)","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:24:27.957226Z","iopub.execute_input":"2024-04-08T02:24:27.958004Z","iopub.status.idle":"2024-04-08T02:24:28.188809Z","shell.execute_reply.started":"2024-04-08T02:24:27.957965Z","shell.execute_reply":"2024-04-08T02:24:28.187585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# meta_data.info()","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:24:28.190132Z","iopub.execute_input":"2024-04-08T02:24:28.190550Z","iopub.status.idle":"2024-04-08T02:24:28.245740Z","shell.execute_reply.started":"2024-04-08T02:24:28.190520Z","shell.execute_reply":"2024-04-08T02:24:28.244569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code reads a CSV file named 'train_metadata.csv' located in the specified path using pandas library. It then displays the first four rows of the DataFrame using the `head()` method. Lastly, it prints a concise summary of the DataFrame's information, including the data types of each column and the count of non-null values, using the `info()` method.","metadata":{}},{"cell_type":"markdown","source":"# **Exploratory Data Analysis (EDA)**","metadata":{}},{"cell_type":"code","source":"# fig = px.scatter_mapbox(meta_data, lat='latitude', lon='longitude', color='common_name', \n#                         hover_name='common_name', hover_data=['latitude', 'longitude'], \n#                         title='Origin of Bird Species',\n#                         zoom=1, height=600, template='plotly_dark')\n# fig.update_layout(\n#     mapbox_style=\"white-bg\",\n#     mapbox_layers=[\n#         {\n#             \"below\": 'traces',\n#             \"sourcetype\": \"raster\",\n#             \"sourceattribution\": \"United States Geological Survey\",\n#             \"source\": [\n#                 \"https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}\"\n#             ]\n#         }\n#       ])\n# fig.show()","metadata":{"execution":{"iopub.status.busy":"2024-04-07T07:04:40.739181Z","iopub.execute_input":"2024-04-07T07:04:40.739657Z","iopub.status.idle":"2024-04-07T07:04:43.881273Z","shell.execute_reply.started":"2024-04-07T07:04:40.739623Z","shell.execute_reply":"2024-04-07T07:04:43.879728Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This Python code utilizes Plotly Express (px) to create a scatter plot on a Mapbox map. It visualizes the geographical distribution of bird species represented in the 'meta_data' DataFrame. Each point on the map represents a bird species, colored by its common name. Hovering over a point displays additional information such as latitude and longitude. The map's background is set to a dark theme ('plotly_dark'), and a raster basemap layer from the United States Geological Survey is added for geographical context. Finally, the interactive plot is displayed using 'fig.show()'.","metadata":{}},{"cell_type":"code","source":"# def audio_waveframe(file_path):\n#     # Load the audio file\n#     audio_data, sampling_rate = librosa.load(file_path)\n#     # Calculate the duration of the audio file\n#     duration = len(audio_data) / sampling_rate\n#     # Create a time array for plotting\n#     time = np.arange(0, duration, 1/sampling_rate)\n#     # Plot the waveform\n#     plt.figure(figsize=(30, 4))\n#     plt.plot(time, audio_data, color='blue')\n#     plt.title('Audio Waveform')\n#     plt.xlabel('Time (s)')\n#     plt.ylabel('Amplitude')\n#     plot = plt.show()\n#     return plot\n\n# def spectrogram(file_path):\n#     # Compute the short-time Fourier transform (STFT)\n#     n_fft = 500  # Number of FFT points 2048\n#     hop_length = 50  # Hop length for STFT 512\n#     audio_data, sampling_rate = librosa.load(file_path)\n#     stft = librosa.stft(audio_data, n_fft=n_fft, hop_length=hop_length)\n#     # Convert the magnitude spectrogram to decibels (log scale)\n#     spectrogram = librosa.amplitude_to_db(np.abs(stft))\n#     # Plot the spectrogram\n#     plt.figure(figsize=(30, 6))\n#     librosa.display.specshow(spectrogram, sr=sampling_rate, hop_length=hop_length, x_axis='time', y_axis='linear')\n#     plt.colorbar(format='%+2.0f dB')\n#     plt.title('Spectrogram')\n#     plt.xlabel('Time (s)')\n#     plt.ylabel('Frequency (Hz)')\n#     plt.tight_layout()\n#     plot = plt.show()\n#     return plot\n\n# def audio_analysis(file_path):\n#     aw = audio_waveframe(file_path)\n#     spg = spectrogram(file_path)\n#     return aw, spg","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:24:55.615315Z","iopub.execute_input":"2024-04-08T02:24:55.615712Z","iopub.status.idle":"2024-04-08T02:24:55.628539Z","shell.execute_reply.started":"2024-04-08T02:24:55.615679Z","shell.execute_reply":"2024-04-08T02:24:55.627153Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code defines three functions for audio analysis:\n\n1. `audio_waveframe(file_path)`: Loads an audio file, plots its waveform showing amplitude variation over time, and returns the plot.\n2. `spectrogram(file_path)`: Computes the spectrogram of the audio file, which visualizes its frequency content over time, and returns the plot.\n3. `audio_analysis(file_path)`: Calls the `audio_waveframe()` and `spectrogram()` functions for the given audio file, then returns the plots generated by both functions.","metadata":{}},{"cell_type":"code","source":"# audio_analysis('/kaggle/input/birdclef-2024/train_audio/asbfly/XC134896.ogg')\n# Audio('/kaggle/input/birdclef-2024/train_audio/asbfly/XC134896.ogg')","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:25:03.924033Z","iopub.execute_input":"2024-04-08T02:25:03.924486Z","iopub.status.idle":"2024-04-08T02:25:20.825313Z","shell.execute_reply.started":"2024-04-08T02:25:03.924450Z","shell.execute_reply":"2024-04-08T02:25:20.824260Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Feature Engineering**","metadata":{}},{"cell_type":"code","source":"# # Path to the directory containing your audio dataset\n# dataset_dir = '/kaggle/input/birdclef-2024/train_audio'\n# # Initialize an empty dictionary to store the mapping between audio files and labels\n# label_mapping = {}\n# # Iterate over subdirectories (classes) in the dataset directory\n# for label in os.listdir(dataset_dir):\n#     label_dir = os.path.join(dataset_dir, label)\n#     # Check if the item in the dataset directory is a directory\n#     if os.path.isdir(label_dir):\n#         # Iterate over audio files in the subdirectory (class)\n#         for audio_file in os.listdir(label_dir):\n#             # Add the mapping between audio file path and label to the dictionary\n#             audio_file_path = os.path.join(label_dir, audio_file)\n#             label_mapping[audio_file_path] = label","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:25:27.933555Z","iopub.execute_input":"2024-04-08T02:25:27.934838Z","iopub.status.idle":"2024-04-08T02:25:34.443071Z","shell.execute_reply.started":"2024-04-08T02:25:27.934799Z","shell.execute_reply":"2024-04-08T02:25:34.441787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code snippet iterates through each subdirectory in the specified dataset directory, representing different classes of bird species. Within each subdirectory, it iterates through the audio files and creates a mapping between the file paths and their corresponding class labels, storing them in a dictionary called `label_mapping`. This dictionary will be used to associate each audio file with its respective bird species label for training a machine learning model.","metadata":{}},{"cell_type":"code","source":"# # Create a list of tuples containing the audio file paths and labels\n# data = [(audio_file_path, label) for audio_file_path, label in label_mapping.items()]\n# # Create a Pandas DataFrame from the list of tuples\n# annotated_data = pd.DataFrame(data, columns=['audio_file_path', 'label'])\n# annotated_data","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:25:44.948967Z","iopub.execute_input":"2024-04-08T02:25:44.949626Z","iopub.status.idle":"2024-04-08T02:25:45.197853Z","shell.execute_reply.started":"2024-04-08T02:25:44.949586Z","shell.execute_reply":"2024-04-08T02:25:45.196793Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code snippet creates a list of tuples where each tuple contains the audio file path and its corresponding label from a dictionary called 'label_mapping'. Then, it creates a Pandas DataFrame named 'annotated_data' from this list of tuples with columns named 'audio_file_path' and 'label'. In essence, it organizes the audio data and their labels into a structured DataFrame for further processing and analysis using Pandas.","metadata":{}},{"cell_type":"markdown","source":"# 1. Feature Extraction","metadata":{}},{"cell_type":"code","source":"# # Function to extract features from audio file\n# def extract_features(file_path):\n#     # Load audio file\n#     audio, sample_rate = librosa.load(file_path)\n#     # Extract features using Mel-Frequency Cepstral Coefficients (MFCC)\n#     mfccs = librosa.feature.mfcc(y=audio, sr=sample_rate, n_mfcc=40)\n#     # Flatten the features into a 1D array\n#     flattened_features = np.mean(mfccs.T, axis=0)\n#     return flattened_features\n\n# # Function to load dataset and extract features\n# def load_data_and_extract_features(data_dir):\n#     labels = []\n#     features = []\n#     # Loop through each audio file in the dataset directory\n#     for filename in os.listdir(data_dir):\n#         if filename.endswith('.ogg'):\n#             file_path = os.path.join(data_dir, filename)\n#             # Extract label from filename\n#             label = filename.split('-')[0]\n#             labels.append(label)\n#             # Extract features from audio file\n#             feature = extract_features(file_path)\n#             features.append(feature)\n#     return np.array(features), np.array(labels)","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:25:52.816414Z","iopub.execute_input":"2024-04-08T02:25:52.817003Z","iopub.status.idle":"2024-04-08T02:25:52.825980Z","shell.execute_reply.started":"2024-04-08T02:25:52.816971Z","shell.execute_reply":"2024-04-08T02:25:52.824358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code defines two functions for feature extraction from audio files and loading the dataset:\n\n1. `extract_features(file_path)`: \n   - Loads an audio file using librosa library.\n   - Calculates Mel-Frequency Cepstral Coefficients (MFCC) features from the audio.\n   - Averages the MFCC features over time to create a flattened feature vector.\n   - Returns the flattened feature vector.\n\n2. `load_data_and_extract_features(data_dir)`:\n   - Iterates through each audio file in the specified directory.\n   - Extracts the label from the filename by splitting it at '-'.\n   - Calls `extract_features()` to extract features from each audio file.\n   - Returns numpy arrays containing the extracted features and corresponding labels.","metadata":{}},{"cell_type":"code","source":"# from tqdm import tqdm\n\n# extracted_features = []\n\n# for i in tqdm(annotated_data['audio_file_path']):\n#     features = extract_features(file_path=i)\n#     # print(features)\n#     extracted_features.append(features)","metadata":{"execution":{"iopub.status.busy":"2024-04-07T07:09:12.915223Z","iopub.status.idle":"2024-04-07T07:09:12.915645Z","shell.execute_reply.started":"2024-04-07T07:09:12.915423Z","shell.execute_reply":"2024-04-07T07:09:12.915439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This Python code snippet uses the `tqdm` library to create a progress bar for iterating over a list of audio file paths (`annotated_data['audio_file_path']`). Inside the loop, it calls a function `extract_features()` to extract features from each audio file. The extracted features are then appended to the list `extracted_features`. The `tqdm()` function provides a visual progress indicator, making it easier to track the progress of the loop.","metadata":{}},{"cell_type":"code","source":"# with open(\"extracted_features\", \"wb\") as file:   #Pickling\n# \tpickle.dump(extracted_features, file)","metadata":{"execution":{"iopub.status.busy":"2024-04-06T03:53:28.322561Z","iopub.execute_input":"2024-04-06T03:53:28.323616Z","iopub.status.idle":"2024-04-06T03:53:28.442790Z","shell.execute_reply.started":"2024-04-06T03:53:28.323570Z","shell.execute_reply":"2024-04-06T03:53:28.441732Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# with open(\"/kaggle/input/extracted-features-pickle/extracted_features\", \"rb\") as file:   # Unpickling\n# \tpickled_extracted_features = pickle.load(file)","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:27:11.476255Z","iopub.execute_input":"2024-04-08T02:27:11.476653Z","iopub.status.idle":"2024-04-08T02:27:11.607014Z","shell.execute_reply.started":"2024-04-08T02:27:11.476623Z","shell.execute_reply":"2024-04-08T02:27:11.605769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This Python code utilizes the `pickle` module to save and load data in binary format:\n\n1. **Saving Data:**\n   - `pickle.dump(extracted_features, file)`: Serializes the `extracted_features` data and writes it to a file named \"extracted_features\" in binary format.\n\n2. **Loading Data:**\n   - `pickled_extracted_features = pickle.load(file)`: Reads the binary data from the \"extracted_features\" file and deserializes it, storing the result in the `pickled_extracted_features` variable.\n\nOverall, this code snippet demonstrates a simple way to save and load Python objects using pickling, enabling data persistence between different program executions.","metadata":{}},{"cell_type":"markdown","source":"# 2. Label Encoding","metadata":{}},{"cell_type":"code","source":"# label_encoder = LabelEncoder()\n# annotated_data['encoded_label'] = label_encoder.fit_transform(annotated_data['label'])\n# annotated_data","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:26:35.584498Z","iopub.execute_input":"2024-04-08T02:26:35.584953Z","iopub.status.idle":"2024-04-08T02:26:35.611186Z","shell.execute_reply.started":"2024-04-08T02:26:35.584918Z","shell.execute_reply":"2024-04-08T02:26:35.609827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# annotated_data.info()","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:26:41.849399Z","iopub.execute_input":"2024-04-08T02:26:41.850005Z","iopub.status.idle":"2024-04-08T02:26:41.866999Z","shell.execute_reply.started":"2024-04-08T02:26:41.849973Z","shell.execute_reply":"2024-04-08T02:26:41.865857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code uses the `LabelEncoder` from scikit-learn to convert categorical labels into numerical values. It fits the encoder to the 'label' column of the annotated dataset, assigning a unique numeric code to each unique label. The encoded labels are then stored in a new column called 'encoded_label' in the annotated dataset. This transformation allows machine learning algorithms to work with categorical data, improving model training and performance.","metadata":{}},{"cell_type":"code","source":"# plt.figure(figsize=(24, 12))\n# sns.countplot(x='primary_label', data=meta_data, order=meta_data['primary_label'].value_counts().index)\n# plt.xticks(rotation=45)\n# plt.rc('font', size=6)\n# plt.title('Count of Bird Species Classes')\n# plt.xlabel('Bird Species')\n# plt.ylabel('Count')\n# plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:26:47.518657Z","iopub.execute_input":"2024-04-08T02:26:47.519071Z","iopub.status.idle":"2024-04-08T02:26:49.366465Z","shell.execute_reply.started":"2024-04-08T02:26:47.519039Z","shell.execute_reply":"2024-04-08T02:26:49.365090Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code creates a countplot to visualize the distribution of bird species classes in the 'primary_label' column of the 'meta_data' DataFrame. The order of species is determined by their frequency in the dataset. The x-axis represents the bird species, while the y-axis shows the count of each species. The plot is displayed with rotated x-axis labels and reduced font size for better readability.","metadata":{}},{"cell_type":"markdown","source":"# 3. Random Sampling Data","metadata":{}},{"cell_type":"code","source":"# x = np.vstack(pickled_extracted_features)\n# y = annotated_data['encoded_label']\n\n# print(x.shape)\n# print(y.shape)","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:27:22.832631Z","iopub.execute_input":"2024-04-08T02:27:22.833032Z","iopub.status.idle":"2024-04-08T02:27:22.886744Z","shell.execute_reply.started":"2024-04-08T02:27:22.833001Z","shell.execute_reply":"2024-04-08T02:27:22.885519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ros = RandomOverSampler(random_state=42)\n# features_resampled, labels_reshampled = ros.fit_resample(x, y)\n\n# print(features_resampled.shape)\n# print(labels_reshampled.shape)","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:27:26.683034Z","iopub.execute_input":"2024-04-08T02:27:26.683499Z","iopub.status.idle":"2024-04-08T02:27:26.738529Z","shell.execute_reply.started":"2024-04-08T02:27:26.683463Z","shell.execute_reply":"2024-04-08T02:27:26.736964Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code uses the RandomOverSampler from the imbalanced-learn library to address class imbalance in a dataset (x, y). It randomly oversamples the minority class to balance class distribution. The resampled features and labels are stored in features_resampled and labels_reshampled, respectively. The shape of the resampled features and labels are printed to verify the new dataset dimensions.","metadata":{}},{"cell_type":"markdown","source":"# **Model Training**","metadata":{}},{"cell_type":"code","source":"# # Split data into training and testing sets\n# x_train, x_test, y_train, y_test = train_test_split(features_resampled, labels_reshampled, test_size=0.2, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:27:32.293839Z","iopub.execute_input":"2024-04-08T02:27:32.294280Z","iopub.status.idle":"2024-04-08T02:27:32.319793Z","shell.execute_reply.started":"2024-04-08T02:27:32.294247Z","shell.execute_reply":"2024-04-08T02:27:32.318068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# random_forest_classifier = RandomForestClassifier(n_estimators=100, random_state=42)\n# random_forest_model = random_forest_classifier.fit(x_train, y_train)\n# y_predict = random_forest_model.predict(x_test)\n# accuracy = accuracy_score(y_test, y_predict)\n# print(\"Accuracy:\", accuracy)","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:27:39.523445Z","iopub.execute_input":"2024-04-08T02:27:39.523842Z","iopub.status.idle":"2024-04-08T02:31:29.408328Z","shell.execute_reply.started":"2024-04-08T02:27:39.523812Z","shell.execute_reply":"2024-04-08T02:31:29.406802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code splits the data into training and testing sets, with 80% for training and 20% for testing. Then, it builds a Random Forest classifier with 100 trees and trains it on the training data. After training, it predicts labels for the testing set and computes the accuracy of the predictions compared to the actual labels. Finally, it prints the accuracy score, indicating how well the classifier performed on the test data.","metadata":{}},{"cell_type":"markdown","source":"# **Model Evaluation**","metadata":{}},{"cell_type":"code","source":"# def evaluate_model(y_true, y_pred):\n#     # Calculate accuracy\n#     accuracy = accuracy_score(y_true, y_pred)\n#     # Calculate precision\n#     precision = precision_score(y_true, y_pred, average='weighted')\n#     # Calculate recall\n#     recall = recall_score(y_true, y_pred, average='weighted')\n#     # Calculate F1 score\n#     f1 = f1_score(y_true, y_pred, average='weighted')\n    \n#     return accuracy, precision, recall, f1\n\n# # Evaluate the model\n# accuracy, precision, recall, f1 = evaluate_model(y_test, y_predict)\n# # Print evaluation metrics\n# print(\"Accuracy:\", accuracy)\n# print(\"Precision:\", precision)\n# print(\"Recall:\", recall)\n# print(\"F1 Score:\", f1)\n","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:31:29.410820Z","iopub.execute_input":"2024-04-08T02:31:29.411390Z","iopub.status.idle":"2024-04-08T02:31:29.479048Z","shell.execute_reply.started":"2024-04-08T02:31:29.411354Z","shell.execute_reply":"2024-04-08T02:31:29.478014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code defines a function `evaluate_model` to assess the performance of a classification model using various metrics such as accuracy, precision, recall, and F1 score. It takes the true labels (`y_true`) and predicted labels (`y_pred`) as inputs. The function calculates each metric using scikit-learn's built-in functions (`accuracy_score`, `precision_score`, `recall_score`, `f1_score`) and returns these metrics. Finally, it evaluates the model on a test set and prints out the computed evaluation metrics.","metadata":{}},{"cell_type":"markdown","source":"# **Model Testing and Deployment**","metadata":{}},{"cell_type":"code","source":"# dump(random_forest_model, 'audio_classifier_model.joblib')","metadata":{"execution":{"iopub.status.busy":"2024-04-07T13:15:15.592409Z","iopub.execute_input":"2024-04-07T13:15:15.593543Z","iopub.status.idle":"2024-04-07T13:15:20.148850Z","shell.execute_reply.started":"2024-04-07T13:15:15.593505Z","shell.execute_reply":"2024-04-07T13:15:20.147513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model = load('/kaggle/working/audio_classifier_model.joblib')","metadata":{"execution":{"iopub.status.busy":"2024-04-07T13:15:34.194186Z","iopub.execute_input":"2024-04-07T13:15:34.200148Z","iopub.status.idle":"2024-04-07T13:15:54.565703Z","shell.execute_reply.started":"2024-04-07T13:15:34.200031Z","shell.execute_reply":"2024-04-07T13:15:54.564405Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code utilizes the `joblib` library to save (`dump`) a trained random forest model (`random_forest_model`) as a file named `'audio_classifier_model.joblib'`. Later, it loads (`load`) the saved model from the specified path into a variable named `model`. This allows the trained model to be stored persistently and reused for future predictions without needing to retrain it each time.","metadata":{}},{"cell_type":"code","source":"# def audio_classification(file_path):\n#     audio = file_path\n#     print(audio)\n#     extracted_features = extract_features(audio).reshape(1, -1)\n#     # extracted_features = x_test[112].reshape(1, -1)\n#     y_predict = random_forest_model.predict(extracted_features)\n#     labels_list = annotated_data['label'].unique()\n#     encoded_label = annotated_data['encoded_label'].unique()\n\n#     labels = {}\n#     for label, prediction in zip(encoded_label, labels_list):\n#         labels[label] = prediction\n#     if y_predict[0] in labels.keys():\n#         predicted = ('Predicted Class:', labels[y_predict[0]])\n#     return predicted","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:31:57.818898Z","iopub.execute_input":"2024-04-08T02:31:57.819942Z","iopub.status.idle":"2024-04-08T02:31:57.827215Z","shell.execute_reply.started":"2024-04-08T02:31:57.819907Z","shell.execute_reply":"2024-04-08T02:31:57.826162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# file_path = '/kaggle/input/birdclef-2024/unlabeled_soundscapes/1001358022.ogg'\n# audio_analysis(file_path)\n# Audio(file_path)","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:32:05.491325Z","iopub.execute_input":"2024-04-08T02:32:05.492304Z","iopub.status.idle":"2024-04-08T02:32:28.112586Z","shell.execute_reply.started":"2024-04-08T02:32:05.492266Z","shell.execute_reply":"2024-04-08T02:32:28.111188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# audio_classification(file_path)","metadata":{"execution":{"iopub.status.busy":"2024-04-08T02:32:28.114703Z","iopub.execute_input":"2024-04-08T02:32:28.115216Z","iopub.status.idle":"2024-04-08T02:32:30.596028Z","shell.execute_reply.started":"2024-04-08T02:32:28.115156Z","shell.execute_reply":"2024-04-08T02:32:30.594537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This Python function, `audio_classification`, takes a file path to an audio file as input. It:\n1. Reads the audio file from the given path.\n2. Extracts features from the audio using a function called `extract_features`.\n3. Predicts the class of the audio using a pre-trained machine learning model.\n4. Returns the predicted class label for the audio file.","metadata":{}},{"cell_type":"markdown","source":"# **Project Submission**","metadata":{}},{"cell_type":"code","source":"# First, load list of audio files by parsing the test_soundscape folder.\ntest_audio_dir = '../input/birdclef-2024/test_soundscapes/'\nfile_list = [f.split('.')[0] for f in sorted(os.listdir(test_audio_dir))]\n\n# At the moment, there should only be a single soundscape visible.\n# During the submission re-run, all other hidden soundscapes\n# will be visible too and can be processed by your notebook.\nprint('Number of test soundscapes:', len(file_list))","metadata":{"execution":{"iopub.status.busy":"2024-04-08T03:12:32.404478Z","iopub.execute_input":"2024-04-08T03:12:32.405883Z","iopub.status.idle":"2024-04-08T03:12:32.417670Z","shell.execute_reply.started":"2024-04-08T03:12:32.405823Z","shell.execute_reply":"2024-04-08T03:12:32.416364Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# This is where we will store our results\npred = {'row_id': []}\ntrain_audio_dir = '../input/birdclef-2024/train_audio/'\nspecies_list = sorted(os.listdir(train_audio_dir))\nfor species_code in species_list:\n    pred[species_code] = []\n\n# Process audio files and make predictions\nfor afile in file_list:\n    \n    # Complete file path\n    path = test_audio_dir + afile + '.ogg'\n    \n    # Open file with librosa and split signal into 5-second chunks\n    # sig, rate = librosa.load(path, sr=32000)\n    # ...\n    \n    # Let's assume we have a list of 120 audio chunks (10min / 5s == 120 segments)\n    chunks = [[] for i in range(120)]\n    \n    # Make prediction for each chunk\n    # Each bird gets a random value in our case\n    # since we don't actually have a model\n    for i in range(len(chunks)):        \n        chunk_end_time = (i + 1) * 5\n        \n        # Assign the row_id which we need to do for each chunk\n        row_id = afile + '_' + str(chunk_end_time)\n        pred['row_id'].append(row_id)\n        \n        for bird in species_list:\n            \n            # This is our random prediction score for this bird\n            score = np.random.uniform()     \n            \n            # Put the result into our prediction dict            \n            pred[bird].append(score)","metadata":{"execution":{"iopub.status.busy":"2024-04-08T03:13:20.768595Z","iopub.execute_input":"2024-04-08T03:13:20.769565Z","iopub.status.idle":"2024-04-08T03:13:20.895387Z","shell.execute_reply.started":"2024-04-08T03:13:20.769524Z","shell.execute_reply":"2024-04-08T03:13:20.894038Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Make a new data frame and look at some results        \nresults = pd.DataFrame(pred, columns = ['row_id'] + species_list)\n\n# Quick sanity check\nprint(results.head()) \n    \n# Convert our results to csv\nresults.to_csv(\"submission.csv\", index=False)    ","metadata":{"execution":{"iopub.status.busy":"2024-04-08T03:13:49.117327Z","iopub.execute_input":"2024-04-08T03:13:49.117772Z","iopub.status.idle":"2024-04-08T03:13:49.219349Z","shell.execute_reply.started":"2024-04-08T03:13:49.117737Z","shell.execute_reply":"2024-04-08T03:13:49.218412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import os\n# import json\n# import numpy as np\n# import pandas as pd\n# import librosa\n\n# # First, load list of audio files by parsing the test_soundscape folder.\n# test_audio_dir = '../input/birdclef-2024/test_soundscapes/'\n# file_list = [f.split('.')[0] for f in sorted(os.listdir(test_audio_dir))]\n\n# # At the moment, there should only be a single soundscape visible.\n# # During the submission re-run, all other hidden soundscapes\n# # will be visible too and can be processed by your notebook.\n# print('Number of test soundscapes:', len(file_list))\n\n# # This is where we will store our results\n# pred = {'row_id': []}\n# train_audio_dir = '../input/birdclef-2024/train_audio/'\n# species_list = sorted(os.listdir(train_audio_dir))\n# for species_code in species_list:\n#     pred[species_code] = []\n\n# # Process audio files and make predictions\n# for afile in file_list:\n    \n#     # Complete file path\n#     path = test_audio_dir + afile + '.ogg'\n    \n#     # Open file with librosa and split signal into 5-second chunks\n#     sig, rate = librosa.load(path, sr=32000)\n    \n#     # Split the signal into 5-second chunks\n#     chunk_size = 5 * rate\n#     chunks = [sig[i:i+chunk_size] for i in range(0, len(sig), chunk_size)]\n    \n#     # Make prediction for each chunk\n#     for i, chunk in enumerate(chunks):\n#         chunk_end_time = (i + 1) * 5\n        \n#         # Assign the row_id which we need to do for each chunk\n#         row_id = afile + '_' + str(chunk_end_time)\n#         pred['row_id'].append(row_id)\n        \n#         for bird in species_list:\n            \n#             # This is our random prediction score for this bird\n#             score = np.random.uniform()     \n            \n#             # Put the result into our prediction dict            \n#             pred[bird].append(score)\n\n# # Make a new data frame and look at some results        \n# results = pd.DataFrame(pred, columns=['row_id'] + species_list)\n\n# # Quick sanity check\n# print(results.head()) \n\n# # Convert our results to csv\n# results.to_csv(\"submission.csv\", index=False)\n","metadata":{"execution":{"iopub.status.busy":"2024-04-08T03:33:40.547041Z","iopub.execute_input":"2024-04-08T03:33:40.547527Z","iopub.status.idle":"2024-04-08T03:33:41.160042Z","shell.execute_reply.started":"2024-04-08T03:33:40.547490Z","shell.execute_reply":"2024-04-08T03:33:41.158070Z"},"trusted":true},"execution_count":null,"outputs":[]}]}