Ungraded Lab: Feature Engineering with Accelerometer Data

This notebook demonstrates how to prepare time series data taken from an accelerometer. We will be using the WISDM Human Activity Recognition Dataset for this example. This dataset can be used to predict the activity a user performs from a set of acceleration values recorded from the accelerometer of a smartphone.

The dataset consists of accelerometer data in the x, y, and z-axis recorded for 36 user different users. A total of 6 activities: 'Walking','Jogging', 'Upstairs', 'Downstairs', 'Sitting', and 'Standing' were recorded. The sensors have a sampling rate of 20Hz which means there are 20 observations recorded per second.

Install Packages

As with the previous lab, you will install the tensorflow_transform Python package and its dependencies.

Note: In Google Colab, you need to restart the runtime at this point to finalize updating the packages you just installed. You can do so by clicking the Restart Runtime at the end of the output cell above (after installation), or by selecting Runtime > Restart Runtime in the Menu bar. Please do not proceed to the next section without restarting. You can also ignore the errors about version incompatibility of some of the bundled packages because we won't be using those in this notebook.

Imports

Running the imports below should not show any error. Otherwise, please restart your runtime or re-run the package installation cell above.

Download the Data

Next, you will download the data and put it in your workspace.

Inspect the Data

You should now inspect the dataset and you can start by previewing it as a dataframe.

You might notice the semicolon at the end of the z-acc elements. This might cause the elements to be treated as a string so you may want to remove it when analyzing your data. You will do this later in the pipeline with Beam.map(). This is also taken care of by the visualize_plots() function below which you will use in the next section.

Histogram of Activities

You can now proceed with the visualizations. You can plot the histogram of activities and make your observations. For instance, you'll notice that there is more data for walking and jogging than other activities. This might have an effect on how your model learns each activity so you should take note of it. For example, you may want to collect more data for the other activities.

Histogram of Measurements per User

You can also observe the number of measurements taken per user.

You can consult with field experts on which of the users you should be part of the training or test set. For this lab, you will just do a simple partition. You will put user ids 1 to 30 in the train set, and the rest in the test set. Here is the partition_fn you will use for Beam.Partition() later.

Acceleration per Activity

Finally, you can plot the sensor measurements against the timestamps. You can observe that acceleration is more for activities like jogging when compared to sitting which should be the expected behaviour. If this is not the case, then there might be problems with the sensor and can make the data invalid.

Declare Schema for Cleaned Data

As usual, you will want to declare a schema to make sure that your data input is parsed correctly.

Create a tf.Transform preprocessing_fn

You can then define your preprocessing function. For this exercise, you will scale the float features by their min-max values and create a vocabulary lookup for the string label. You will also discard features that you will not need in the model such as the user id and timestamp.

Transform the data

Now you're ready to start transforming the data in an Apache Beam pipeline using Tensorflow Transform. It will follow these major steps:

  1. Read in the data using beam.io.ReadFromText
  2. Clean it using beam.Map and beam.Filter
  3. Transform it using a preprocessing pipeline that scales numeric data and converts categorical data from strings to int64 values indices.
  4. Write out the result as a TFRecord of Example protos, which can be used for training a model later.

Prepare Training and Test Datasets from TFTransformOutput

Now that you have the transformed examples, you now need to prepare the dataset windows for this time series data. As discussed in class, you want to group a series of measurements and that will be the feature for a particular label. In this particular case, it makes sense to group consecutive measurements and use that as the indicator for an activity. For example, if you take 80 measurements and it oscillates greatly (just like in the visualizations in the earlier parts of this notebook), then the model should be able to tell that it is a 'Running' activity. Let's implement that in the following cells using the tf.data.Dataset.window() method. Notice that there is an add_mode() function. If you remember how the original CSV looks like, you'll notice that each row has an activity label. Thus if we want to associate a single activity to a group of 80 measurements, then we just get the activity that is mentioned most in all those rows (e.g. if 75 elements of the window point to Walking activity and only 5 point to 'Sitting, then the entire window is associated toWalking`).

You should see a sample of a dataset window above. There are 80 consecutive measurements of x-acc, y-acc, and z-acc that correspond to a single labeled activity. Moreover, you also set it up to be in batches of 100 windows. This can now be fed to train an LSTM so it can learn how to detect activities based on 80-measurement windows. You can also preview a sample in the test set:

Wrap Up

In this lab, you were able to prepare time-series data from an accelerometer to transformed features that are grouped into windows to make predictions. The same concept can be applied to any data where you need take a few seconds of measurements before the model makes a prediction.