{"cells":[{"metadata":{"_uuid":"51684b311cc89e52bf813d48bee2ea9977f917e6","_cell_guid":"cfdf5261-0d8e-4836-bb7e-8e9d71b17a26"},"cell_type":"markdown","source":"# Problem Statement #\n\nBuild a general-purpose automatic audio tagging system using a dataset of audio files covering a wide range of real-world environments. Sounds in the dataset include things like musical instruments, human sounds, domestic sounds, and animals from Freesound’s library, annotated using a vocabulary of more than 40 labels from Google’s AudioSet ontology. \n\nHere, I built an SVM classifier using MFCC features from the audio files. PCA was also used for dimension reduction.\nActually, SVM achieved a pretty good classification accuracy."},{"metadata":{"_uuid":"87310fe6b6fbee4f8cf1ad06104541c55bc5e0a8","_cell_guid":"d8f5e0d8-e998-4145-b5c3-a16f09020627"},"cell_type":"markdown","source":"## Data preprocessing ##"},{"metadata":{"_uuid":"2a4eee0fbac8bd185c4b4d0dc894c56ae12e7c14","collapsed":true,"_cell_guid":"dd5815f4-36db-4a1a-9b25-90c5ef7bede3","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\n\nimport os\nimport librosa\n\nimport scipy\nfrom scipy.stats import skew\nfrom tqdm import tqdm, tqdm_pandas\n\ntqdm.pandas()\n\nfrom sklearn.model_selection import GridSearchCV\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\nfrom sklearn.preprocessing import StandardScaler\nfrom sklearn.decomposition import PCA\n\nfrom sklearn.svm import SVC","execution_count":1,"outputs":[]},{"metadata":{"_uuid":"d88c4b81919ca194041ce32277170a962e9af015","collapsed":true,"_cell_guid":"5fba92a1-1288-42ac-9c6e-39180c58c3e8","trusted":true},"cell_type":"code","source":"# Load data\n\naudio_train_files = os.listdir('../input/audio_train')\naudio_test_files = os.listdir('../input/audio_test')\n\ntrain = pd.read_csv('../input/train.csv')\nsubmission = pd.read_csv('../input/sample_submission.csv')","execution_count":2,"outputs":[]},{"metadata":{"_uuid":"92ceb1641f2f3bd8248f7daf547baef445b3543b","collapsed":true,"_cell_guid":"9230b979-dd71-4852-842e-f3f7eb2b328b","trusted":false},"cell_type":"code","source":"# Function from EDA kernel: https://www.kaggle.com/codename007/a-very-extensive-freesound-exploratory-analysis\nSAMPLE_RATE = 44100\n\ndef clean_filename(fname, string):   \n    file_name = fname.split('/')[1]\n    if file_name[:2] == '__':        \n        file_name = string + file_name\n    return file_name\n\n# Generate mfcc features with mean and standard deviation\ndef get_mfcc(name, path):\n    data, _ = librosa.core.load(path + name, sr = SAMPLE_RATE)\n    assert _ == SAMPLE_RATE\n    try:\n        ft1 = librosa.feature.mfcc(data, sr = SAMPLE_RATE, n_mfcc=30)\n        ft2 = librosa.feature.zero_crossing_rate(data)[0]\n        ft3 = librosa.feature.spectral_rolloff(data)[0]\n        ft4 = librosa.feature.spectral_centroid(data)[0]\n        ft5 = librosa.feature.spectral_contrast(data)[0]\n        ft6 = librosa.feature.spectral_bandwidth(data)[0]\n        ft1_trunc = np.hstack((np.mean(ft1, axis=1), np.std(ft1, axis=1), skew(ft1, axis = 1), np.max(ft1, axis = 1), np.median(ft1, axis = 1), np.min(ft1, axis = 1)))\n        ft2_trunc = np.hstack((np.mean(ft2), np.std(ft2), skew(ft2), np.max(ft2), np.median(ft2), np.min(ft2)))\n        ft3_trunc = np.hstack((np.mean(ft3), np.std(ft3), skew(ft3), np.max(ft3), np.median(ft3), np.min(ft3)))\n        ft4_trunc = np.hstack((np.mean(ft4), np.std(ft4), skew(ft4), np.max(ft4), np.median(ft4), np.min(ft4)))\n        ft5_trunc = np.hstack((np.mean(ft5), np.std(ft5), skew(ft5), np.max(ft5), np.median(ft5), np.min(ft5)))\n        ft6_trunc = np.hstack((np.mean(ft6), np.std(ft6), skew(ft6), np.max(ft6), np.median(ft6), np.max(ft6)))\n        return pd.Series(np.hstack((ft1_trunc, ft2_trunc, ft3_trunc, ft4_trunc, ft5_trunc, ft6_trunc)))\n    except:\n        print('bad file')\n        return pd.Series([0]*210)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d63822023d6f11917946ddcbd1f19cb9719dc7ad","collapsed":true,"_cell_guid":"b7bb62ec-5cef-47ab-bd14-a29237f81d2e","trusted":false},"cell_type":"code","source":"def convert_to_labels(preds, i2c, k=3):\n    ans = []\n    ids = []\n    for p in preds:\n        idx = np.argsort(p)[::-1]\n        ids.append([i for i in idx[:k]])\n        ans.append(' '.join([i2c[i] for i in idx[:k]]))\n\n    return ans, ids","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"f6a6ee21d1a6c6f05c85cbf3cc507f9ca0b703e4","_cell_guid":"b60ddc34-1685-488e-b6d0-65b68c918391","trusted":false,"collapsed":true},"cell_type":"code","source":"# Prepare data\n\ntrain_data = pd.DataFrame()\ntrain_data['fname'] = train['fname']\ntest_data = pd.DataFrame()\ntest_data['fname'] = audio_test_files\n\ntrain_data = train_data['fname'].progress_apply(get_mfcc, path='../input/audio_train/')\nprint('done loading train mfcc')\ntest_data = test_data['fname'].progress_apply(get_mfcc, path='../input/audio_test/')\nprint('done loading test mfcc')\n\ntrain_data['fname'] = train['fname']\ntest_data['fname'] = audio_test_files\n\ntrain_data['label'] = train['label']\ntest_data['label'] = np.zeros((len(audio_test_files)))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"fc0c0c8452bf2f0115c4223c50888fb255e2698f","_cell_guid":"7d69c0e2-dc16-4235-be76-c23ce877def2","trusted":false,"collapsed":true},"cell_type":"code","source":"train_data.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"70f97a79c3015700d69f9b198efa26ebfc401bba","collapsed":true,"_cell_guid":"cd4f7b80-9e9c-4934-9261-b53b83b6b1f1","trusted":false},"cell_type":"code","source":"# Functions from Random Foresth using MFCC ttps://www.kaggle.com/amlanpraharaj/random-forest-using-mfcc-features\n# Construct features set\nX = train_data.drop(['label', 'fname'], axis=1)\nfeature_names = list(X.columns)\nX = X.values\nlabels = np.sort(np.unique(train_data.label.values))\nnum_class = len(labels)\nc2i = {}\ni2c = {}\nfor i, c in enumerate(labels):\n    c2i[c] = i\n    i2c[i] = c\ny = np.array([c2i[x] for x in train_data.label.values])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"554c5f50fbf3e58d58705e2f80053faf682f7db4","collapsed":true,"_cell_guid":"d17e50f9-6fc3-4c71-89a5-2d1175454631","trusted":false},"cell_type":"code","source":"X_test = test_data.drop(['label', 'fname'], axis=1)\nX_test = X_test.values","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e302db496d1bf0a2ca6089d52aec1ff1a737546d","_cell_guid":"fc8c6f0a-8834-4b2d-8deb-afcfca040631","trusted":false,"collapsed":true},"cell_type":"code","source":"print(X.shape)\nprint(X_test.shape)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"433867b877581dc1701aacc7bfd1dc15d3d04ad2","collapsed":true,"_cell_guid":"5031c61a-57f7-43d2-a71e-0a96a99a3111","trusted":false},"cell_type":"code","source":"# Apply scaling for PCA\nscaler = StandardScaler()\nX_scaled = scaler.fit_transform(X)\nX_test_scaled = scaler.transform(X_test)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"88398b59ddb71221412226e63aad4ec35d331af2","_cell_guid":"45a2ba1c-d7cf-4fdb-8768-3518ca1ca7fd","trusted":false,"collapsed":true},"cell_type":"code","source":"# Apply PCA for dimension reduction\npca = PCA(n_components=65).fit(X_scaled)\nX_pca = pca.transform(X_scaled)\nX_test_pca = pca.transform(X_test_scaled)\n\nprint(sum(pca.explained_variance_ratio_)) ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b50dbbb7920621b8a75768cd09f255440b9de189","_cell_guid":"026777a8-bfe7-47f8-821f-20427bedabe7","trusted":false,"collapsed":true},"cell_type":"code","source":"# Fit an SVM model\nX_train, X_val, y_train, y_val = train_test_split(X_pca, y, test_size = 0.2, random_state = 42, shuffle = True)\n\nclf = SVC(kernel = 'rbf', probability=True)\n\nclf.fit(X_train, y_train)\n\nprint(accuracy_score(clf.predict(X_val), y_val))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9153aa7eedbc5ccb938f1681f57eb5b70a5ab9fc","_cell_guid":"645770d4-0fbb-4bc3-acc2-52f6458bccde","trusted":false,"collapsed":true},"cell_type":"code","source":"# Define the paramter grid for C from 0.001 to 10, gamma from 0.001 to 10\nC_grid = [0.001, 0.01, 0.1, 1, 10]\ngamma_grid = [0.001, 0.01, 0.1, 1, 10]\nparam_grid = {'C': C_grid, 'gamma' : gamma_grid}\n\ngrid = GridSearchCV(SVC(kernel='rbf'), param_grid, cv = 3, scoring = \"accuracy\")\ngrid.fit(X_train, y_train)\n\n# Find the best model\nprint(grid.best_score_)\n\nprint(grid.best_params_)\n\nprint(grid.best_estimator_)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ce5f72cdc585dea4bb49dbb850f365b5bf1d50b8","_cell_guid":"4905392d-e387-4605-85b2-80977df4dade","trusted":false,"collapsed":true},"cell_type":"code","source":"# Optimal model\nclf = SVC(kernel = 'rbf', C = 4, gamma = 0.01, probability=True)\n\nclf.fit(X_train, y_train)\n\nprint(accuracy_score(clf.predict(X_val), y_val))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6b5e028fab7e4ac7e4f10e6b40fa28bc892a815c","collapsed":true,"_cell_guid":"bcd3a3db-6f02-44c9-ac64-ac5867bd0b1c","trusted":false},"cell_type":"code","source":"# Fit the entire training sets\nclf.fit(X_pca, y)\nstr_preds, _ = convert_to_labels(clf.predict_proba(X_test_pca), i2c, k=3)\n\n# Write to outputs\nsubm = pd.DataFrame()\nsubm['fname'] = audio_test_files\nsubm['label'] = str_preds\nsubm.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a92500ad028e500cdaafdc167b32156e76c2567a","collapsed":true,"_cell_guid":"c2efdd7f-6fc6-47d4-a113-56e50634891b","trusted":false},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"}},"nbformat":4,"nbformat_minor":1}