{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Dataset Overview\n\nThe dataset we are working with is provided by [Parinaz Kasebzadeh](http://users.isy.liu.se/rt/parka23/publications/IPIN2017.pdf). The dataset consists of path trace recordings of a person walking/standing still/running from one point to another. During the traversal, the following sensor signals are recorded:\n* acceleration(accelerometer)\n* magnetic field(magnetometer)\n* Angular Velocity/Orientation(gyroscope)\n* pressure(barometer)\n* GPS signal as ground truth","metadata":{}},{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nfrom dataclasses import dataclass\n\nimport matplotlib.pyplot as plt # visualization\nplt.rcParams.update({'font.size': 14})\nimport seaborn as sns # visualization\n\nimport warnings # Supress warnings \nwarnings.filterwarnings('ignore')\n\nfrom tqdm import tqdm\n\nimport json\nimport plotly.graph_objs as go\n\nfrom sklearn import preprocessing","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gps_data = pd.read_csv('../input/iotdataset/Case1_GPS.csv')\ngps_data.columns = ['time', 'latitude', 'longitude', 'some_number']\n\nord = {'S':0,\n       'W': 1,\n       'R': 2}\n\nacc_data = pd.read_csv('../input/iotdataset/Case1_AccR.csv')\nacc_data.columns = ['time', 'accx', 'accy', 'accz']\nacc_gt = pd.read_csv('../input/iotdataset/Case1_GT_phone_AccR.csv')\nacc_gt.columns = ['c1', 'c2']\nacc_data['c1'] = acc_gt['c1']\nacc_data['c2'] = acc_gt['c2']\nacc_data['gt'] = acc_gt['c1'].map(str) + acc_gt['c2'].map(str)\nacc_data['c1'] = acc_data.c1.map(ord)\n\nang_data = pd.read_csv('../input/iotdataset/Case1_AngVelR.csv')\nang_data.columns = ['time', 'angx', 'angy', 'angz']\nang_gt = pd.read_csv('../input/iotdataset/Case1_ GT_phone_AngVelR.csv')\nang_gt.columns = ['c1', 'c2']\nang_data['c1'] = ang_gt['c1']\nang_data['c2'] = ang_gt['c2']\nang_data['gt'] = ang_gt['c1'].map(str) + ang_gt['c2'].map(str)\nang_data['c1'] = ang_data.c1.map(ord)\n\nmag_data = pd.read_csv('../input/iotdataset/Case1_MagR.csv')\nmag_data.columns = ['time', 'magx', 'magy', 'magz']\nmag_gt = pd.read_csv('../input/iotdataset/Case1_GT_phone_MagR.csv')\nmag_gt.columns = ['c1', 'c2']\nmag_data['c1'] = mag_gt['c1']\nmag_data['c2'] = mag_gt['c2']\nmag_data['gt'] = mag_gt['c1'].map(str) + mag_gt['c2'].map(str)\nmag_data['c1'] = mag_data.c1.map(ord)\n\nori_data = pd.read_csv('../input/iotdataset/Case1_OriR.csv')\nori_data.columns = ['time', 'orix', 'oriy', 'oriz']\nori_gt = pd.read_csv('../input/iotdataset/Case1_GT_phone_OriR.csv')\nori_gt.columns = ['c1', 'c2']\nori_data['c1'] = ori_gt['c1']\nori_data['c2'] = ori_gt['c2']\nori_data['gt'] = ori_gt['c1'].map(str) + ori_gt['c2'].map(str)\nori_data['c1'] = ori_data.c1.map(ord)\n\npre_data = pd.read_csv('../input/iotdataset/Case1_Pressure.csv')\npre_data.columns = ['time', 'pressure']\npre_gt = pd.read_csv('../input/iotdataset/Case1_GT_phone_Pressure.csv')\npre_gt.columns = ['c1', 'c2']\npre_data['c1'] = pre_gt['c1']\npre_data['c2'] = pre_gt['c2']\npre_data['gt'] = pre_gt['c1'].map(str) + pre_gt['c2'].map(str)\npre_data['c1'] = pre_data.c1.map(ord)","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from mpl_toolkits.basemap import Basemap\nplt.figure(1, figsize=(12,6))\nlon_min, lon_max = 6.8, 6.8599\nlat_min, lat_max = 52.2, 52.239\n\n\nimg = plt.imread('../input/geo-loc/Untitled design.png')\nplt.imshow(img)\n\nplt.title(\"GPS mapping of the plot\")\nplt.show()\n\n# Mercator of France\nm1 = Basemap(projection='merc',\n             llcrnrlat=lat_min,\n             urcrnrlat=lat_max,\n             llcrnrlon=lon_min,\n             urcrnrlon=lon_max,\n             lat_ts=35,\n             resolution='c')\n\nm1.fillcontinents(color='#191919',lake_color='#000000') # dark grey land, black lakes\nm1.drawmapboundary(fill_color='#000000')                # black background\nm1.drawcountries(linewidth=0.1, color=\"w\")              # thin white line for country borders\n\n# Plot the data\nmxy = m1(gps_data[\"longitude\"].tolist(), gps_data[\"latitude\"].tolist())\nm1.scatter(mxy[0], mxy[1], s=3, c=\"#1292db\", lw=0, alpha=1, zorder=5)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Inertial Measurement Unit (IMU)\nThe inertial measurement unit (IMU) is a sensor that measures the force, angular rate and orientation of a body. In this case, the body is a phone. These values are measured by accelerometers, gyroscopes, and in this case also magnetometers. \n* **Accelerometer**: Measures change in velocity ($m/s^2$) \n* **Gyroscopes**: Measures change in rotation ($rad/s$)\n* **Magnetometer**: Measures magnetic field ($\\mu T$)\n\nThe IMU sensor data has the same shape in this case. Note, that this is true for a lot of traces but not all of them. We can concatenate them to a dataframe for the initial analysis of the data.","metadata":{}},{"cell_type":"markdown","source":"Let's have a look at the acceleration first.","metadata":{}},{"cell_type":"code","source":"def plot_imu_signals(df, col, units, title):\n    fig, ax = plt.subplots(nrows=3, ncols=1, figsize=(14, 9))\n    ax[0].set_ylabel(f\"{col}_x (in {units})\")\n    ax[1].set_ylabel(f\"{col}_y (in {units})\")\n    ax[2].set_ylabel(f\"{col}_z (in {units})\")\n    \n    ax[0].plot(df.time, df[f\"{col}x\"])\n    ax[1].plot(df.time, df[f\"{col}y\"])\n    ax[2].plot(df.time, df[f\"{col}z\"])\n\n    plt.tight_layout()\n    plt.title(f\"{title}\", y=-0.01)\n    plt.show()\n    \nplot_imu_signals(acc_data, 'acc', 'm/s^2', 'acceleration')   \n","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The first thing, we can notice is that the mean value of acce_z looks familiarly close to the standard gravity $g=9.8 m/s^2$.\n\nThat is why the value of the z-axis corresponds to $g$.","metadata":{}},{"cell_type":"code","source":"# > Therefore, to measure the real acceleration of the device, the contribution of the force of gravity must be removed from the accelerometer data. \n# This can be achieved by applying a high-pass filter. Conversely, a low-pass filter can be used to isolate the force of gravity. \n# The following example shows how you can do this -[Android Developer Docs: Motion Sensors](https://developer.android.com/guide/topics/sensors/sensors_motion#java)\n\n# In this example, alpha is calculated as t / (t + dT),\n# where t is the low-pass filter's time-constant and\n# dT is the event delivery rate.\n\nalpha = 0.8\n\nacc_data['g_x'] = 0\nacc_data['g_y'] = 0\nacc_data['g_z'] = 9.81\n\nacc_data['g_x'] = alpha * acc_data['g_x'] + (1 - alpha) * acc_data['accx'];\nacc_data['g_y'] = alpha * acc_data['g_y'] + (1 - alpha) * acc_data['accy'];\nacc_data['g_z'] = alpha * acc_data['g_z']  + (1 - alpha) * acc_data['accz'];\n\nfig, ax = plt.subplots(nrows=1, ncols=1, figsize=(14, 3))\n\nplt.plot(acc_data.time, acc_data[\"accy\"])\nplt.plot(acc_data.time, acc_data[\"g_y\"])\nplt.show()","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_imu_signals(ang_data, 'ang', 'rad/s', 'angular velocity')   ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_imu_signals(mag_data, 'mag', 'gauss', 'magnetic flux')   ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_imu_signals(ori_data, 'ori', 'deg', 'orientation')   ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\nacc_X_train, acc_X_test, acc_y_train, acc_y_test = train_test_split(acc_data[['accx', 'accy', 'accz']], acc_data.c1, test_size=0.3, random_state=42)\nang_X_train, ang_X_test, ang_y_train, ang_y_test = train_test_split(ang_data[['angx', 'angy', 'angz']], ang_data.c1, test_size=0.3, random_state=42)\nmag_X_train, mag_X_test, mag_y_train, mag_y_test = train_test_split(mag_data[['magx', 'magy', 'magz']], mag_data.c1, test_size=0.3, random_state=42)\nori_X_train, ori_X_test, ori_y_train, ori_y_test = train_test_split(ori_data[['orix', 'oriy', 'oriz']], ori_data.c1, test_size=0.3, random_state=42)\npre_X_train, pre_X_test, pre_y_train, pre_y_test = train_test_split(pre_data[['pressure']], pre_data.c1, test_size=0.3, random_state=42)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.ensemble import RandomForestClassifier\n\nacc_model = RandomForestClassifier(n_estimators=1000)\nacc_model.fit(acc_X_train, acc_y_train)\nacc_score = acc_model.score(acc_X_test, acc_y_test)\n\nang_model = RandomForestClassifier(n_estimators=1000)\nang_model.fit(ang_X_train, ang_y_train)\nang_score = ang_model.score(ang_X_test, ang_y_test)\n\nori_model = RandomForestClassifier(n_estimators=1000)\nori_model.fit(ori_X_train, ori_y_train)\nori_score = ori_model.score(ori_X_test, ori_y_test)\n\nmag_model = RandomForestClassifier(n_estimators=1000)\nmag_model.fit(mag_X_train, mag_y_train)\nmag_score = mag_model.score(mag_X_test, mag_y_test)\n\npre_model = RandomForestClassifier(n_estimators=1000)\npre_model.fit(pre_X_train, pre_y_train)\npre_score = pre_model.score(pre_X_test, pre_y_test)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"The final accuracy scores are as follows:\\n- Acceleration: {0:.2f}%\\n- Angular velocity: {1:.2f}%\\n- Orientation: {2:.2f}%\\n- Magnitude: {3:.2f}%\\n- Pressure: {4:.2f}%\\n\".format(acc_score*100, ang_score*100, ori_score*100, mag_score*100, pre_score*100))","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}