FrenchEnglishChinese (Simplified)Spanish

notre livre
Data Science

Récupérer et nettoyer des données dans le cadre de la reconnaissance d’une activité humaine

Avant de pouvoir travailler avec des données, il faut bien entendu les récolter et surtout vous assurer qu’elles soient “propres” avant toute manipulation. Dans cet article, nous verrons comment recueillir, travailler et nettoyer un ensemble de données (dataset) construit à partir d’enregistrement de 30 sujets réalisant des activités de la vie quotidienne (ADL en anglais). Ces enregistrements ont été effectués en faisant porter un smartphone à la taille des sujets, avec des capteurs inertiels intégrés.

Récupérer et nettoyer des données dans le cadre de la reconnaissance d’une activité humaine 7

En pleine expansion depuis quelques années, le secteur des “wearables” (informatique portable ou informatique vestimentaire) est également un sujet d’étude passionnant pour la Data Science. Des entreprises comme Apple, Samsung, Withings, Fitbit ou encore Nike se sont lancés dans une course permanente pour développer les algorithmes les plus avancés et ainsi attirer de nouveaux utilisateurs.

Les données prises en compte dans cette analyse ont été collectées à partir des accéléromètres du smartphone Samsung Galaxy S. Une description complète est disponible dans le référentiel UC Irvine Machine Learning, à partir duquel les données ont été obtenues :

http://archive.ics.uci.edu/ml/datasets/Human+Activity+Recognition+Using+Smartphones

Voici les données utilisées pour cette analyse :

https://d396qusza40orc.cloudfront.net/getdata%2Fprojectfiles%2FUCI%20HAR%20Dataset.zip

Le but de cette analyse est d’obtenir un dataset “propre” qui fournira les mesures sur la moyenne et l’écart-type pour chaque variable. Pour cela, nous appliquerons un processus en 4 étapes:

  1. Fusionner le dataset d’entraînement et le dataset de test pour créer un dataset unique.
  2. Extraire uniquement les mesures sur la moyenne et l’écart type pour chaque variable.
  3. Labelliser correctement le dataset avec des noms de variables descriptifs.
  4. À partir du dataset créé à l’étape précédente, créer un deuxième dataset indépendant rangé avec la moyenne de chaque variable pour chaque activité et chaque sujet.

 

Les expériences ont été menées avec un groupe de 30 volontaires dans une tranche d’âge de 19 à 48 ans. Chaque personne a réalisé six activités (WALKING, WALKING_UPSTAIRS, WALKING_DOWNSTAIRS, SITTING, STANDING, LAYING) portant un smartphone (Samsung Galaxy S II) à la taille. En utilisant l’accéléromètre et le gyroscope intégrés, une accélération linéaire à 3 axes et une vitesse angulaire à 3 axes ont été capturées à une fréquence constante de 50 Hz. Les expériences ont été enregistrées sur vidéo pour labelliser les données manuellement. Le dataset obtenu a été partitionné au hasard en deux ensembles, où 70% des volontaires ont été sélectionnés pour générer les données d’entraînement et 30% les données de test. Les signaux du capteur (accéléromètre et gyroscope) ont été prétraités en appliquant des filtres de bruit, puis échantillonnés dans des fenêtres coulissantes de valeur fixe (2,56 secondes avec un chevauchement de 50% (128 lectures / fenêtre)). Le signal d’accélération du capteur, qui dispose de composants gravitationnels et de mouvement corporel, a été séparé à l’aide d’un filtre passe-bas Butterworth en accélération corporelle et gravité. On suppose que la force gravitationnelle n’a que des composantes à basse fréquence, c’est pourquoi un filtre avec une fréquence de coupure de 0,3 Hz a été utilisé. A partir de chaque fenêtre, un vecteur de caractéristiques a été obtenu en calculant des variables du domaine temporel et fréquentiel.

 

Description du dataset

Les fonctionnalités sélectionnées pour cette base de données proviennent des signaux bruts 3 axes de l’accéléromètre et du gyroscope (tAcc-XYZ and tGyro-XYZ). Ces signaux du domaine temporel (le préfixe ‘t’ a été ajouté pour désigner le temps) ont été capturés à une fréquence constante de 50 Hz. Le signal d’accélération a ensuite été séparé en signaux d’accélération corporelle et gravimétrique (tBodyAcc-XYZ et tGravityAcc-XYZ) – tous deux utilisant un filtre de Butterworth passe-basL’accélération linéaire du corps et la vitesse angulaire ont été dérivées dans le temps pour obtenir des signaux de secousse (tBodyAccJerk-XYZ and tBodyGyroJerk-XYZ). La magnitude de ces signaux tridimensionnels a également été calculée en utilisant la norme euclidienne (tBodyAccMag, tGravityAccMag, tBodyAccJerkMag, tBodyGyroMag, tBodyGyroJerkMag). Une transformation de Fourier rapide(FFT) a été appliquée à certains de ces signaux produisant fBodyAcc-XYZ, fBodyAccJerk-XYZ, fBodyGyro-XYZ, fBodyAccJerkMag, fBodyGyroMag, fBodyGyroJerkMag. (À noter que le suffixe ‘f’ indique une fréquence).

 

Description des abréviations :

  • Un suffice “t” ou “f” indique respectivement des mesures de temps ou de fréquence
  • Body = lié au mouvement du corps
  • Gravity = accélération de la gravité
  • Acc = mesures de l’accéléromètre
  • Gyro = mesures du gyroscope
  • Jerk = mouvement soudain d’accélération (secousse)
  • Mag = ampleur du mouvement
  • la moyenne et l’écart type sont calculés pour chaque sujet pour chaque activité : mean() , std()

 

Les unités utilisées sont le g pour l’accéléromètre, rad/sec pour le gyroscope, g/sec et rad/sec/sec pour les secousses respectives.

 

APPLICATION

Récupérer et nettoyer des données dans le cadre de la reconnaissance d’une activité humaine 8

Pour cet exercice, nous travaillerons sur R. Tout d’abord, nous devons collecter les données. Pour cela, nous créons un fichier temporaire :

temp

En utilisant download.file() nous récupérons le dataset dans le fichier temporaire :

download.file(“https://d396qusza40orc.cloudfront.net/getdata%2Fprojectfiles%2FUCI%20HAR%20Dataset.zip”,temp)

Pour afficher le nom et le chemin des fichiers contenus dans l’archive que nous utilisons unzip() :

unzip(temp, list=T)

  • UCI HAR Dataset/activity_labels.txt
  • UCI HAR Dataset/features.txt
  • UCI HAR Dataset/train/X_train.txt
  • UCI HAR Dataset/train/y_train.txt
  • UCI HAR Dataset/train/subject_train.txt
  • UCI HAR Dataset/test/X_test.txt
  • UCI HAR Dataset/test/y_test.txt
  • UCI HAR Dataset/test/subject_test.txt

 

Maintenant que nous savons quels fichiers sont contenus dans l’archive, nous décidons quels fichiers nous devons lire et convertir afin de pouvoir réaliser notre analyse :

features

features

activityLabels

activityLabels

dataTrainX

dataTrainY

dataTrainSubject

dataTestX

dataTestY

dataTestSubject

 

Puisque nous avons fini d’importer dans notre espace de travail toutes les données dont nous avons besoin, nous pouvons supprimer le fichier temporaire grâce à unlink() :

unlink(temp)

 

Grâce à la fonction str()nous examinons les propriétés des variables ci-dessus :

str(features)

str(activityLabels)

str(dataTrainX)

str(dataTrainY)

str(dataTrainSubject)

str(dataTestX)

str(dataTestY)

str(dataTestSubject)

 

La prochaine étape sera de combiner X_train, y_train et subject_train dans un data frame “train”, et X_test, y_test et subject_test dans un data frame “test”:

dataTrain dataTest

 

Désormais, nous pouvons renommer correctement les colonnes des nouveaux blocs de données à l’aide du dataset «features» que nous avons précédemment importé :

names(dataTrain) names(dataTest)

 

 

Récupérer et nettoyer des données dans le cadre de la reconnaissance d’une activité humaine 9

Nous appliquons ensuite le processus en 4 étapes évoqué au début de l’article :

 

1. Fusionner le dataset d’entraînement et le dataset de test pour créer un dataset unique.

data

 

2. Extraire uniquement les mesures sur la moyenne et l’écart type pour chaque variable.

dataExtr

Nous pouvons vérifier la structure du data frame “dataExtr” :

str(dataExtr)

 

3. Labelliser correctement le dataset avec des noms de variables descriptifs.

Voici les noms des variables dans “dataExtr” :

names(dataExtr)

 

Nous recherchons maintenant les labels que nous devons modifier :

unique(gsub(“-(mean|std)().*”, “”, names(dataExtr)[-c(1:2)]))

 

Afin de labelliser le dataset avec des noms descriptifs, nous allons apporter les modifications suivantes (le code est disponible plus bas) :

  • le préfixe t est remplacé par “time”
  • Acc est remplacé par “Accelerometer”
  • Gyro est remplacé par “Gyroscope”
  • Le préfixe f est remplacé par “frequency”
  • Mag est remplacé par “Magnitude”
  • BodyBody est remplacé par “Body”

 

names(dataExtr)[-c(1:2)]

names(dataExtr)[-c(1:2)]

names(dataExtr)[-c(1:2)]

names(dataExtr)[-c(1:2)]

names(dataExtr)[-c(1:2)]

names(dataExtr)[-c(1:2)]

 

Nous pouvons vérifier les nouvelles propriétés du data frame “dataExtr :

names(dataExtr)

str(dataExtr)

 

4. À partir du dataset créé à l’étape précédente, créer un deuxième dataset indépendant rangé avec la moyenne de chaque variable pour chaque activité et chaque sujet.

tidyData

tidyData

 

Le dataset “tidyData” comprend la moyenne de chaque variable pour chaque activité et chaque sujet. 10299 instances sont réparties en 180 groupes (30 sujets et 6 activités) et 66 caractéristiques d’écart moyen et standard sont moyennées pour chaque groupe. Le tableau de données qui en résulte comporte 180 lignes et 68 colonnes – 33 variables moyennes + 33 variables d’écart type + 1 sujet (1 des 30 sujets de test) + ActivityName. La première ligne du dataset correctement rangé est l’en-tête contenant les noms de chaque colonne.

 

Grâce à la fonction str() nous pouvons lister et décrire toutes les variables de notre dataset :


str(tidyData)

#'data.frame': 180 obs. of 68 variables:
# $ subject : int 1 1 1 1 1 1 2 2 2 2 ...
# $ activity : chr "LAYING" "SITTING" "STANDING" "WALKING" ...
# $ timeBodyAccelerometer-mean()-X : num 0.222 0.261 0.279 0.277 0.289 ...
# $ timeBodyAccelerometer-mean()-Y : num -0.04051 -0.00131 -0.01614 -0.01738 -0.00992 ...
# $ timeBodyAccelerometer-mean()-Z : num -0.113 -0.105 -0.111 -0.111 -0.108 ...
# $ timeBodyAccelerometer-std()-X : num -0.928 -0.977 -0.996 -0.284 0.03 ...
# $ timeBodyAccelerometer-std()-Y : num -0.8368 -0.9226 -0.9732 0.1145 -0.0319 ...
# $ timeBodyAccelerometer-std()-Z : num -0.826 -0.94 -0.98 -0.26 -0.23 ...
# $ timeGravityAccelerometer-mean()-X : num -0.249 0.832 0.943 0.935 0.932 ...
# $ timeGravityAccelerometer-mean()-Y : num 0.706 0.204 -0.273 -0.282 -0.267 ...
# $ timeGravityAccelerometer-mean()-Z : num 0.4458 0.332 0.0135 -0.0681 -0.0621 ...
# $ timeGravityAccelerometer-std()-X : num -0.897 -0.968 -0.994 -0.977 -0.951 ...
# $ timeGravityAccelerometer-std()-Y : num -0.908 -0.936 -0.981 -0.971 -0.937 ...
# $ timeGravityAccelerometer-std()-Z : num -0.852 -0.949 -0.976 -0.948 -0.896 ...
# $ timeBodyAccelerometerJerk-mean()-X : num 0.0811 0.0775 0.0754 0.074 0.0542 ...
# $ timeBodyAccelerometerJerk-mean()-Y : num 0.003838 -0.000619 0.007976 0.028272 0.02965 ...
# $ timeBodyAccelerometerJerk-mean()-Z : num 0.01083 -0.00337 -0.00369 -0.00417 -0.01097 ...
# $ timeBodyAccelerometerJerk-std()-X : num -0.9585 -0.9864 -0.9946 -0.1136 -0.0123 ...
# $ timeBodyAccelerometerJerk-std()-Y : num -0.924 -0.981 -0.986 0.067 -0.102 ...
# $ timeBodyAccelerometerJerk-std()-Z : num -0.955 -0.988 -0.992 -0.503 -0.346 ...
# $ timeBodyGyroscope-mean()-X : num -0.0166 -0.0454 -0.024 -0.0418 -0.0351 ...
# $ timeBodyGyroscope-mean()-Y : num -0.0645 -0.0919 -0.0594 -0.0695 -0.0909 ...
# $ timeBodyGyroscope-mean()-Z : num 0.1487 0.0629 0.0748 0.0849 0.0901 ...
# $ timeBodyGyroscope-std()-X : num -0.874 -0.977 -0.987 -0.474 -0.458 ...
# $ timeBodyGyroscope-std()-Y : num -0.9511 -0.9665 -0.9877 -0.0546 -0.1263 ...
# $ timeBodyGyroscope-std()-Z : num -0.908 -0.941 -0.981 -0.344 -0.125 ...
# $ timeBodyGyroscopeJerk-mean()-X : num -0.1073 -0.0937 -0.0996 -0.09 -0.074 ...
# $ timeBodyGyroscopeJerk-mean()-Y : num -0.0415 -0.0402 -0.0441 -0.0398 -0.044 ...
# $ timeBodyGyroscopeJerk-mean()-Z : num -0.0741 -0.0467 -0.049 -0.0461 -0.027 ...
# $ timeBodyGyroscopeJerk-std()-X : num -0.919 -0.992 -0.993 -0.207 -0.487 ...
# $ timeBodyGyroscopeJerk-std()-Y : num -0.968 -0.99 -0.995 -0.304 -0.239 ...
# $ timeBodyGyroscopeJerk-std()-Z : num -0.958 -0.988 -0.992 -0.404 -0.269 ...
# $ timeBodyAccelerometerMagnitude-mean() : num -0.8419 -0.9485 -0.9843 -0.137 0.0272 ...
# $ timeBodyAccelerometerMagnitude-std() : num -0.7951 -0.9271 -0.9819 -0.2197 0.0199 ...
# $ timeGravityAccelerometerMagnitude-mean() : num -0.8419 -0.9485 -0.9843 -0.137 0.0272 ...
# $ timeGravityAccelerometerMagnitude-std() : num -0.7951 -0.9271 -0.9819 -0.2197 0.0199 ...
# $ timeBodyAccelerometerJerkMagnitude-mean() : num -0.9544 -0.9874 -0.9924 -0.1414 -0.0894 ...
# $ timeBodyAccelerometerJerkMagnitude-std() : num -0.9282 -0.9841 -0.9931 -0.0745 -0.0258 ...
# $ timeBodyGyroscopeMagnitude-mean() : num -0.8748 -0.9309 -0.9765 -0.161 -0.0757 ...
# $ timeBodyGyroscopeMagnitude-std() : num -0.819 -0.935 -0.979 -0.187 -0.226 ...
# $ timeBodyGyroscopeJerkMagnitude-mean() : num -0.963 -0.992 -0.995 -0.299 -0.295 ...
# $ timeBodyGyroscopeJerkMagnitude-std() : num -0.936 -0.988 -0.995 -0.325 -0.307 ...
# $ frequencyBodyAccelerometer-mean()-X : num -0.9391 -0.9796 -0.9952 -0.2028 0.0382 ...
# $ frequencyBodyAccelerometer-mean()-Y : num -0.86707 -0.94408 -0.97707 0.08971 0.00155 ...
# $ frequencyBodyAccelerometer-mean()-Z : num -0.883 -0.959 -0.985 -0.332 -0.226 ...
# $ frequencyBodyAccelerometer-std()-X : num -0.9244 -0.9764 -0.996 -0.3191 0.0243 ...
# $ frequencyBodyAccelerometer-std()-Y : num -0.834 -0.917 -0.972 0.056 -0.113 ...
# $ frequencyBodyAccelerometer-std()-Z : num -0.813 -0.934 -0.978 -0.28 -0.298 ...
# $ frequencyBodyAccelerometerJerk-mean()-X : num -0.9571 -0.9866 -0.9946 -0.1705 -0.0277 ...
# $ frequencyBodyAccelerometerJerk-mean()-Y : num -0.9225 -0.9816 -0.9854 -0.0352 -0.1287 ...
# $ frequencyBodyAccelerometerJerk-mean()-Z : num -0.948 -0.986 -0.991 -0.469 -0.288 ...
# $ frequencyBodyAccelerometerJerk-std()-X : num -0.9642 -0.9875 -0.9951 -0.1336 -0.0863 ...
# $ frequencyBodyAccelerometerJerk-std()-Y : num -0.932 -0.983 -0.987 0.107 -0.135 ...
# $ frequencyBodyAccelerometerJerk-std()-Z : num -0.961 -0.988 -0.992 -0.535 -0.402 ...
# $ frequencyBodyGyroscope-mean()-X : num -0.85 -0.976 -0.986 -0.339 -0.352 ...
# $ frequencyBodyGyroscope-mean()-Y : num -0.9522 -0.9758 -0.989 -0.1031 -0.0557 ...
# $ frequencyBodyGyroscope-mean()-Z : num -0.9093 -0.9513 -0.9808 -0.2559 -0.0319 ...
# $ frequencyBodyGyroscope-std()-X : num -0.882 -0.978 -0.987 -0.517 -0.495 ...
# $ frequencyBodyGyroscope-std()-Y : num -0.9512 -0.9623 -0.9871 -0.0335 -0.1814 ...
# $ frequencyBodyGyroscope-std()-Z : num -0.917 -0.944 -0.982 -0.437 -0.238 ...
# $ frequencyBodyAccelerometerMagnitude-mean() : num -0.8618 -0.9478 -0.9854 -0.1286 0.0966 ...
# $ frequencyBodyAccelerometerMagnitude-std() : num -0.798 -0.928 -0.982 -0.398 -0.187 ...
# $ frequencyBodyAccelerometerJerkMagnitude-mean(): num -0.9333 -0.9853 -0.9925 -0.0571 0.0262 ...
# $ frequencyBodyAccelerometerJerkMagnitude-std() : num -0.922 -0.982 -0.993 -0.103 -0.104 ...
# $ frequencyBodyGyroscopeMagnitude-mean() : num -0.862 -0.958 -0.985 -0.199 -0.186 ...
# $ frequencyBodyGyroscopeMagnitude-std() : num -0.824 -0.932 -0.978 -0.321 -0.398 ...
# $ frequencyBodyGyroscopeJerkMagnitude-mean() : num -0.942 -0.99 -0.995 -0.319 -0.282 ...
# $ frequencyBodyGyroscopeJerkMagnitude-std() : num -0.933 -0.987 -0.995 -0.382 -0.392 ...

Références

  • Getting and Cleaning Data Course Project, (2016). Johns Hopkins University (Coursera) – Part of a 10-course series, the Data Science Specialization.
  • Lichman, M. (2013). UCI Machine Learning Repository – http://archive.ics.uci.edu/ml/index.html . Irvine, CA: University of California, School of Information and Computer Science.
  • Inside Activity Tracking, (2013). “Data Science, Wearable Computing and the Battle for the Throne as World’s Top Sports Brand” – http://www.insideactivitytracking.com/data-science-activity-tracking-and-the-battle-for-the-worlds-top-sports-brand/

FrenchEnglishChinese (Simplified)Spanish

ACHETER LE LIVRE
Cart Overview