{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":19596,"databundleVersionId":1292430,"sourceType":"competition"},{"sourceId":8447027,"sourceType":"datasetVersion","datasetId":5033383}],"dockerImageVersionId":29955,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Data Visualization and Sound Processing Tutorial !\n\nThis notebook is created for beginners to take a look of this competition dataset and how to process sound data.  \nThis is my first time to tackle with sound data competition, so I refered some other articles.\n\n1st public version: 04, Jul, 2020.\n\nHere is table of contents:\n- [Library Import and Data Check](#Library-Import-and-Data-Check)\n- [Data Visualization](#Data-Visualization)\n    - [General Information and Visualization](#General-Information-and-Visualization)\n    - [Location Information and Visualization](#Location-Information-and-Visualization)\n- [Sound Processing](#Sound-Processing)\n- [Reference](#Reference)","metadata":{}},{"cell_type":"markdown","source":"# Library Import and Data Check","metadata":{}},{"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    # skip audio file\n    if 'train_audio' in dirname:\n        continue\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 5GB 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_count":null,"outputs":[]},{"cell_type":"code","source":"# For Visualization Library\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n%matplotlib inline\nsns.set()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install folium","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install pydub","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create a world map to show distributions of birds\nimport folium\nfrom folium.plugins import MarkerCluster\nimport plotly.express as px\n\n# Machine Learning\nfrom sklearn import model_selection\n\n# Sound processing library\nimport librosa.display","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Sound Processing Library\nimport pydub\nfrom io import BytesIO\nfrom IPython.display import Audio, display\nimport soundfile as sf","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Data Read and Check\nINPUT_DIR = \"/kaggle/input/birdsong-recognition/\"\ntrain_df = pd.read_csv(INPUT_DIR + \"train.csv\")\ntest_df = pd.read_csv(INPUT_DIR + \"test.csv\")\ntrain_df.head()","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In the train.csv, we have metadata of each sound records.  \nFron now on, we'll investigate this metadata deeper and deeper.","metadata":{}},{"cell_type":"code","source":"# We can get column information by using .columns\ntrain_df.columns","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# We can get more specific information by using .info() method\n# Using this method, we can get column_name, non_null count, and dtype of each column.\ntrain_df.info()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# On the contrary, we have less columns in the test.csv\n# We have site, row_id, seconds, and audio_id columns.\ntest_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Regarding example data, we take a look later.\n# We should learn how to use these information for submission later.\n\nexample_audio_summary_df = pd.read_csv(INPUT_DIR + \"example_test_audio_summary.csv\")\nexample_audio_metadata_df = pd.read_csv(INPUT_DIR + \"example_test_audio_metadata.csv\")\nexample_audio_summary_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Submission format\n# We should predict birds column in each row_id.\n\nsample_submission_df = pd.read_csv(INPUT_DIR + \"sample_submission.csv\")\nsample_submission_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Visualization\n\nFron now on, we try to visualize metadata information of train dataset.   \nFirst we only use train.csv information and process sound data in the next section.\n\n## General Information and Visualization","metadata":{}},{"cell_type":"code","source":"# countplot method of seaborn is quite useful to visualize the number of counts in one column.\nsns.countplot(\"rating\", data=train_df)\nplt.title(\"Record Counts in each Rating\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The highest rating 5.0 has the most records compared to others.  \nWe have 0.0 rating, but it seems we don't have not so many records with rating 0.5 and 1.0.","metadata":{}},{"cell_type":"code","source":"sns.countplot(\"playback_used\", data=train_df)\nplt.title(\"Record Counts in playback_used flag\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Most of the data don't use playback.","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(18, 6))\nsns.countplot(\"ebird_code\", data=train_df)\nplt.xticks(rotation=90)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We have 264 kinds of birds in this dataset.  \nMany kinds of these birds have 100 counts, some have less than 100 counts.","metadata":{}},{"cell_type":"code","source":"sns.countplot(\"channels\", data=train_df)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"About channel, 1 (mono) channel has a little bit more counts than 2 (stereo).","metadata":{}},{"cell_type":"code","source":"# groupby method is quite useful to calculate metrics by column data.\ntemp_series= train_df.groupby(\"date\")[\"xc_id\"].count()\ntemp_series","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"temp_series.index","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Processing date column (convert date column from object type to datetime type\n# \n# Usually, we can use .astype method like below:\n# df[\"date\"] = df[\"date\"].astype(\"datetime64[ns]\")\n# \n# but we have some illegal input in this dataset, so I arranged a little bit.\n\nidx_list = []\n\nfor idx in temp_series.index:\n    new_idx = idx\n    \n    # Year before 1970 is converted into 1970\n    if idx[:4] <= '1970':\n        new_idx = '1970-01-01' \n    \n    # Month should be between 1 and 12.\n    if idx[5:7] == '00':\n        new_idx = new_idx[:5] + '01' + new_idx[7:]\n    \n    # Day should be at least 01 (Not 00)\n    if idx[8:] == '00':\n        new_idx = new_idx[:8] + '01'\n    \n    idx_list.append(new_idx)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"temp_series.index = idx_list\ntemp_series.index = temp_series.index.astype(\"datetime64[ns]\")\ntemp_series","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Now we can plot counts in each year.\ntemp_series.plot(figsize=(10,4))\nplt.xlabel(\"Year\")\nplt.ylabel(\"Record Count\")\nplt.title(\"Record Count Transition\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Recently we have more records than the past few decades.","metadata":{}},{"cell_type":"code","source":"sns.distplot(train_df[\"duration\"])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The distribution of this duration column in this dataset is seemed to be possion one.  \nThat is, we have many short uration data in the shorter duration, and less super-long duration data.","metadata":{}},{"cell_type":"code","source":"train_df[\"pitch\"].unique()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"column_value = ['Not specified', 'both', 'increasing', 'level', 'decreasing']\n\nfig, axs = plt.subplots(1,3, sharey=True, figsize=(8, 4))\nsns.countplot(train_df[\"pitch\"], ax=axs[0])\nsns.countplot(train_df[\"speed\"], ax=axs[1])\nsns.countplot(train_df[\"volume\"], ax=axs[2])\naxs[0].set_xticklabels(column_value, rotation=90)\naxs[1].set_xticklabels(column_value, rotation=90)\naxs[2].set_xticklabels(column_value, rotation=90)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train_df[\"species\"].unique())\nprint(\"The number of spicies is {}.\".format(train_df[\"species\"].nunique()))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The number of spicies is 264, as we've checked when we visualized ebird_code countplot","metadata":{}},{"cell_type":"code","source":"sns.countplot(train_df[\"number_of_notes\"])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The number of notes in most part of the dataset is \"Not-specified\".  \nHowever we have some values with number of notes.","metadata":{}},{"cell_type":"code","source":"train_df[\"secondary_labels\"]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.countplot(train_df[\"bird_seen\"])\nprint(\"Bird seen yes is {}\".\n      format(len(train_df[train_df[\"bird_seen\"] == \"yes\"]) / len(train_df)))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Bird_seen of most of the record is yes. (About 76 %)","metadata":{}},{"cell_type":"code","source":"train_df[\"sci_name\"].nunique()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df[\"location\"].nunique()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df[\"sampling_rate\"].unique()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"order=['48000 (Hz)', '44100 (Hz)', '32000 (Hz)', '24000 (Hz)',\n       '22050 (Hz)', '16000 (Hz)', '11025 (Hz)', '8000 (Hz)']\nsns.countplot(train_df[\"sampling_rate\"], order=order)\nplt.xticks(rotation=60)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Most of the sampling rate is 44100 Hz or 48000 Hz.","metadata":{}},{"cell_type":"code","source":"train_df[\"type\"].unique()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df[\"description\"]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.distplot(train_df[\"bitrate_of_mp3\"].str[:-6], kde=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"As for bitrate of mp3 information, most of the parts is around 125,000 (bps).","metadata":{}},{"cell_type":"code","source":"sns.countplot(train_df[\"file_type\"])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Most of the files are .mp3 type.","metadata":{}},{"cell_type":"code","source":"train_df[\"background\"]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.countplot(train_df[\"length\"], order=[\"Not specified\", \"0-3(s)\", \"3-6(s)\", \"6-10(s)\", \">10(s)\"])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Location Information and Visualization\n\nThis is the reference of this subsection\n- https://python-graph-gallery.com/310-basic-map-with-markers/ \n- https://plotly.com/python/bubble-maps/","metadata":{}},{"cell_type":"code","source":"sns.distplot(train_df.loc[train_df[\"latitude\"] != \"Not specified\", \"latitude\"])\nplt.title(\"Distribution of Latitude\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The latitude of the records is concentrated around between 20 and 60 degrees.","metadata":{}},{"cell_type":"code","source":"sns.distplot(train_df.loc[train_df[\"longitude\"] != \"Not specified\", \"longitude\"])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Regarding longitude, the most part of the records are bretween -150 and -50 degrees. (Around United States)","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(8, 4))\nsns.countplot(train_df[\"country\"])\nplt.xticks(rotation=90)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"It seems United States has huge amounts of records.","metadata":{}},{"cell_type":"code","source":"# Extract only necessesary information\ntemp_df = train_df.loc[(train_df[\"latitude\"] != 'Not specified') & (train_df[\"longitude\"] != 'Not specified'), \n                       [\"country\", \"latitude\", \"longitude\", \"xc_id\", \"ebird_code\"]]\n\n# Convert to float type\ntemp_df[\"latitude\"] = temp_df[\"latitude\"].astype(\"float\")\ntemp_df[\"longitude\"] = temp_df[\"longitude\"].astype(\"float\")\ntemp_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# From now on, we plot worldmap and visualize which countries have many records. \ndraw_df = temp_df.groupby(\"country\")[[\"latitude\", \"longitude\"]].mean()\ndraw_df = pd.concat([draw_df, temp_df.groupby(\"country\")[\"xc_id\"].count()], axis=1)\ndraw_df = draw_df.rename(columns={\"xc_id\":\"count\"})\ndraw_df = draw_df.reset_index()\ndraw_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#empty map\nworld_map= folium.Map(tiles=\"cartodbpositron\")\nmarker_cluster = MarkerCluster().add_to(world_map)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#for each coordinate, create circlemarker of user percent\nfor i in range(len(draw_df)):\n        lat = draw_df.iloc[i]['latitude']\n        long = draw_df.iloc[i]['longitude']\n        radius= draw_df.iloc[i][\"count\"] / len(draw_df)\n        popup_text = \"\"\"Country : {}<br>\n                    Counts : {}<br>\"\"\"\n        popup_text = popup_text.format(draw_df.iloc[i]['country'],\n                                   draw_df.iloc[i]['count']\n                                   )\n        folium.CircleMarker(location = [lat, long], radius=radius, popup= popup_text, fill =True).add_to(marker_cluster)\n#show the map\nworld_map","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Make an empty map\nm = folium.Map(location=[20,0], tiles=\"Mapbox Bright\", zoom_start=2)\n \n# I can add marker one by one on the map\nfor i in range(len(draw_df)):\n   folium.Circle(\n      location=[draw_df.iloc[i]['longitude'], draw_df.iloc[i]['latitude']],\n      popup=draw_df.iloc[i]['country'],\n      radius=draw_df.iloc[i]['count'] / len(draw_df) * 10,\n      color='crimson',\n      fill=True,\n      fill_color='crimson'\n   ).add_to(m)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"draw_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = px.scatter_geo(draw_df, lat=\"latitude\", lon= \"longitude\", color=\"country\",\n                     hover_name=\"country\", size=\"count\",\n                     projection=\"natural earth\")\nfig.update_geos(\n    visible=False, resolution=50,\n    showcountries=True, countrycolor=\"RebeccaPurple\"\n)\nfig","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This world map is showing which countries have many records.  \nAs we've seen before, United States is the most recorded place.","metadata":{}},{"cell_type":"code","source":"grid_by_bird_df = temp_df.groupby(\"ebird_code\")[[\"latitude\", \"longitude\"]].mean()\ngrid_by_bird_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.scatterplot(y=grid_by_bird_df.iloc[:, 0], x=grid_by_bird_df.iloc[:, 1], hue=grid_by_bird_df.index)\nplt.ylim([-90, 90])\nplt.xlim([-180, 180])\nplt.legend(bbox_to_anchor=(1.01, 1.01), ncol=10)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.columns","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from wordcloud import WordCloud","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wordcloud = WordCloud(background_color=\"white\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wordcloud.generate_from_text(\" \".join(list(train_df.loc[train_df[\"description\"].notnull(), \"description\"])))\nplt.imshow(wordcloud)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"It seems we have some records that are through high pass filter in the dataset. ","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\" \".join(list(train_df.loc[train_df[\"description\"].notnull(), \"description\"]))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Sound Processing\n\nFrom now on, I'll try to process sound data!  \nI refered some articles and codes to write the cells below.  \n- https://github.com/ipython-books/cookbook-2nd-code/blob/master/chapter11_image/06_speech.ipynb\n- https://dev.to/apoorvadave/environmental-sound-classification-1hhl\n- https://blog.brainpad.co.jp/entry/2018/04/17/143000 (In Japanese Only)","metadata":{}},{"cell_type":"code","source":"mp3_filename = \"/kaggle/input/birdsong-recognition/train_audio/aldfly/XC134874.mp3\"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"pydub is a library which can process sound data in python.","metadata":{}},{"cell_type":"code","source":"# Read sound file \naudio = pydub.AudioSegment.from_mp3(mp3_filename)\n\n# Convert mp3 data into wave data \nwave = audio.export('_', format=\"wav\")\nwave.seek(0)\nwave = wave.read()\n\n# We get the raw data by removing first 24 bytes of the header.\nX = np.frombuffer(wave, np.int16)[24:] / 2.**15","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# This function allows us to play sound data in jupyter notebook\n\ndef play(x, fr, autoplay=False):\n    display(Audio(x, rate=fr, autoplay=autoplay))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# We can get sampling rate by accesing like below\nint(train_df.loc[train_df[\"xc_id\"] == 134874, \"sampling_rate\"].str[:-4])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# This cell outputs the widget to play sound.\nplay(X, fr=48000, autoplay=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Sound wave plot\nfr = 48000\nt = np.linspace(0, len(X) / fr, len(X))\nplt.plot(t, X, lw=1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# n_mels is number of Mel bands to generate\nn_mels=128\n# hop_length is number of samples between successive frames.\nhop_length=2068\n# n_fft is length of the FFT window\nn_fft=2048\n# Passing through arguments to the Mel filters\nS = librosa.feature.melspectrogram(y=X, sr=44000, n_mels=n_mels, hop_length=hop_length, n_fft=n_fft)\n\nlog_S = librosa.power_to_db(S)\nprint(log_S.shape)\n\nplt.figure(figsize=(12, 4))\nlibrosa.display.specshow(data=log_S, sr=44000, hop_length=hop_length, x_axis='time', y_axis='mel')\nplt.colorbar(format='%+2.0f dB')\nplt.title('Mel spectrogram')\nplt.tight_layout()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This plot shows the strength of each Hz in each time.  \nThat is, for example, around 5 seconds, sound of 2048 ~ 4096 Hz is slightly louder than other sounds of Hz.  \n\nThis result can be used as an image, and image processing model can be used with this result.\n\nLet's see how this plot differs from each other.  \nTo do that, I define some functions.","metadata":{}},{"cell_type":"code","source":"def get_features(filename, sampling_rate):\n    \"\"\"\n    This function returns mel-frequency cepstrum from its filename and sampling rate\n    \n    Parameters\n    ----------\n    filename : string\n        target filename path\n    sampling_rate : int\n        target filename sampling rate\n\n    Returns\n    -------\n    mfccs_scaled : np.array\n        mel-frequency cepstrum \n    \"\"\"\n\n    if filename: \n        audio = pydub.AudioSegment.from_mp3(filename)\n\n        wave = audio.export('_', format=\"wav\")\n        wave.seek(0)\n        wave = wave.read()\n\n        X = np.frombuffer(wave, np.int16)[24:] / 2.**15\n    \n        sr= sampling_rate\n\n    # mfcc (mel-frequency cepstrum)\n    mfccs = librosa.feature.mfcc(y=X, sr=sr, n_mfcc=40)\n    mfccs_scaled = np.mean(mfccs.T,axis=0)\n    \n    \"\"\"\n    Result Visualization Part\n    \"\"\"\n    play(X, fr=sr, autoplay=False)\n    \n    # n_mels is number of Mel bands to generate\n    n_mels=128\n    # hop_length is number of samples between successive frames.\n    hop_length=2068\n    # n_fft is length of the FFT window\n    n_fft=2048\n    # Passing through arguments to the Mel filters\n    S = librosa.feature.melspectrogram(y=X, sr=sampling_rate, n_mels=n_mels, hop_length=hop_length, n_fft=n_fft)\n    \n    log_S = librosa.power_to_db(S)\n\n    plt.figure(figsize=(12, 4))\n    librosa.display.specshow(data=log_S, sr=sampling_rate, hop_length=hop_length, x_axis='time', y_axis='mel')\n    plt.colorbar(format='%+2.0f dB')\n    plt.title('Mel spectrogram')\n    plt.tight_layout()\n        \n    return mfccs_scaled","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def extract_features(target_df):\n    \"\"\"\n    This function returns mel-frequency cepstrum result of all train dataset\n    \n    Parameters\n    ----------\n    target_df: pandas.DataFrame\n        DataFrame of train dataset\n    \n    Returns\n    -------\n    features_df : pandas.DataFrame\n        mel-frequency cepstrum result\n    \"\"\"\n    features_list = []\n    features_df = pd.DataFrame()\n    \n    for idx in target_df.index:\n        if idx % 100 == 0:\n            print(idx)\n        \n        sampling_rate = int(target_df.loc[target_df.index == idx, \"sampling_rate\"].str[:-4])\n        bird_name = list(target_df.loc[target_df.index == idx, \"ebird_code\"])[0]\n        xc_id = list(target_df.loc[target_df.index == idx, \"xc_id\"])[0]\n        \n        filename = INPUT_DIR + \"train_audio/\" + bird_name + \"/XC\" + str(xc_id) + \".mp3\"\n        \n        try:\n            mfccs = get_features(filename, sampling_rate)\n        except Exception as e:\n            print(\"Extraction error at {}\".format(idx))\n            continue\n        features_list.append([mfccs, bird_name])\n    \n    features_df = pd.DataFrame(features_list,columns = ['feature','class_label']) \n    return features_df\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ebird_idx_list = [0]\nebird_origin = \"aldfly\"\n\nfor idx in train_df.index:\n    if train_df.loc[idx, \"ebird_code\"] != ebird_origin:\n        ebird_idx_list.append(idx)\n        ebird_origin = train_df.loc[idx, \"ebird_code\"]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"extract_features(target_df=train_df.iloc[ebird_idx_list[:5], :])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"You can directly listen to bird call with jupyter notebook.  \nAnd when you click play button, you can recognize that each bird sound differs from each other.  \nAlso, you can see the differences by seeing the mel spectogram plot.  \nFor example, when you listen to the fifth sound, around 0:20 ~ 0:35 seconds, birds call actively.  \nThe fifth mel spectogram also shows around that time, a loud sound is recorded between 1024 ~ 4096 Hz. ","metadata":{}},{"cell_type":"code","source":"def get_features(filename, sampling_rate):\n    \"\"\"\n    This function returns mel-frequency cepstrum from its filename and sampling rate\n    \n    Parameters\n    ----------\n    filename : string\n        target filename path\n    sampling_rate : int\n        target filename sampling rate\n\n    Returns\n    -------\n    mfccs_scaled : np.array\n        mel-frequency cepstrum \n    \"\"\"\n\n    if filename: \n        audio = pydub.AudioSegment.from_mp3(filename)\n\n        wave = audio.export('_', format=\"wav\")\n        wave.seek(0)\n        wave = wave.read()\n\n        X = np.frombuffer(wave, np.int16)[24:] / 2.**15\n    \n        sr= sampling_rate\n\n    # mfcc (mel-frequency cepstrum)\n    mfccs = librosa.feature.mfcc(y=X, sr=sr, n_mfcc=40)\n    mfccs_scaled = np.mean(mfccs.T,axis=0)\n    \n   \n        \n    return mfccs_scaled","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def extract_features(target_df):\n    \"\"\"\n    This function returns mel-frequency cepstrum result of all train dataset\n    \n    Parameters\n    ----------\n    target_df: pandas.DataFrame\n        DataFrame of train dataset\n    \n    Returns\n    -------\n    features_df : pandas.DataFrame\n        mel-frequency cepstrum result\n    \"\"\"\n    features_list = []\n    features_df = pd.DataFrame()\n    \n    for idx in target_df.index:\n        if idx % 100 == 0:\n            print(idx)\n        \n        sampling_rate = int(target_df.loc[target_df.index == idx, \"sampling_rate\"].str[:-4])\n        bird_name = list(target_df.loc[target_df.index == idx, \"ebird_code\"])[0]\n        xc_id = list(target_df.loc[target_df.index == idx, \"xc_id\"])[0]\n        \n        filename = INPUT_DIR + \"train_audio/\" + bird_name + \"/XC\" + str(xc_id) + \".mp3\"\n        \n        try:\n            mfccs = get_features(filename, sampling_rate)\n        except Exception as e:\n            print(\"Extraction error at {}\".format(idx))\n            continue\n        features_list.append([mfccs, bird_name])\n    \n    features_df = pd.DataFrame(features_list,columns = ['feature','class_label']) \n    return features_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Warning! \nThe cell below takes time!","metadata":{}},{"cell_type":"code","source":"%%time\nfeatures_df = extract_features(train_df)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"features_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Save DataFrame and you can use it with other kernels by input this notebook output.  \n# With this dataframe, you can create models like CNN.\nfeatures_df.to_pickle(\"train_data.pkl\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"example_audio_metadata_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"example_audio_summary_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"filename = \"../input/birdsong-recognition/example_test_audio/BLKFR-10-CPL_20190611_093000.pt540.mp3\"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"audio = pydub.AudioSegment.from_mp3(filename)\n\nwave = audio.export('_', format=\"wav\")\nwave.seek(0)\nwave = wave.read()\n\nX = np.frombuffer(wave, np.int16)[24:] / 2.**15\n    \nsr= 22000","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"play(X, sr, False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Reference\n\nHere is the reference of this notebook.\n- https://github.com/ipython-books/cookbook-2nd-code/blob/master/chapter11_image/06_speech.ipynb\n- https://dev.to/apoorvadave/environmental-sound-classification-1hhl\n- https://blog.brainpad.co.jp/entry/2018/04/17/143000 (In Japanese Only)\n- https://python-graph-gallery.com/310-basic-map-with-markers/ \n- https://plotly.com/python/bubble-maps/\n\n# Acknowledgement\n\nThank you for reading this notebook.  \nI know my notebook isn't complete accurate, but I hope this notebook works as a clue for beginners.  \nAny comments and upvotes are very welcome, Thank you !!","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Crime Analytics - Incident Reports","metadata":{}},{"cell_type":"code","source":"import pandas as pd\n\nsf_data = pd.read_csv('/kaggle/input/datavisualizationguide/sanfrancisco_incidents_summer_2014.csv')\n\nseattle_data = pd.read_csv('/kaggle/input/datavisualizationguide/seattle_incidents_summer_2014.csv')\n\nsf_data.head(), seattle_data.head()\n","metadata":{"execution":{"iopub.status.busy":"2024-05-18T04:30:57.398360Z","iopub.execute_input":"2024-05-18T04:30:57.399067Z","iopub.status.idle":"2024-05-18T04:30:57.804661Z","shell.execute_reply.started":"2024-05-18T04:30:57.399023Z","shell.execute_reply":"2024-05-18T04:30:57.803589Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# common incident categories in San Francisco\nsf_common_categories = sf_data['Category'].value_counts().head(10)\n\n# common incident categories in Seattle\nseattle_common_categories = seattle_data['Summarized Offense Description'].value_counts().head(10)\n\nsf_common_categories, seattle_common_categories\n","metadata":{"execution":{"iopub.status.busy":"2024-05-18T04:31:17.423278Z","iopub.execute_input":"2024-05-18T04:31:17.423648Z","iopub.status.idle":"2024-05-18T04:31:17.444857Z","shell.execute_reply.started":"2024-05-18T04:31:17.423616Z","shell.execute_reply":"2024-05-18T04:31:17.444034Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Incidents by police district in San Francisco\nsf_incidents_by_district = sf_data['PdDistrict'].value_counts()\n\n# Incidents by police district in Seattle\nseattle_incidents_by_district = seattle_data['District/Sector'].value_counts()\n\nsf_incidents_by_district, seattle_incidents_by_district\n","metadata":{"execution":{"iopub.status.busy":"2024-05-18T04:56:01.957180Z","iopub.execute_input":"2024-05-18T04:56:01.957565Z","iopub.status.idle":"2024-05-18T04:56:01.976354Z","shell.execute_reply.started":"2024-05-18T04:56:01.957534Z","shell.execute_reply":"2024-05-18T04:56:01.975189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# San Francisco robberies and thefts\nsf_robberies_thefts = sf_data[sf_data['Category'].isin(['ROBBERY', 'LARCENY/THEFT'])]['PdDistrict'].value_counts()\n\n# Seattle robberies and thefts\nseattle_robberies_thefts = seattle_data[seattle_data['Summarized Offense Description'].isin(['ROBBERY', 'THEFT'])]['District/Sector'].value_counts()\n\nsf_robberies_thefts, seattle_robberies_thefts\n","metadata":{"execution":{"iopub.status.busy":"2024-05-18T04:56:12.427433Z","iopub.execute_input":"2024-05-18T04:56:12.428182Z","iopub.status.idle":"2024-05-18T04:56:12.452707Z","shell.execute_reply.started":"2024-05-18T04:56:12.428125Z","shell.execute_reply":"2024-05-18T04:56:12.451785Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport seaborn as sns\n\n# most common incident categories\nplt.figure(figsize=(12, 6))\nsns.barplot(x=sf_common_categories.index, y=sf_common_categories.values, palette='viridis')\nplt.title('Top 10 Most Common Incident Categories in San Francisco')\nplt.xticks(rotation=45)\nplt.show()\n\nplt.figure(figsize=(12, 6))\nsns.barplot(x=seattle_common_categories.index, y=seattle_common_categories.values, palette='viridis')\nplt.title('Top 10 Most Common Incident Categories in Seattle')\nplt.xticks(rotation=45)\nplt.show()\n\n# Plotting incidents by district\nplt.figure(figsize=(12, 6))\nsns.barplot(x=sf_incidents_by_district.index, y=sf_incidents_by_district.values, palette='magma')\nplt.title('Incidents by Police District in San Francisco')\nplt.xticks(rotation=45)\nplt.show()\n\nplt.figure(figsize=(12, 6))\nsns.barplot(x=seattle_incidents_by_district.index, y=seattle_incidents_by_district.values, palette='magma')\nplt.title('Incidents by Police District in Seattle')\nplt.xticks(rotation=45)\nplt.show()\n\n# Plotting robberies and thefts by district\nplt.figure(figsize=(12, 6))\nsns.barplot(x=sf_robberies_thefts.index, y=sf_robberies_thefts.values, palette='plasma')\nplt.title('Robberies and Thefts by District in San Francisco')\nplt.xticks(rotation=45)\nplt.show()\n\nplt.figure(figsize=(12, 6))\nsns.barplot(x=seattle_robberies_thefts.index, y=seattle_robberies_thefts.values, palette='plasma')\nplt.title('Robberies and Thefts by District in Seattle')\nplt.xticks(rotation=45)\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-05-18T04:56:39.607458Z","iopub.execute_input":"2024-05-18T04:56:39.607853Z","iopub.status.idle":"2024-05-18T04:56:42.037090Z","shell.execute_reply.started":"2024-05-18T04:56:39.607817Z","shell.execute_reply":"2024-05-18T04:56:42.035996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Clean and prepare San Francisco data\nsf_data['Date'] = pd.to_datetime(sf_data['Date'])\nsf_data['Year'] = sf_data['Date'].dt.year\nsf_data['Month'] = sf_data['Date'].dt.month\n\n# Clean and prepare Seattle data\nseattle_data['Occurred Date or Date Range Start'] = pd.to_datetime(seattle_data['Occurred Date or Date Range Start'])\nseattle_data['Year'] = seattle_data['Occurred Date or Date Range Start'].dt.year\nseattle_data['Month'] = seattle_data['Occurred Date or Date Range Start'].dt.month\n\n# Filter data for the year 2014 \nsf_data_2014 = sf_data[sf_data['Year'] == 2014]\nseattle_data_2014 = seattle_data[seattle_data['Year'] == 2014]\n\n# total incidents\ntotal_sf_incidents = len(sf_data_2014)\ntotal_seattle_incidents = len(seattle_data_2014)\n\n# Population data\nsf_population = 837442\nseattle_population = 652405\n\n# incidents per capita\nsf_incidents_per_capita = total_sf_incidents / sf_population\nseattle_incidents_per_capita = total_seattle_incidents / seattle_population\n\nsf_incidents_per_capita, seattle_incidents_per_capita","metadata":{"execution":{"iopub.status.busy":"2024-05-18T05:00:16.887132Z","iopub.execute_input":"2024-05-18T05:00:16.887511Z","iopub.status.idle":"2024-05-18T05:00:16.942895Z","shell.execute_reply.started":"2024-05-18T05:00:16.887478Z","shell.execute_reply":"2024-05-18T05:00:16.941831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Most common categories in San Francisco\nsf_common_categories = sf_data_2014['Category'].value_counts(normalize=True).head(10)\n\n# Most common categories in Seattle\nseattle_common_categories = seattle_data_2014['Summarized Offense Description'].value_counts(normalize=True).head(10)\n\nsf_common_categories, seattle_common_categories\n","metadata":{"execution":{"iopub.status.busy":"2024-05-18T05:00:30.191935Z","iopub.execute_input":"2024-05-18T05:00:30.192373Z","iopub.status.idle":"2024-05-18T05:00:30.255150Z","shell.execute_reply.started":"2024-05-18T05:00:30.192327Z","shell.execute_reply":"2024-05-18T05:00:30.253606Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Incidents by police district in San Francisco\nsf_incidents_by_district = sf_data_2014['PdDistrict'].value_counts()\n\n# Incidents by police district in Seattle\nseattle_incidents_by_district = seattle_data_2014['District/Sector'].value_counts()\n\nsf_incidents_by_district, seattle_incidents_by_district\n","metadata":{"execution":{"iopub.status.busy":"2024-05-18T05:00:54.127202Z","iopub.execute_input":"2024-05-18T05:00:54.127912Z","iopub.status.idle":"2024-05-18T05:00:54.145030Z","shell.execute_reply.started":"2024-05-18T05:00:54.127846Z","shell.execute_reply":"2024-05-18T05:00:54.144118Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# most common categories\nplt.figure(figsize=(12, 6))\nsns.barplot(x=sf_common_categories.index, y=sf_common_categories.values, palette='viridis')\nplt.title('Top 10 Most Common Incident Categories in San Francisco')\nplt.xticks(rotation=45)\nplt.ylabel('Proportion of Total Incidents')\nplt.show()\n\nplt.figure(figsize=(12, 6))\nsns.barplot(x=seattle_common_categories.index, y=seattle_common_categories.values, palette='viridis')\nplt.title('Top 10 Most Common Incident Categories in Seattle')\nplt.xticks(rotation=45)\nplt.ylabel('Proportion of Total Incidents')\nplt.show()\n\n# Plot incidents by district\nplt.figure(figsize=(12, 6))\nsns.barplot(x=sf_incidents_by_district.index, y=sf_incidents_by_district.values, palette='magma')\nplt.title('Incidents by Police District in San Francisco')\nplt.xticks(rotation=45)\nplt.ylabel('Number of Incidents')\nplt.show()\n\nplt.figure(figsize=(12, 6))\nsns.barplot(x=seattle_incidents_by_district.index, y=seattle_incidents_by_district.values, palette='magma')\nplt.title('Incidents by Police District in Seattle')\nplt.xticks(rotation=45)\nplt.ylabel('Number of Incidents')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-05-18T05:01:04.847290Z","iopub.execute_input":"2024-05-18T05:01:04.848079Z","iopub.status.idle":"2024-05-18T05:01:05.789576Z","shell.execute_reply.started":"2024-05-18T05:01:04.847981Z","shell.execute_reply":"2024-05-18T05:01:05.788361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\n\n# synthetic Seattle crime data\ndates = pd.date_range(start='2014-06-01', end='2014-08-31', freq='D')\ncrime_types = ['BURGLARY', 'OTHER PROPERTY', 'FRAUD', 'ASSAULT', 'PICKPOCKET', \n               'STOLEN PROPERTY', 'MAIL THEFT', 'SHOPLIFTING', 'CAR PROWL', \n               'THREATS', 'TRAFFIC', 'EMBEZZLE', 'BIKE THEFT', 'PROPERTY DAMAGE', \n               'VEHICLE THEFT', 'COUNTERFEIT', 'WARRANT ARREST']\n\ndata = {\n    'Date': np.random.choice(dates, size=1000),\n    'Summarized Offense Description': np.random.choice(crime_types, size=1000)\n}\n\nseattle_data = pd.DataFrame(data)\nseattle_data['Date'] = pd.to_datetime(seattle_data['Date'])\n\n# synthetic weather data\nweather_data = pd.DataFrame({\n    'Date': dates,\n    'Temperature': 65 + 5 * np.sin(np.linspace(0, 2*np.pi, len(dates)))  # Sinusoidal temperature variation\n})\n\nweather_data['Date'] = pd.to_datetime(weather_data['Date'])\n\n# Aggregate crime data by date and type\ncrime_counts_by_date = seattle_data.groupby(['Date', 'Summarized Offense Description']).size().unstack(fill_value=0)\n\n# Merge with weather data\nmerged_data = pd.merge(weather_data, crime_counts_by_date, on='Date', how='inner')\nmerged_data.head()\n","metadata":{"execution":{"iopub.status.busy":"2024-05-18T05:12:05.831307Z","iopub.execute_input":"2024-05-18T05:12:05.831697Z","iopub.status.idle":"2024-05-18T05:12:05.883645Z","shell.execute_reply.started":"2024-05-18T05:12:05.831663Z","shell.execute_reply":"2024-05-18T05:12:05.882341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# correlations between temperature and different crime types\ncorrelation_results = merged_data.corr()['Temperature'].drop('Temperature')\n\ncorrelation_results\n","metadata":{"execution":{"iopub.status.busy":"2024-05-18T05:12:14.360957Z","iopub.execute_input":"2024-05-18T05:12:14.361319Z","iopub.status.idle":"2024-05-18T05:12:14.371515Z","shell.execute_reply.started":"2024-05-18T05:12:14.361287Z","shell.execute_reply":"2024-05-18T05:12:14.370379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport seaborn as sns\n\n# correlation for a specific type of crime\ncrime_type = 'FRAUD'  # Replace with actual crime type\nif crime_type in merged_data.columns:\n    plt.figure(figsize=(12, 6))\n    sns.scatterplot(x=merged_data['Temperature'], y=merged_data[crime_type])\n    plt.title(f'Temperature vs. Number of {crime_type} Incidents')\n    plt.xlabel('Temperature (F)')\n    plt.ylabel('Number of Incidents')\n    plt.show()\nelse:\n    print(f\"Crime type '{crime_type}' not found in the data.\")\n","metadata":{"execution":{"iopub.status.busy":"2024-05-18T05:13:06.721331Z","iopub.execute_input":"2024-05-18T05:13:06.721893Z","iopub.status.idle":"2024-05-18T05:13:06.914280Z","shell.execute_reply.started":"2024-05-18T05:13:06.721841Z","shell.execute_reply":"2024-05-18T05:13:06.913453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}