{"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":"markdown","source":"# Intro\nWelcome to the [BirdCLEF 2022](https://www.kaggle.com/c/birdclef-2022/overview) compedition.\n\n![](https://storage.googleapis.com/kaggle-competitions/kaggle/33246/logos/header.png)\n\nWe recommmend this [notebook](https://www.kaggle.com/drcapa/birdclef-2021-starter) to the data set of the last year and this [notebook](https://www.kaggle.com/drcapa/recognizesongapp-fromscratch-tutorial) for handling audio data tutorial.\n\n**Table of content:**\n1. [Overview](#Overview)\n2. [A Sample File](#SampleFile)\n3. [Plot Examples](#PlotExamples)\n4. [Exploratory Data Analysis](#EDA)\n5. [Focus On Labels](#FocusOnLabels)\n6. [Audio Data Generator](#AudioDataGenerator)\n\n<font size=\"4\"><span style=\"color: royalblue;\">Please vote the notebook up if it helps you. Feel free to leave a comment above the notebook. Thank you. </span></font>","metadata":{}},{"cell_type":"markdown","source":"# Libraries","metadata":{}},{"cell_type":"code","source":"import os\nimport ast\nimport json\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport soundfile as sf\nimport librosa\nimport librosa.display\nimport IPython.display as display","metadata":{"execution":{"iopub.status.busy":"2022-02-15T20:14:57.822775Z","iopub.execute_input":"2022-02-15T20:14:57.823097Z","iopub.status.idle":"2022-02-15T20:14:57.828263Z","shell.execute_reply.started":"2022-02-15T20:14:57.823064Z","shell.execute_reply":"2022-02-15T20:14:57.827277Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Path\n","metadata":{}},{"cell_type":"code","source":"path = '/kaggle/input/birdclef-2022/'\nos.listdir(path)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:44:33.244489Z","iopub.execute_input":"2022-02-15T19:44:33.245346Z","iopub.status.idle":"2022-02-15T19:44:33.252511Z","shell.execute_reply.started":"2022-02-15T19:44:33.245298Z","shell.execute_reply":"2022-02-15T19:44:33.251891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load Data","metadata":{}},{"cell_type":"code","source":"train_meta = pd.read_csv(path+'train_metadata.csv')\ntest_data = pd.read_csv(path+'test.csv')\nebird_data = pd.read_csv(path+'eBird_Taxonomy_v2021.csv')\nsamp_subm = pd.read_csv(path+'sample_submission.csv')\n\nwith open(path+'scored_birds.json') as f:\n    scored_birds = json.load(f)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:45:19.08112Z","iopub.execute_input":"2022-02-15T19:45:19.081391Z","iopub.status.idle":"2022-02-15T19:45:19.204725Z","shell.execute_reply.started":"2022-02-15T19:45:19.08136Z","shell.execute_reply":"2022-02-15T19:45:19.20391Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Funcions\nWe load some helper functions.","metadata":{}},{"cell_type":"code","source":"def read_ogg_file(path, file):\n    \"\"\" Read ogg audio file and return numpay array and samplerate\"\"\"\n    \n    data, samplerate = sf.read(path+file)\n    return data, samplerate\n\n\ndef plot_audio_file(data, samplerate):\n    \"\"\" Plot the audio data\"\"\"\n    \n    sr = samplerate\n    fig = plt.figure(figsize=(8, 4))\n    x = range(len(data))\n    y = data\n    plt.plot(x, y)\n    plt.plot(x, y, color='red')\n    plt.legend(loc='upper center')\n    plt.grid()\n    \n    \ndef plot_spectrogram(data, samplerate):\n    \"\"\" Plot spectrogram with mel scaling \"\"\"\n    \n    sr = samplerate\n    spectrogram = librosa.feature.melspectrogram(y=data, sr=sr)\n    log_spectrogram = librosa.power_to_db(spectrogram, ref=np.max)\n    librosa.display.specshow(log_spectrogram, sr=sr, x_axis='time', y_axis='mel')","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:57:44.18346Z","iopub.execute_input":"2022-02-15T19:57:44.183893Z","iopub.status.idle":"2022-02-15T19:57:44.192052Z","shell.execute_reply.started":"2022-02-15T19:57:44.183828Z","shell.execute_reply":"2022-02-15T19:57:44.190837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Overview <a name=\"Overview\"></a>\n**train_metadata.csv** - A wide range of metadata is provided for the training data. The most directly relevant fields are:\n\n* primary_label - a code for the bird species. You can review detailed information about the bird codes by appending the code to https://ebird.org/species/, such as https://ebird.org/species/amecro for the American Crow.\n* secondary_labels: Background species as annotated by the recordist. An empty list does not mean that no background birds are audible.\n* author - the eBird user who provided the recording.\n* filename: the associated audio file.\n* rating: Float value between 0.0 and 5.0 as an indicator of the quality rating on Xeno-canto and the number of background species, where 5.0 is the highest and 1.0 is the lowest. 0.0 means that this recording has no user rating yet.","metadata":{}},{"cell_type":"code","source":"train_meta.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:35:45.356676Z","iopub.execute_input":"2022-02-15T19:35:45.357476Z","iopub.status.idle":"2022-02-15T19:35:45.37576Z","shell.execute_reply.started":"2022-02-15T19:35:45.357434Z","shell.execute_reply":"2022-02-15T19:35:45.374945Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**train_audio/** - The bulk of the training data consists of short recordings of individual bird calls generously uploaded by users of xenocanto.org. These files have been downsampled to 32 kHz where applicable to match the test set audio and converted to the ogg format.","metadata":{}},{"cell_type":"code","source":"print('Number of subfolders/species:', len(os.listdir(path+'train_audio')))","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:41:11.347935Z","iopub.execute_input":"2022-02-15T19:41:11.348264Z","iopub.status.idle":"2022-02-15T19:41:11.355176Z","shell.execute_reply.started":"2022-02-15T19:41:11.34823Z","shell.execute_reply":"2022-02-15T19:41:11.354104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**test_soundscapes/** - When you submit a notebook, the test_soundscapes directory will be populated with approximately 5,500 recordings to be used for scoring. These are each within a few milliseconds of 1 minute long and in the ogg audio format. Only one soundscape is available for download.","metadata":{}},{"cell_type":"code","source":"os.listdir(path+'test_soundscapes')","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:41:49.76389Z","iopub.execute_input":"2022-02-15T19:41:49.76467Z","iopub.status.idle":"2022-02-15T19:41:49.776749Z","shell.execute_reply.started":"2022-02-15T19:41:49.764627Z","shell.execute_reply":"2022-02-15T19:41:49.776097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**test.csv** - Metadata for the test set. Only the first three rows are available for download; the full test.csv is provided in the hidden test set.\n\n* row_id - A unique identifier for the row.\n* file_id - A unique identifier for the audio file.\n* bird - The ebird code for the row. There is one row for each of the scored species per 5 second window per audio file.\n* end_time - The last second of the 5 second time window (5, 10, 15, etc).","metadata":{}},{"cell_type":"code","source":"test_data.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:36:23.10839Z","iopub.execute_input":"2022-02-15T19:36:23.109025Z","iopub.status.idle":"2022-02-15T19:36:23.121041Z","shell.execute_reply.started":"2022-02-15T19:36:23.108966Z","shell.execute_reply":"2022-02-15T19:36:23.120148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**sample_submission.csv** - A valid sample submission. Only the first three rows are available for download; the full submission.csv is provided in the hidden test set.\n\n* row_id - A unique identifier for the row.\n* target - True/False for whether or not the bird in question called during the 5 second window.","metadata":{}},{"cell_type":"code","source":"samp_subm","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:42:26.685013Z","iopub.execute_input":"2022-02-15T19:42:26.685322Z","iopub.status.idle":"2022-02-15T19:42:26.696234Z","shell.execute_reply.started":"2022-02-15T19:42:26.685292Z","shell.execute_reply":"2022-02-15T19:42:26.695253Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**scored_birds.json** - The subset of the species in the dataset that are scored.","metadata":{}},{"cell_type":"code","source":"scored_birds[0:5]","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:45:52.03993Z","iopub.execute_input":"2022-02-15T19:45:52.040511Z","iopub.status.idle":"2022-02-15T19:45:52.047417Z","shell.execute_reply.started":"2022-02-15T19:45:52.040463Z","shell.execute_reply":"2022-02-15T19:45:52.046594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**eBird_Taxonomy_v2021.csv** - Data on the relationships between different species.","metadata":{}},{"cell_type":"code","source":"ebird_data.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:48:18.338448Z","iopub.execute_input":"2022-02-15T19:48:18.339238Z","iopub.status.idle":"2022-02-15T19:48:18.354424Z","shell.execute_reply.started":"2022-02-15T19:48:18.339192Z","shell.execute_reply":"2022-02-15T19:48:18.35336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# A Sample File <a name=\"SampleFile\"></a>\nWe focus on the sample in the first row of the train meta data.","metadata":{}},{"cell_type":"code","source":"row = 0\ntrain_meta.iloc[row]","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:50:19.279633Z","iopub.execute_input":"2022-02-15T19:50:19.279933Z","iopub.status.idle":"2022-02-15T19:50:19.287095Z","shell.execute_reply.started":"2022-02-15T19:50:19.279901Z","shell.execute_reply":"2022-02-15T19:50:19.286273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We extract to features, the primary label which is the name of the folder where the audio file is stored and the filename:","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:50:31.704081Z","iopub.execute_input":"2022-02-15T19:50:31.704848Z","iopub.status.idle":"2022-02-15T19:50:31.710606Z","shell.execute_reply.started":"2022-02-15T19:50:31.704809Z","shell.execute_reply":"2022-02-15T19:50:31.709827Z"}}},{"cell_type":"code","source":"label = train_meta.loc[row, 'primary_label']\nfilename = train_meta.loc[row, 'filename']\n\nprint(filename)\n# Check if the file is in the folder\nfilename.split('/')[1] in os.listdir(path+'train_audio/'+label)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:52:58.289451Z","iopub.execute_input":"2022-02-15T19:52:58.289712Z","iopub.status.idle":"2022-02-15T19:52:58.297625Z","shell.execute_reply.started":"2022-02-15T19:52:58.289685Z","shell.execute_reply":"2022-02-15T19:52:58.29694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data, samplerate = sf.read(path+'train_audio/'+filename)\nprint('snipe of data:', data[:4])\nprint('samplerate:', samplerate)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:54:35.196543Z","iopub.execute_input":"2022-02-15T19:54:35.197086Z","iopub.status.idle":"2022-02-15T19:54:35.21948Z","shell.execute_reply.started":"2022-02-15T19:54:35.197038Z","shell.execute_reply":"2022-02-15T19:54:35.218878Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_audio_file(data, samplerate)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:55:00.512197Z","iopub.execute_input":"2022-02-15T19:55:00.512883Z","iopub.status.idle":"2022-02-15T19:55:01.205319Z","shell.execute_reply.started":"2022-02-15T19:55:00.512831Z","shell.execute_reply":"2022-02-15T19:55:01.204671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Plot [spectrogram](https://en.wikipedia.org/wiki/Spectrogram) with mel scaling:","metadata":{}},{"cell_type":"code","source":"plot_spectrogram(data, samplerate)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:57:51.379765Z","iopub.execute_input":"2022-02-15T19:57:51.380309Z","iopub.status.idle":"2022-02-15T19:57:51.988041Z","shell.execute_reply.started":"2022-02-15T19:57:51.380274Z","shell.execute_reply":"2022-02-15T19:57:51.986933Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Listen to the bird:","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:58:28.369607Z","iopub.execute_input":"2022-02-15T19:58:28.370125Z","iopub.status.idle":"2022-02-15T19:58:28.376407Z","shell.execute_reply.started":"2022-02-15T19:58:28.370074Z","shell.execute_reply":"2022-02-15T19:58:28.375105Z"}}},{"cell_type":"code","source":"display.Audio(path+'train_audio/'+filename)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:58:48.795018Z","iopub.execute_input":"2022-02-15T19:58:48.79549Z","iopub.status.idle":"2022-02-15T19:58:48.807588Z","shell.execute_reply.started":"2022-02-15T19:58:48.795445Z","shell.execute_reply":"2022-02-15T19:58:48.806761Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Exploratory Data Analysis <a name=\"EDA\"></a>\nThere are 152 primary lables and 152 common names. Both are related. The labels are not evenly distributed.","metadata":{}},{"cell_type":"code","source":"train_meta['primary_label'].value_counts()[0:5]","metadata":{"execution":{"iopub.status.busy":"2022-02-15T20:05:54.523802Z","iopub.execute_input":"2022-02-15T20:05:54.524126Z","iopub.status.idle":"2022-02-15T20:05:54.533583Z","shell.execute_reply.started":"2022-02-15T20:05:54.524096Z","shell.execute_reply":"2022-02-15T20:05:54.532757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_meta['common_name'].value_counts()[0:5]","metadata":{"execution":{"iopub.status.busy":"2022-02-15T20:05:58.028643Z","iopub.execute_input":"2022-02-15T20:05:58.029138Z","iopub.status.idle":"2022-02-15T20:05:58.040757Z","shell.execute_reply.started":"2022-02-15T20:05:58.029095Z","shell.execute_reply":"2022-02-15T20:05:58.039865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Focus On Labels <a name=\"FocusOnLabels\"></a>\nThe secondary label is a string representation of list.","metadata":{}},{"cell_type":"code","source":"row = 1\nprint('original type:',  type(train_meta.loc[row, 'secondary_labels']))\nprint('converted type:', type(ast.literal_eval(train_meta.loc[row, 'secondary_labels'])))","metadata":{"execution":{"iopub.status.busy":"2022-02-15T20:17:54.197474Z","iopub.execute_input":"2022-02-15T20:17:54.198247Z","iopub.status.idle":"2022-02-15T20:17:54.204274Z","shell.execute_reply.started":"2022-02-15T20:17:54.1982Z","shell.execute_reply":"2022-02-15T20:17:54.203211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We convert all label of the train data:","metadata":{}},{"cell_type":"code","source":"labels = []\nfor row in train_meta.index:\n    labels.extend(ast.literal_eval(train_meta.loc[row, 'secondary_labels']))\nlabels = list(set(labels))\n\nprint('Number of unique bird labels:', len(labels))","metadata":{"execution":{"iopub.status.busy":"2022-02-15T20:19:04.921171Z","iopub.execute_input":"2022-02-15T20:19:04.921748Z","iopub.status.idle":"2022-02-15T20:19:05.142009Z","shell.execute_reply.started":"2022-02-15T20:19:04.921693Z","shell.execute_reply":"2022-02-15T20:19:05.141144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Audio Data Generator <a name=\"AudioDataGenerator\"></a>\nWe use a Data Generator to load the data on demand.\n\n**Coming Soon**","metadata":{}},{"cell_type":"markdown","source":"# Export","metadata":{}},{"cell_type":"code","source":"samp_subm['target'] = True\nsamp_subm.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:43:34.195733Z","iopub.execute_input":"2022-02-15T19:43:34.196043Z","iopub.status.idle":"2022-02-15T19:43:34.212237Z","shell.execute_reply.started":"2022-02-15T19:43:34.196013Z","shell.execute_reply":"2022-02-15T19:43:34.211578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"samp_subm.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:27:20.971654Z","iopub.execute_input":"2022-02-15T19:27:20.972213Z","iopub.status.idle":"2022-02-15T19:27:20.979909Z","shell.execute_reply.started":"2022-02-15T19:27:20.972159Z","shell.execute_reply":"2022-02-15T19:27:20.978981Z"},"trusted":true},"execution_count":null,"outputs":[]}]}