{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom scipy import fftpack\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom scipy import signal","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ebb46d4b34f6bb8feab7287d761f0eb5faa94144"},"cell_type":"code","source":"%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1ffd3b2dca2bb8f62d2b87ab9020eb56530abc44"},"cell_type":"markdown","source":"## Intro\nThe acoustic data can be analyzed in frequency space. It gives a pretty different feeling and the information that exists in the data.\n\nI wanted to show you 4 things:\n1. Frequency representation of the data\n2. Some nice compresion\n3. Different \"compresion\" - frequency bins\n4. Data size can be reduced easily with no lost in the frequeny information\n\nLet's take a look at what we've got here."},{"metadata":{"trusted":true,"_uuid":"685b96eb9f2ab1d9c6a46d360ff3adacac350cc7","_kg_hide-input":true},"cell_type":"code","source":"train = pd.read_csv('../input/train.csv', nrows=10000000, dtype={'acoustic_data': np.int16, 'time_to_failure': np.float64})\nprint(\"train shape\", train.shape)\ntrain.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"28c16458f50e9bf3a6a6993f4d3fd60c9829b2db"},"cell_type":"markdown","source":"I set the important parameter here, that will be crucial in proper calculations"},{"metadata":{"trusted":true,"_uuid":"6daf6ec56d25f389310cdc8c0349a13bac165e83","_kg_hide-output":true},"cell_type":"code","source":"sampling_rate = 4000000","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d46a3996a9bc42e533d5be248689efd0fce1ac1d"},"cell_type":"markdown","source":"## Frequency representation of the data"},{"metadata":{"_uuid":"8624d03c84536eaaa88bd492cde4108e5cb6a043"},"cell_type":"markdown","source":"The pitch perception of the ear is proportional to the logarithm of frequency rather than to frequency itself. We can't hear most of the frequencies that exist here (0 - 2000000 vs 0-20000 Hz), but watching the frequencies in logarithmic scale is much nicer.\n\nSo I define _log_specgram_ funcion to calcuate the logarithm of STFT, and a funciton to visualize it."},{"metadata":{"trusted":true,"_uuid":"b241956b571b68dc953ba4a776fef6be2fbe2ab0","_kg_hide-input":true},"cell_type":"code","source":"def log_specgram(data, sample_rate, nperseg=2000, noverlap=1000, eps=1e-10, dct=False):\n    freqs, times, spec = signal.spectrogram(data,\n                                            fs=sample_rate,\n                                            window='hann',\n                                            nperseg=nperseg,\n                                            noverlap=noverlap,\n                                            detrend=False)\n    spec = np.log(spec).astype(np.float32)\n    if dct:\n        spec = fftpack.dct(spec, type=2, axis=0, norm='ortho')\n    return freqs, times, spec\n\n\ndef plot_specgram(data, sample_rate, final_idx, init_idx=0, step=1, nperseg=2000, \n                  noverlap=1000, dct=False, title='', subsampling=False):\n    idx = [i for i in range(init_idx, final_idx, step)]\n    acoustic_data = data.iloc[idx].acoustic_data.values\n    if subsampling:\n        acoustic_data = acoustic_data[::subsampling]\n    freqs, times, spectrogram = log_specgram(acoustic_data, sample_rate, \n                                             nperseg=nperseg, noverlap=noverlap, dct=dct)\n\n    plt.figure(figsize=(10, 8))\n    plt.imshow(spectrogram, aspect='auto', origin='lower',\n               extent=[times.min(), times.max(), freqs.min(), freqs.max()])\n    plt.title(title)\n    plt.ylabel('Freqs in Hz')\n    plt.xlabel('Seconds')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","collapsed":true,"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":false},"cell_type":"markdown","source":"I also borrowed a function from the kernel I really liked:\nhttps://www.kaggle.com/jsaguiar/seismic-data-exploration"},{"metadata":{"trusted":true,"_uuid":"ceee05ebbc5d9b75cd40ef8e5772255f28fa33d2","_kg_hide-input":true},"cell_type":"code","source":"def single_timeseries(final_idx, init_idx=0, step=1, title=\"\",\n                      color1='orange', color2='blue', subsampling=False):\n    idx = [i for i in range(init_idx, final_idx, step)]\n    fig, ax1 = plt.subplots(figsize=(10, 5))\n    fig.suptitle(title, fontsize=14)\n    \n    ax2 = ax1.twinx()\n    ax1.set_xlabel('index')\n    ax1.set_ylabel('Acoustic data')\n    ax2.set_ylabel('Time to failure')\n    acoustic_data = train.iloc[idx].acoustic_data.values\n    time_to_failure = train.iloc[idx].time_to_failure.values\n    if subsampling:\n        acoustic_data = acoustic_data[::subsampling]\n        time_to_failure = time_to_failure[::subsampling]\n\n    p1 = sns.lineplot(data=acoustic_data, ax=ax1, color=color1)\n    p2 = sns.lineplot(data=time_to_failure, ax=ax2, color=color2)\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"bc88a226077b109d8e63eff0341d79bfb0a95b30"},"cell_type":"markdown","source":"Let's plot some data:"},{"metadata":{"trusted":true,"_uuid":"f2f662bbfb1aa313bca286f2b0b3800c95a951f2"},"cell_type":"code","source":"plot_specgram(train, sampling_rate, 100000, title='Specgram of first hundred thousand rows')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c9fd3edffacd5eca67a3072b251595e03488b977"},"cell_type":"code","source":"single_timeseries(100000, title=\"First hundred thousand rows\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"22b3f583c8a109d52283ad2a4974216a5bcc6d4e"},"cell_type":"markdown","source":"Earthquake data:"},{"metadata":{"trusted":true,"_uuid":"31911a5c6d5d6b2ac95ae98d1a3f7acdafc66b15"},"cell_type":"code","source":"plot_specgram(train, sampling_rate, final_idx=6000000, init_idx=5000000, \n              title='Specgram of earthquake')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b0d435ae9a8d62bda512c9d835922365480581bc"},"cell_type":"code","source":"single_timeseries(final_idx=6000000, init_idx=5000000, title=\"Five to six million index\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c00f1429ab9b5c7559c8db7f5ebb67265b1b99e1"},"cell_type":"markdown","source":"## DCT - Discrete Cosinous Transform\n\nOne of the steps in the popular algorithm in acoustic signal analysis, MFCC (Mel-Frequency-Cepstral-Coefficients), is Discrete Cosine Transform. According to [wikipedia](https://en.wikipedia.org/wiki/Discrete_cosine_transform), it can decorrelate some signals very well. It happens fast and online. You can think about like doing some PCA on data."},{"metadata":{"trusted":true,"_uuid":"bd8e08a4fec12edf4609c5d2cfa2d61153af847e"},"cell_type":"code","source":"plot_specgram(train, sampling_rate, 10000, title='Specgram of first hundred thousand rows', dct=True)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"715b2089d6f0c0a30650e598368c4c98deefddb8"},"cell_type":"markdown","source":"It's up to you how and if to use it. It works very well in speech recognition. You can plot fewer components to choose the threshold for the number of it."},{"metadata":{"_uuid":"6153094649f1969e4d391d8e12c6db1ed79b44c6"},"cell_type":"markdown","source":"## Data size reduction - subsampling"},{"metadata":{"_uuid":"40cb69c613fc66371b75506bb072af4c2e54fd3f"},"cell_type":"markdown","source":"You can see that there's a lot of 'blank' space in the spectrogram. It looks like most of the high frequencies are just noise. We can subsample the data by, let's say 4, to leave only the meaningful part of the signal. Without going into details, we just need to take every 4th sample and change the sampling rate to 1M.\n I'm gonna plot some part of the data, but subsampled. You can compare it to the original format.\n"},{"metadata":{"trusted":true,"_uuid":"8e4c8332e328d7b746f6708d7e3e7e755b0a80e4"},"cell_type":"code","source":"single_timeseries(80000, title=\"First eighty thousand rows\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f1fecd99922ec9bdd6b14e9ba92b8ce1cc55a20d"},"cell_type":"code","source":"plot_specgram(train, sampling_rate, 80000, title='Specgram of first eighty thousand rows')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"aecd206cf01fb6db94b87ec8ba629ec51d8744a4"},"cell_type":"code","source":"single_timeseries(80000, title=\"First eighty thousand rows - subsampled\", subsampling=4)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"69b6cb48873761cc38967a1eeedbb55b2d1dde4b"},"cell_type":"code","source":"plot_specgram(train, sample_rate=1000000, final_idx=80000, nperseg=500, noverlap=250, \n              title='Subsampled specgram of first eighty thousand rows', subsampling=4)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"407572fdad9a178368b32a6b82948011baf35662"},"cell_type":"markdown","source":"Skipping every 3 samples, we can carry the same frequency information, having the data size 4 times smaller!"},{"metadata":{"_uuid":"f74e16f7b24bc4e66fca728b00f6eba9a9b51712"},"cell_type":"markdown","source":"I hope my presentation shows you some interesting ideas. Don't forget to upvote if you like it."}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}