{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Signal processing using Scipy\n", "\n", "In this notebook we will explore how the [scipy](https://scipy.org/scipylib/) package can be used to perform signal processing.\n", "\n", "Scipy stands for *sci*entific *py*thon, and is a package with a vast range of modules for a range of scientific computing problems. From linear algebra to optimization; from integration to interpolation: it is the go-to Python package for traditional scientific computing problems. Scipy is built from numpy's `ndarray`, and scipy interfaces with `matlotlib` for visuals. So when working with scipy it is essential we also have numpy and matplotlib imported too." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Scipy is a large package with many submodules. It is standard to just import the modules we will be working with on a givgen task. In this notebook, we'll be using the module `signal`, which give access to methods related to signal processing. We will also need some helper functions for reading in signals, from the `scipy.io` module." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from scipy import signal\n", "from scipy.io import wavfile" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will also run the following code to tell Python we don't want it to display warnings when we run code. This is because the functions we will use from `scipy.io` often produce spurious warnings which are not of concern to us here." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import warnings\n", "warnings.simplefilter(\"ignore\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Working with signals\n", "A signal is a series of measurements over time, related to some phenmomenon. It could be the light emitted from a chemical reaction, sound transmitted through the air, or the heat of an organism throughout some biological process. When we work with signals in python, we are considering digital signals: samples of a signal taken at discrete time-steps. Today we will be working with a familiar signal: we'll be working with audio signals (i.e. those coming from sound waves). \n", "\n", "### Reading in a wav audio file\n", "Let's see how we can represent an audio signal in python. We are going to use the `wavfile.read` helper to read in a recording of a guitar chord (you can listen to it by clicking on the file in the Jupyter folder)." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "scrolled": true }, "outputs": [], "source": [ "chord = wavfile.read(\"data/chord-11.wav\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This function returns a tuple. The first element is the sample rate, and the second is the actual data from the file." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "(44100, array([[ -8, 45],\n", " [ 30, 91],\n", " [ 82, 129],\n", " ...,\n", " [ 0, 0],\n", " [ 0, 0],\n", " [ 0, 0]], dtype=int16))" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "chord" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Plotting the data from the wav with `plt` will give the charactersitic plot of the sound wave that we're used to." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.plot(chord[1])\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To check we're doing things correctly, let's write that data back to another file. By opening the original file and the file we've written, you should convince yourself that the numpy array created by `wavfile.read` really does represent the audio signal of the wav file." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "wavfile.write(\"data/test.wav\", chord[0], chord[1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Converting to Mono\n", "Many sound signals are multi-channel, and often we store audio in stereo. In fact, the audio signal `chord` is in stereo. The audio data is a list of pairs. Each pair represents a point in time: the first value is the data from the L channel, and the secon is the data from the R channel." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ -8, 45],\n", " [ 30, 91],\n", " [ 82, 129],\n", " ...,\n", " [ 0, 0],\n", " [ 0, 0],\n", " [ 0, 0]], dtype=int16)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "chord[1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For simplicity, we will work only with mono signals for the remainder of this notebook. Your first task is to write a function `to_mono`, which takes a tuple representing a sound signal, and returns another sound signal by averaging the data fro each time-step. The data part of your sound signal should be an array of `np.int16` data.\n", "\n", "_(Hint: remember that a signal is represented as a tuple: so your function must return a tuple including the sample frequency!)_" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "def to_mono(sound):\n", " if sound[1].shape ==1:\n", " return sound\n", " else:\n", " aves = []\n", " for t in sound[1]:\n", " aves.append(np.mean(t))\n", " return sound[0], np.array(aves, dtype=np.int16)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, replace `chord` with its mono version. Plot this signal, and write it to a wav file. Does it sound similar to the file you started with?" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 18, 60, 105, ..., 0, 0, 0], dtype=int16)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "chord = to_mono(chord)\n", "chord[1]" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAY8AAAD8CAYAAACPWyg8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzt3Xl4VOXd//H3NzsJSxI2CSEEMICArBHcN0TApaBVq+2j2GrpU7VP/Wntg0urdWmptdrqY22pYtWquLRWrQvFXSsIQauAbGEPIAkk7IRs9++POWASQpIJMzkzk8/runJl5p4z53zncMhnzn3uc4455xAREQlGnN8FiIhI9FF4iIhI0BQeIiISNIWHiIgETeEhIiJBU3iIiEjQQhIeZjbTzIrNbHGttjvMbKOZ/cf7OafWazebWaGZLTez8bXaJ3hthWY2rVZ7HzP7xMxWmtlzZpYUirpFRKRlQrXn8RdgQgPtDzjnhns/rwOY2SDgUmCw954/mFm8mcUDDwMTgUHAZd60AL/25pUHlAFXhahuERFpgZCEh3PuA6C0mZNPAmY55/Y759YAhcBo76fQObfaOVcBzAImmZkBZwIveu9/ApgcirpFRKRlEsI8/+vM7AqgALjROVcG9ATm1ZqmyGsD2FCvfQzQGdjunKtqYPrD6tKli8vNzT2y6kVE2piFCxdudc51bWq6cIbHI8BdgPN+/xb4HmANTOtoeC/INTL9IcxsKjAVICcnh4KCguCrFhFpw8xsXXOmC9toK+fcFudctXOuBvgzgW4pCOw59Ko1aTawqZH2rUC6mSXUa29omTOcc/nOufyuXZsMThERaaGwhYeZ9aj19ALgwEisV4BLzSzZzPoAecB8YAGQ542sSiJwUP0VF7hy47vARd77pwAvh6tuERFpWki6rczsWeB0oIuZFQG3A6eb2XACXUxrgR8AOOeWmNnzwJdAFXCtc67am891wGwgHpjpnFviLeJ/gVlmdjfwGfBYKOoWEZGWsVi9JHt+fr7TMQ8RkeCY2ULnXH5T0+kMcxERCZrCQ0REgqbwEBGRoCk8IohzjhcKNlBRVeN3KSIijVJ4RJA3Fn/FTS9+we/fXgFAdY3j/RUlPlclInIohUcE2bGvEoCisn3c++Yyfv/WCqbMnM+7y4t9rkxEpK5wX9tKWuDl/9Q9gX7z9nIWrC1lcFZHFhXt4LjcTCqqa0hJjPepQhFp6xQeUeC+fy2ndE8FOZmprC/dy7lDe/DaF5tZcfdEkhK08ygirU9/eVrZg2+vZPHGHTxfsIGvdpTz3IL17Nhb2eh7SvdUALC+dC8Ar32xGYCKah1YFxF/aM+jld0/ZwX3z1lRp232ki30TG9HRmpiUPNavHEHSzbt5KqT+4SyRBGRJik8IsA7y1p2QPzSGYHbokwensW2PRX0794hlGWJiByWuq1iwLgHPuDsBz7wuwwRaUMUHjHgwDEREZHWovAQEZGgKTxERCRoCo8Y8nzBBu59c5nfZYhIG6DwiCE/ffEL/vDeKr/LEJE2QOEhIiJBU3i0oli95a+ItD0KDxERCZrCIwbtrahi9/4qv8sQkRim8GhFrdVrNequtxhy++zWWZiItEkKjxi0r7La7xJEJMYpPEREJGgKj1aksVYiEisUHjFs2Vc7KSze5XcZIhKDdD+PGDbhdx8CsHb6uT5XIiKxRnserUgnCYpIrFB4iIhI0BQebcBt/1jEI7pgooiEUEjCw8xmmlmxmS2u1ZZpZnPMbKX3O8NrNzN70MwKzewLMxtZ6z1TvOlXmtmUWu2jzGyR954HzcxCUXdb8dd56/m1LtUuIiEUqj2PvwAT6rVNA952zuUBb3vPASYCed7PVOARCIQNcDswBhgN3H4gcLxpptZ6X/1lRQUd8RCRWBGS8HDOfQCU1mueBDzhPX4CmFyr/UkXMA9IN7MewHhgjnOu1DlXBswBJnivdXTOzXWBI85P1pqXiIj4IJzHPLo75zYDeL+7ee09gQ21pivy2hprL2qg/RBmNtXMCsysoKSkJCQfQkREDuXHAfOGjle4FrQf2ujcDOdcvnMuv2vXrkdQYnhopK6IxIpwhscWr8sJ73ex114E9Ko1XTawqYn27AbaJUiP/3sN76/QHpmIHLlwhscrwIERU1OAl2u1X+GNujoe2OF1a80GzjazDO9A+dnAbO+1XWZ2vDfK6opa85Ig/OLVL5kycz41NU4nLIrIEQnVUN1ngbnAADMrMrOrgOnAODNbCYzzngO8DqwGCoE/A9cAOOdKgbuABd7PnV4bwA+BR733rALeCEXdrc1FyHirvre8zhUz5/tdhohEsZBc28o5d9lhXhrbwLQOuPYw85kJzGygvQAYciQ1Sl0frtxK8a5yOqYkkpIY73c5IhJldIZ5Gzb6nre57M/z/C5DRKKQwqMVReJhhs/Wb+f8hz7i1c81BkFEmk/hISzauIMfPfuZ32WISBRReIiISNAUHiIiEjSFhxz08LuFbCjd63cZIhIFFB5y0G9mL+fKx3X+h4g0TeHRiiJxtFV9eyuq/S5BRKKAwkPqqKpx3PLSIorK1H0lIoen8JA6Snbt55lP1nPj85/7XYqIRLCQXJ5EDu9fS74ip3MqX+0oJyu9nd/lNFtNNPSxiYhvFB5hNvWphX6X0CI1Diqra0iM186piBxKfxmkQatLdpN36xv847ONfpciIhFI4SENKttbCcAbizf7XImIRCKFhzSqRoc+RKQBCg9plHPw3vJi3XlQROpQeEij3lq6hSsfX8DTn6z3uxQRiSAKD2kWXfNKRGpTeEizlO6p4Ibn/sPu/VV+lyIiEUDneUizvLCwCICBPTow9dR+PlcjIn7TnocERaOvRAQUHhIkDbr6WtmeCkp27T/4vKbGaVSatBnqtpKgfFRYwq/fXMb8W8bSrWOK3+W0qo8Lt7J40w7eW17CJ2tKqfZ2w3p0SiEtOYHC4t0c27MTyQlxnNCvM/NWb+O8oVl0SElgVO8MendO8/kTiISOwkOC8u/CbQB8ur6MCUN6+FxNeK0q2c07S4vZVV7Jw++tOhgW9W3eUX7w8aKNOwAoWFcGwIK1gd8piXGUV9Zw7Rn9WLC2jFvOOYbhvdLD/AlEwkfhESY79lZy7kMf+l1G2FRUx273TOmeCj5YUcIdry5hu3eZliNVXlkDwMPvrgLg+08WULJrP09dNZqEuDjG9MkkLs5CsiyR1qDwCJNhd/7L7xLCand5FR+uLOGUvK5+lxIyH64sYcrM+fTv3oFlX+0K67IOHCu58vEFVNc4bjv3GLIz2jF+8FGYKUQk8ik8pEXun7OCrbv388p1JzE0O7q7X+at3salM+aRk5lKjSPswVHbga6wu19bCsBN4wewqmQ3v7zgWFIS41utDpFgKTxa6EfPfgbAQ5eN8LkSf2zdHfjmXBaibh0/zF9TyiV/mktOZioA6yPgLPrfzF4OQFpSAu8sK+bN60+hQ0qiz1WJHEpDdVvo1c838ernm/wuw3eLirZzwq/epqKqxu9SmmXzjn2sLtlN7rTX+N1bK4DICI36npq3jo3b9zHtb4vInfYam3fs4/MN2/0uS+SgsIeHma01s0Vm9h8zK/DaMs1sjpmt9H5neO1mZg+aWaGZfWFmI2vNZ4o3/UozmxLuuusr3VPBV7VG1UjAff9aweYd5cxfU+p3KQ3auns/5ZXV/PCvC3nti82c8Kt3uGLmfAA+XrXN5+qa9tqiwP1UJv3fv5n08L8p2bWfwuLdPlcl0np7Hmc454Y75/K959OAt51zecDb3nOAiUCe9zMVeAQCYQPcDowBRgO3Hwic1jLyrjkc/6u3W3ORUWX7vgoe/XC132UctHjjDrbsLCf/7re48A8f88bir7j2mU8BKCrb53N1wSv2DrBfOmMuZ93/PnsrqijepS8z4h+/uq0mAU94j58AJtdqf9IFzAPSzawHMB6Y45wrdc6VAXOACa1dNMD7K0oabC/eWc7O8ujt/z9S1z3zGXe/tvTgsRC/PPrhahauK+O8hz7iwj98DMCXm3f6WlMorSrZA8BFj8xl9D36MiP+aY3wcMC/zGyhmU312ro75zYDeL+7ee09gQ213lvktR2uvdVN8bo86hv9y7cZese/2FdRzbPz2+69L5Zu3sn9c1a0+nKf+HgtH64s4e7XlvLNRwKhsXF79O1hNNeBQPzeXxbQ75bXfa5G2qLWGG11knNuk5l1A+aY2bJGpm1ogLtrpL3umwPhNBUgJyenJbU2y8V//Pjg43vfXEa3DskHnx/z8zfDttxocPljgXD90ZlHkxgf/u8mz85fT0ZqEre/siTsy4pE7ywrBuCXry+leGc5v7u0bY7+k9YX9vBwzm3yfheb2UsEjllsMbMezrnNXrdUsTd5EdCr1tuzgU1e++n12t9rYFkzgBkA+fn5YTsF+sAlJwD+8N6qcC0mqq3cspsVW3YxeUR4dhA3bd9HnBk3/31RWOYfbWZ8EDjedNfkIQAa3ithF9bwMLM0IM45t8t7fDZwJ/AKMAWY7v1+2XvLK8B1ZjaLwMHxHV7AzAZ+Wesg+dnAzeGsXY7MOQ8GLs0yaXgWzhGyS288v2ADpXsrmP5GYzuwbdexdwSubLB2+rk+VyKxLtx7Ht2Bl7zLLSQAzzjn3jSzBcDzZnYVsB642Jv+deAcoBDYC3wXwDlXamZ3AQu86e50zkXm2FCp47t/WcB7y0ta/MdsQ+leisr2sXrrblZu2c1fPl4b2gJj1L1vLiMzLYmrT+nrdykSo8IaHs651cCwBtq3AWMbaHfAtYeZ10xgZqhrlPB6b3lgdNr+qmqcg4Q447mCDXwrvxcJDRwTqaquYWd5FdU1jrXb9nDxH+e2dskx4UB36nlDs2iXGE+nVHVjSWjp8iTSKgbcFhhIcNnoHJ6dv54vN+3ko8KtTJswkBue/5zJI7J4dv6GJuYiwTr+V2/TITmBL+44G0AXXZSQsVi981l+fr4rKCgI2fxyp70WsnmJ+OGsY7rz6JT8pieUNs3MFtY6ofuwdG0rkTbiraVbuP3lxYc90VUkGAoPkTbkibnrmDJzPu8s26LLm8gRUXiItEHf+0sBl/xxLqtKdrO/qtrvciQKKTxE2qi12/Yy9rfvc9MLX7Bm6x6qqqPjsvoSGRQeIm3cK59v4oz73mP6G8tYuWXXwbsbijRG4SEiADz27zWMe+ADHnx7Jeu37SVWR2JKaCg8RASAA1nxpw9Wcepv3uWFgiIK1pYqRKRBOkmwGXbvr/K7BJFWU14ZOPZx28uLqaiq4YFvDWNA944Myuroc2USSRQezTDu/vf9LkGk1R24L/3P/7GEXfurmDX1eHp0SqF35zSfKwu/mhpHjXNUVNew3wvTyuoaUpLicQ46tdPlXhQezbBZ9y6XNmyXt+d94/Ofs3H7Pt6+8TSyM9qRnBDvc2UtV13jKCzeTfeOyXxUuJXM1CQe+2gNfbqk8ehHaxg/uDuzl2yhV2Y7NpTuw+zrbj2AsQO7kZmWxDvLisnPzeDU/l3J69aBnfsqyevenl3lVeR0TmXT9n3kdk6jvLKajimJIbu6dCTQ5UmaQZcmEfnamD6ZfLKmlEV3nB019w2pqKrh6U/WcVxuJlfMnM/4wUfx7Pz1dO+YzJadob11cnycUV3j6Nc1jVUle8jvnUHBujKuPDGXZ+ev5/HvHsfcVdu4+uS+/HPRJr6V34vt+yrp0j6ZyuqaVrmJWmOae3kShUczKDxEDu+XFxzL5BFZfLZ+O8flZrJtz356dGrnWz3FO8vJSEviwbdXcvqAbnzzkY85rX/XiL0sy8icdD5dv53Lj+/NU/PW8cFNZ5DTOdW3ehQeCg+RVje6Tybz15Ry/yXDeL5gA9MvHMqabXs4Y0C3kC+rusYRZ/DiwiKOy83knteXcsGInlzz9KcM65XO5xu2h3yZrWHG5aM4e/BRvi1f4aHwEIkYPzy9H299uYUHvjWckt37GdyjI1U1jqz05u+h7CyvJCHO+P1bKxnSsxM/evYzzh+Wxaufbwpj5a3vzIHdeGdZMZ/9bBwZaUmtvvzmhocOmItI2D1y4OZUD31Up/3obu3ZvreSU/O6sLO8kqHZ6aQlJ5CWFDgYv7eimk/WbKNbhxSemreOLu2T2Lq74uD7Yy04AN5ZVgzAutK9voRHcyk8RMQ3hcW7Afj7ZxsBeGtpcaPT1w4O8ZfOMBcRkaApPEREJGgKj3r2VlQx58stfpchIm2ccy6i77Wi8Kjntn8s5vtPFrB0806/SxGRNuzeN5cz4LY3IzZAFB71rNu2F9DFEEXEX3NXbwNgz36FR1SIt8C1Z3RDHBGJBJF6h0eFRz0J8V+Hx8ertjLqrjk+VyQibVl1hJ7IrfM86imvDOwifufRT3yuREQEtuzcz4bSfYzuk+l3KXUoPOoJ9RU2RUSOxIV/+Dc1DtZOP9fvUupQt1U9I3LS/S5BROSgA4dfD9ycK1IoPOqJs9i5WYuIxI59FZE16ipqwsPMJpjZcjMrNLNp4VtOuOYsItJy0/7+BTURNAo0KsLDzOKBh4GJwCDgMjMbFI5lRdquoYgIwBuLv+KOV5f4XcZBUREewGig0Dm32jlXAcwCJoVjQRE6Kk5EhCfnriN32mts2+3/wJ5oGW3VE9hQ63kRMCYcC+reMTkcsxURCZlRd79V5/nFo7LrPL/qlD4MPKpjWGuIlvBo6EjEIfsIZjYVmAqQk5PTogX17pzWoveJiPjlg5UlB6+OAXDhyOxGpg6NaAmPIqBXrefZwCG3EHPOzQBmQOA2tC1Z0PdO7sOd//yyJW8VEQm77Ix2FJXtO/j85okD+cFp/Vq9jmgJjwVAnpn1ATYClwLf9rckEZHW88h3RjLx2B5+l3FQVISHc67KzK4DZgPxwEznXOQMOxARCbNICg6IkvAAcM69Drzudx0iIhI9Q3VFRNqsk4/u4ncJh1B4iIhEsONyM/jr1WE5M+GIKDyaIScz1e8SRKSNOrFf5O11gMKjQX+/5kTOOqYbAKcP6MrEIUf5XJGItFU/HpvndwkNUng0YGROBpefkAsE7ii4dtsefwsSkTYrLi4yr9aq8DiMDimBgWid05KwBk9wFxEJr16Z7fwu4bAUHocxolc6935zKHdNHqLLtItIqxvQvQMf/vRMv8s4rKg5z6O1mRmXHNfLe+xzMSLS5kT63x3teTSDuq1EpLVF+l1NFR7NEdn/hiISg84c2M3vEhql8GgGZYeItKarTu7DDeP6+11Go3TMoxkswncfRSR2dE5L4mfnheUu2yGlPY9mUHSISLjldk6lQ3ICPz8/8oMDtOchItKqju7Wno4pCZzWvxt9u6YxKKsjG8v2MSirI13aR89tsBUezaBeK5HWkZYUT3pqEjmZqVx9Sh+WbNrJN0dl89TcdYzuk8GvXl/GTeMH8NS8dZx0dBf+Om8dEwYfxTvLiinbW0HZ3kq/P0Idk4ZnUVldw38d35vkhDgGZ3UiPs5IjK/b6dOva3ufKmw5c65Fd2uNePn5+a6goCAk87psxjzmrt4WknmJCPTtksbqrXv41YXH8nzBBh6bchxrtu5mVO/MFs9zz/4qKqtr2FdZTXWNY/OOclIS4ln21U56ZrRj5kdrOHNgd2YtWM/Fo7L52ctLGD+4O7OXbOHobu0pLN5Nfu8MCtaVcVr/rry/ooRje3Zi0cYdDDyqA8u+2sUZA7ry7vISzhzYjXeWFXP1yX149KM13DVpMC99tpE7Jw1h845yhvTsyN6K6ugMBbOFzrn8JqdTeDQtd9prIZmPSFs1uk8m89eUMvPKfOavKeP6s/LYvreSozql+FbTnv1VtEuMp2BdGcf27ERh8W4GZXVkzdY99OuaxqqSPeR2TuX9FSWc1r8rX27eyeCsTmzbs5/M1CR27KukcxR1MzWXwiOE4XHO7z/ky807QzIvkbZgVO8MVpXs5v5LhrFzXxVnD+5OapJ6yaNBc8ND/5rN8OiUfE6c/o7fZYhEtIzURK4+pS+n9e9Kbpc02ifrz0ss079uM6TpG5PIIfp3b8+Qnp04f1gWvTJSObpb9PXvS8vpr2JzaLSVCO2TE9i9v4rHrzyOlMR4TujX2e+SxEcKj2bQUF1pi9olxrOvspr7LxlGUdk+pp7aF+egXVK836VJBFB4NIOyQ9qSb47M5m+fFvH+TadTvGs/Q3p28rskiUC6PEkz6NpW0hZceWIuAPddPJS108+lW8cUBYcclsKjGRQdEsvumjSYswd152fnDWLt9HP1ZUmaRd1WzaD/SxKL7r1oKEnxcUwe0ZPLT8j1uxyJMgqPZtCdBCWW3DR+AEnxcVw0Mpu4OG3b0jIKj2bQnodEs4Q4o6rGcdu5x7C/qoapp/Y95MJ8IsHSFhQC91087ODj2849xsdKRA513ZlH8+p1J3PVyX249oyjFRwSEtrzaIbG9jw6piSQlR64uNuYPpmk6ZIMUW1ETjqfrd/Oucf24LVFm/0u54icN7QH1515NHndOhCv7ikJsbD9pTOzO4DvAyVe0y3Oude9124GrgKqgf9xzs322icAvwfigUedc9O99j7ALCAT+BS43DlXEa7aD/ksTRzziPPSxRG4eqhEn8FZHenRKYVfTBpCz/R2AHR+eTGpSQn88f1VPlcXnItHZXPBiJ4Mz0nXxQglbMK9ZT3gnLuvdoOZDQIuBQYDWcBbZnbgTu8PA+OAImCBmb3inPsS+LU3r1lm9kcCwfNImGuvVfPhX/vO8b2/fuICN3X5zUVDuenFL8JfmByxHp1S2LyjnAtHZnPVyX3qvHbnpCEAZKYl0r1jCj+e9R8/SmyWK0/M5exB3cnr3oH01ER1TUnY+fG1ZBIwyzm3H1hjZoXAaO+1QufcagAzmwVMMrOlwJnAt71pngDuoDXDo97zA/cm6JXZjp+OH8C81aUNTygRKzHeuO3cQUwcchRpyQmkNnLJjamn9gOga4dkenRqxxn3vXfwJkJ+6pnejlvOOYZ+3dIYeFRHX2uRtifc4XGdmV0BFAA3OufKgJ7AvFrTFHltABvqtY8BOgPbnXNVDUzfKuLq7XrcM3kI4x74gKT4OMyM7IxAN8fpA7oCge4riVz/dXwOF4zIZlTvjKDed2K/LgCsuHsi8XHGM5+sY0zfzlzz9Kf8eGweD79byPVn5fHff/2Up64azbLNu/jG8Cx+/vJiurRP5ulP1re45sR4o7LaMXHIUXTtkMyN4waQlBCn60yJb44oPMzsLeCoBl66lcCewV0E/pbeBfwW+B4Nfz93NDzyyzUyfUP1TAWmAuTk5DRRffPV77bq17U93z0pl8u9LqtemanMv3UsXdJi765iseaa0/vx0wkDj2geSQmBTfXAiXVv3XAaAOcPywJg7fRzATglL/Bl4k+X51NeWU2fLmn07pzG958sICczlfWlew+Zd2pSPHsrqhmZk86n67fzp8tHUbangknDA9+XFBYSKY4oPJxzZzVnOjP7M/BP72kR0KvWy9nAJu9xQ+1bgXQzS/D2PmpPX7+eGcAMCNxJsJkfozn113keF2fcfv7gOm3dOnx9O836eyriv7EDu/HYlcf5tvyUxHiuPqUvEAiXLTvL+dunRYzOzeSxj9YweURP/v5pEXd8YzAbSvcxqncG1TXuYFCJRJpwjrbq4Zw7MNbxAmCx9/gV4Bkzu5/AAfM8YD6BPYw8b2TVRgIH1b/tnHNm9i5wEYERV1OAl8NV9+H89uJh3PjC580a8nj+sB785IXPW6EqaY7CeyZGXKB375jCNacfDUB+bmCE3vjBgZ34Hp0C3aAaXiuRLJzHPO41s+EEupjWAj8AcM4tMbPngS+BKuBa51w1gJldB8wmMFR3pnNuiTev/wVmmdndwGfAY2Gsu0EXjuzJu8uLuWx0091hyQnxMXGeQLR7bEo+3TumkKCRRyIhZ87F5uHd/Px8V1BQ4Nvyr336U4WHT/561RhSk+MZmRPcAXERATNb6JzLb2o6nUEkMefkvC5+lyAS8xQeYeI0YLfVZKQmUra3kvm3jvW7FJE2Q+EhUe/jaWOpqqmhQ0qi36WItBk6kthKLsnPJlnDLkPiwPkU7/3kdF747xNolxSv4BBpZfprFib1xyGcNzSL5XdP9KeYKHfBiMAJcgdOynzoshGsnX4uuV3SOC5XF6IU8YO6rVqJjoAELzMtidI9Fdwwrj8PfGs4AHdNHuJzVSICCo9Wo9O9mu+kozvz78JtvPjfJ7B7fxW9MlP9LklE6lF4SMS59Lgcnr76eL/LEJFGKDxaSYRdHSMi3XrOMWRntGPCkIautSkikUThESYHDpjfOK4/C9aV6cBuI84b2oNvDMvirGO6E6frOYlEBYVHmNR46ZHXvT0/GpvnczWRqUNKArvKqzhvaA/OHqy9DZFoovAIkwPhEWlXc40EGamJ5HZJ4+fnDWKErj8lEpUUHmFS43Vb6bLah8pMS+Kla07yuwwROQIKjzCprtGeR0NunjiQc47t4XcZInKEFB5hcrDbSnseB104sic/OK2f32WISAgoPMLkQHjEa88DgMW/GE+Kru0lEjMUHmHydbdV09OmJMZRXlkT5or8MaZPJt8YnkX7ZG1qIrFEXwXDpMbLgqa6rT7/+dkM6tGxFSryx3M/OIHvjOntdxkiEmIKjzC5flweHVMSGJTVcDDMvflM3vvJ6XRKTeSKE3IBYu7b+fBe6X6XICJhElt/rSLIif268MUd4w/7eo9O7Q4+njyiJ5NH9OTkX7/D7v1VrVFe2C27awIJGiwgErMUHhGk/j1AotGw7E707dqelMR4v0sRkTBSeEhIvXzdyX6XICKtQOHRyp6bejzLvtrldxkiIkdE4dHKxvTtzJi+nf0uI2SSE+LYX1XD/FvHYrrllUibofCIIMflZrDxP/v8LiMoC382jupqR6fURL9LEZFWpKG6EWT6N4fyxo9PISUx8v9ZfnBqX4b1Sqd9coKCQ6QN0p5HBElJjOeYHh352w9P5PVFm3n43VV+l3SIZ74/hi837eTqU/r6XYqI+EjhEYEGZ3VicFaniAyPE/t14cR+XfwuQ0R8Fvn9I21YJJ1j98PT+5EUr81FRAKO6K+BmV1sZkvMrMbRiAKqAAAInElEQVTM8uu9drOZFZrZcjMbX6t9gtdWaGbTarX3MbNPzGylmT1nZklee7L3vNB7PfdIao4mb91wGg9dNsLvMgC4/qw8Vtwz0e8yRCRCHOlXycXAhcAHtRvNbBBwKTAYmAD8wczizSweeBiYCAwCLvOmBfg18IBzLg8oA67y2q8CypxzRwMPeNO1CX27tuf8YVkM6N7B71I0DFdE6jii8HDOLXXOLW/gpUnALOfcfufcGqAQGO39FDrnVjvnKoBZwCQzM+BM4EXv/U8Ak2vN6wnv8YvAWG/6NuOla09kwa1n+V2GiMhB4erE7glsqPW8yGs7XHtnYLtzrqpee515ea/v8KZvM1KTEujaIdmXZU89tS9JCXG6yKGI1NHkaCszews4qoGXbnXOvXy4tzXQ5mg4rFwj0zc2r0MXajYVmAqQk5NzmNKi1z+uPYmyvRV89/EFrbbM/xrTm1vOOabVlici0aHJ8HDOtaS/pAjoVet5NrDJe9xQ+1Yg3cwSvL2L2tMfmFeRmSUAnYDSw9Q6A5gBkJ+fHwPXqK3rwP0xXv+fU9hXWcU3H5kbtmV1SE5g1/4qUpI0wkpEDhWu8zxeAZ4xs/uBLCAPmE9gLyLPzPoAGwkcVP+2c86Z2bvARQSOg0wBXq41rynAXO/1d5yLhYuXt9zhbjAVSg98azgdUhLo1iEl7MsSkehzpEN1LzCzIuAE4DUzmw3gnFsCPA98CbwJXOucq/b2Kq4DZgNLgee9aQH+F7jBzAoJHNN4zGt/DOjstd8AHBzeK+GTmhwfUxdwFJHQOqI9D+fcS8BLh3ntHuCeBtpfB15voH01gdFY9dvLgYuPpE5pvtF9Mpm/ppTczml+lyIiEUyXJ5E6vjMmh6euGk1ygu4EKCKHp6OhUew3Fw1l+oXHhny+Cg4RaYrCI4pdnN+LS0eHZkhyp3aBy6r3TG8XkvmJSGxTt5UAgZMBT+vflSE9O/ldiohEAe15CBC4nayCQ0SaS3seMeD3lw4nPTWJKTPnB/3ei0Zl071jMpef0DsMlYlIrFJ4xIBJw3s2PdFhtEuM56bxA0NYjYi0BQqPGHLtGf3o370DcWYMPKoD4x74oMn3HDhQLiISDIVHDGloD6JDSgIXjcpmcFYnfvLC53ROS2LbngoevSKfTTv28a3jejUwJxGRxik8YthDl41gWHY6OZ1TWf7VLgB6Zaay8GfjfK5MRKKdwiOGnT8s6+Dj/t3bc/1ZeVySrz0NETlyCo82wsy4/qz+fpchIjFC53mIiEjQFB4iIhI0hYeIiARN4SEiIkFTeIiISNAUHiIiEjSFh4iIBE3hISIiQTPnnN81hIWZlQDrWvj2LsDWEJYTi7SOGqf10zSto6b5sY56O+e6NjVRzIbHkTCzAudcvt91RDKto8Zp/TRN66hpkbyO1G0lIiJBU3iIiEjQFB4Nm+F3AVFA66hxWj9N0zpqWsSuIx3zEBGRoGnPQ0REgqbwqMfMJpjZcjMrNLNpftcTTmbWy8zeNbOlZrbEzH7stWea2RwzW+n9zvDazcwe9NbNF2Y2sta8pnjTrzSzKbXaR5nZIu89D5qZtf4nPTJmFm9mn5nZP73nfczsE++zPmdmSV57sve80Hs9t9Y8bvbal5vZ+FrtUb+9mVm6mb1oZsu8bekEbUN1mdn/8/6PLTazZ80sJeq3I+ecfrwfIB5YBfQFkoDPgUF+1xXGz9sDGOk97gCsAAYB9wLTvPZpwK+9x+cAbwAGHA984rVnAqu93xne4wzvtfnACd573gAm+v25W7CebgCeAf7pPX8euNR7/Efgh97ja4A/eo8vBZ7zHg/ytqVkoI+3jcXHyvYGPAFc7T1OAtK1DdVZPz2BNUC7WtvPldG+HWnPo67RQKFzbrVzrgKYBUzyuaawcc5tds596j3eBSwlsKFPIvAHAe/3ZO/xJOBJFzAPSDezHsB4YI5zrtQ5VwbMASZ4r3V0zs11ga3/yVrzigpmlg2cCzzqPTfgTOBFb5L66+fAensRGOtNPwmY5Zzb75xbAxQS2Naifnszs47AqcBjAM65CufcdrQN1ZcAtDOzBCAV2EyUb0cKj7p6AhtqPS/y2mKet2s8AvgE6O6c2wyBgAG6eZMdbv001l7UQHs0+R3wU6DGe94Z2O6cq/Ke1/5MB9eD9/oOb/pg11s06QuUAI97XXuPmlka2oYOcs5tBO4D1hMIjR3AQqJ8O1J41NVQX2rMD0czs/bA34DrnXM7G5u0gTbXgvaoYGbnAcXOuYW1mxuY1DXxWkyuH08CMBJ4xDk3AthDoJvqcNrcOvKO90wi0NWUBaQBExuYNKq2I4VHXUVAr1rPs4FNPtXSKswskUBwPO2c+7vXvMXrLsD7Xey1H279NNae3UB7tDgJ+IaZrSXQFXAmgT2RdK/7Aep+poPrwXu9E1BK8OstmhQBRc65T7znLxIIE21DXzsLWOOcK3HOVQJ/B04kyrcjhUddC4A8bxREEoGDVa/4XFPYeP2ojwFLnXP313rpFeDAaJcpwMu12q/wRswcD+zwuiRmA2ebWYb3LetsYLb32i4zO95b1hW15hXxnHM3O+eynXO5BLaFd5xz3wHeBS7yJqu/fg6st4u86Z3Xfqk3iqYPkEfgIHDUb2/Oua+ADWY2wGsaC3yJtqHa1gPHm1mq9xkOrKPo3o78HokQaT8ERoOsIDB64Va/6wnzZz2ZwO7tF8B/vJ9zCPSvvg2s9H5netMb8LC3bhYB+bXm9T0CB/AKge/Was8HFnvv+T+8E1Oj7Qc4na9HW/Ul8J+2EHgBSPbaU7znhd7rfWu9/1ZvHSyn1mihWNjegOFAgbcd/YPAaCltQ3XX0S+AZd7neIrAiKmo3o50hrmIiARN3VYiIhI0hYeIiARN4SEiIkFTeIiISNAUHiIiEjSFh4iIBE3hISIiQVN4iIhI0P4/EEwdHVX242oAAAAASUVORK5CYII=\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.plot(chord[1])\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "wavfile.write(\"data/test.wav\", chord[0], chord[1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Power Spectral Density\n", "The [Power Spectral Density](https://en.wikipedia.org/wiki/Spectral_density) (psd) is a way of estimating how a signal breaks into its component parts. With audio signals, it tells us how we could have built up our original signal by combining certain elementary (sin and cosine) sound waves. It's a bit like trying to \"unmix\" coloured paint to figure out how much red, blue and yellow went into a given colour. The process is quite complicated, so for the purposes of this notebook we will just understand it at this high level: given a signal, the PSD gives us an estimate of its decomposition into elementary waves, which is like a kind of fingerprint unique to that signal. The PSD is related to the Fourier transform, which you may have heard of - in fact, we can use the Fourier transform to estimate PSD.\n", "\n", "In `scipy.signal`, the `periodogram` method computes the PSD of a signal. We need to supply the signal data, as well as the sample rate. Then `signal.periodogram` returns an array of frequencies, and a corresponding array representing the Power Spectral Density: how much of each pure frequency went into the original signal." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(array([0.00000000e+00, 5.26315789e-01, 1.05263158e+00, ...,\n", " 2.20489474e+04, 2.20494737e+04, 2.20500000e+04]),\n", " array([2.9092380e-26, 6.8505745e+00, 6.6323647e+00, ..., 2.3682150e-03,\n", " 2.6045353e-05, 4.7440056e-04], dtype=float32))" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "psd = signal.periodogram(chord[1], fs = chord[0])\n", "psd" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.plot(psd[0], psd[1])\n", "plt.xlabel(\"Frequency (Hz)\")\n", "plt.title(\"Power Spectral Density\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Comparing Yes and No\n", "Suppose we want to classify between recordings of the word \"yes\", and the word \"no\". Of course, speech recognition is a huge problem and we would need much more than just the PSD to tackle it in general. But if we know in advance that a signal will be saying \"yes\" or \"no\" (for example suppose we were creating an automatic phone system for a big company, that asks the caller a question and routes them according to their answer). Then it turns out that the PSD is in fact enough to differentiate between them.\n", "\n", "Let's see this in action." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "# Obtain mono versions of the recordings\n", "yes = to_mono(wavfile.read(\"data/yes_male.wav\"))\n", "no = to_mono(wavfile.read(\"data/no_male.wav\"))" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "# Get psds\n", "yes_psd = signal.periodogram(yes[1], fs=yes[0])\n", "no_psd = signal.periodogram(no[1], fs=no[0])" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# PSD for yes\n", "plt.plot(yes_psd[0], yes_psd[1])\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# PSD for no\n", "plt.plot(no_psd[0], no_psd[1])\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see that the signal for \"no\" does not contain as much high-frequency as the signal for \"yes\". We will try to create a classifier based on this feature." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Developing a Feature\n", "We will now develop a feature based on the observation above. Given a signal, a feature is a number we can compute whose value is significantly different based on whether a recording is a \"yes\" or a \"no\". We will then use such a feature to classify our recordings.\n", "\n", "One possibility is to add up the PSD for low frequencies, and divide it by the PSD for high frequencies. Then a recording of the word \"no\" should have a higher value than a recording of the word \"yes\". This feature is not sensitive to the length of the recording, and neither is it affected by different volume leves since it is a ratio.\n", "\n", "The easiest way to do this is to choose a hard cutoff between what we regard as high vs low frequency. Then to compute our feature, we just add up the PSD for all frequencies below/above the cutoff, and take their ratio. Looking at the plots above, we can try placing the line between low and high frequency at 5000 Hz.\n", "\n", "Write a function `get_feature` which accepts the PSD of a signal, and returns the feature." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "def get_feature(psd):\n", " lo = 0\n", " hi = 0\n", " for i in range(len(psd[0])):\n", " if psd[0][i] <= 5000:\n", " lo += psd[1][i]\n", " else:\n", " hi += psd[1][i]\n", " return hi/lo" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we need to try our function on some known recordings, to find a threshold value for the feature which distinguishes \"yes\" from \"no\". In `data/yes` and `data/no` are different recordings of the words yes and no: these recordings are our training data. The paths of these files are tored in the csv `data/scipy_training_files.csv`.\n", "\n", "Use numpy to obtain two lists, `yes_paths` and `no_paths`, from the file `scipy_training_files.csv`. The lists should contain the file paths of the training data." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "paths = np.genfromtxt(\"data/scipy_training_files.csv\", dtype=np.str, delimiter=\",\")\n", "yes_paths = paths[0]\n", "no_paths = paths[1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we need to choose a threshold value, below which the feature indicates a \"yes\" and above which it indicates a \"no\". We will decide a threshold value by eye in this exercise.\n", "\n", "You should write code to:\n", "- Read in all of the files with filepaths given in `yes_paths`\n", "- Compute the feature value for each recording\n", "- Repeat the above for the `no_paths` folder" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "y_feats = []\n", "for s in yes_paths:\n", " sound = to_mono(wavfile.read(s))\n", " psd = signal.periodogram(sound[1], fs=sound[0])\n", " feat = get_feature(psd)\n", " y_feats.append(feat)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "scrolled": true }, "outputs": [], "source": [ "n_feats = []\n", "for s in no_paths:\n", " sound = to_mono(wavfile.read(s))\n", " psd = signal.periodogram(sound[1], fs=sound[0])\n", " feat = get_feature(psd)\n", " n_feats.append(feat)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now use `plt` to produce an overlaid plot of two histograms - one counting the feature values for \"yes\" recordings, the other counting the feature values for \"no\" recordings. To make things easier to interpret, you should use the same bins for each histogram - at first, set the bins to be of size 0.01 on the range from 0 to 3. Passing a list of the endpoints of the bins to `plt.hist` will control the size of the bins used.\n", "\n", "Your plot should have a legend, and will be easier to read if you set the parameter `alpha=0.5` in each call to `plt.hist` (this makes the plots appear slightly transparent)." ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "scrolled": true }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "bins = np.arange(0, 3, 0.01)\n", "plt.hist(y_feats, bins, alpha=0.5, label=\"Yes\")\n", "plt.hist(n_feats, bins, alpha = 0.5, label=\"No\")\n", "plt.legend()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we can see, there are some \"Yes\" outliers at the upper end of the scale, making it difficult to see what's happening at the low end. We can copy the above code and change the range of our binning to restrict the plot to the low end of the scale." ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "bins = np.arange(0, 0.5, 0.01)\n", "plt.hist(y_feats, bins, alpha=0.5, label=\"Yes\")\n", "plt.hist(n_feats, bins, alpha = 0.5, label=\"No\")\n", "plt.legend()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Having inspected the above data, determine what you believe to be a good threshold value for this calculation. To choose an exact value, you may wish to inspect the values given in `y_feats` and `n_feats`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Testing Your Classification\n", "Write a function `classify_yesno` which takes in a sound (a bitrate/data tuple), and classifies whether this is the word \"yes\" or the word \"no\". You should return the string `\"Y\"` for yes, and `\"N\"` for no." ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "def classify_yesno(sound):\n", " thresh = 0.023\n", " psd = signal.periodogram(sound[1], fs=sound[0])\n", " feat = get_feature(psd)\n", " if feat > thresh:\n", " return \"Y\"\n", " else:\n", " return \"N\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now run the code cell below. It will test your classifier against test data, and count True Positives (how many \"yes\" recordings were correctly classified as such), True Negatives (how many \"no\" recordings were properly classified), Fale Positives ( where \"no\" was classified as \"yes\"), and False Negatives (where \"yes\" was classified as \"no\")." ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "TP = 0\n", "FP = 0\n", "TN = 0\n", "FN = 0\n", "\n", "paths = np.genfromtxt(\"data/scipy_test_files.csv\", dtype=np.str, delimiter=\",\")\n", "yes_tests = paths[0]\n", "no_tests = paths[1]\n", "\n", "for s in yes_tests:\n", " sound = to_mono(wavfile.read(s))\n", " if classify_yesno(sound) == \"Y\":\n", " TP += 1\n", " else:\n", " FN += 1\n", " \n", "for s in no_tests:\n", " sound = to_mono(wavfile.read(s))\n", " if classify_yesno(sound) == \"N\":\n", " TN += 1\n", " else:\n", " FP += 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This data can be summarised in a confusion matrix. In this matrix, the (0, 0) entry of the confusion matrix shows True Positives, and the (1, 1) entry shows True Negatives. Since we tested our classifier on 8 samples of each type, then the closer our matrix looks to $$\\begin{bmatrix}8 & 0\\\\ 0 & 8 \\end{bmatrix}$$ the better our classifier is performing." ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[5, 0],\n", " [3, 8]])" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "confusion_matrix = np.reshape(np.array([TP, FP, FN, TN]), (2, 2))\n", "\n", "confusion_matrix" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We could also compute a summary statistic of the classifier's performance. One such statistic is the accuracy: that is the proportion of the recordings correctly classified. it is calculated as $$\\frac{TP + TN}{TP + TN + FP + FN}$$." ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.8125" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "acc = (TP + TN)/(TP + FP + TN + FN)\n", "\n", "acc" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In reality, we'd likely train and test on much more data. We would also train the classifier using some form of predictive model, rather than by eyeballing the data. Packages such as [scikit-learn](https://scikit-learn.org/stable/index.html) have easy-to-use inbuilt functions for building and testing classifiers (in fact, sklearn has its own project notebook as part of this course)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## References\n", "This notebook was based on a project from \"Enhance your DSP Course with these Interesting Projects\" by D. Hoffbeck, in proceedings AC 2012-3836, the American Society for Engineering Education, 2012. \n", "\n", "Training files were obtained from freesound. Licensing info and accreditation is given in scipy_training_licensing.txt.\n", "\n", "Testing files were recorded by the author." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.6" } }, "nbformat": 4, "nbformat_minor": 2 }