diff --git a/Jawbone/features.csv b/Jawbone/features.csv new file mode 100644 index 0000000..7adb374 --- /dev/null +++ b/Jawbone/features.csv @@ -0,0 +1,81 @@ +Field,Definition +DATE,Date of column data (in year/month/day format). +age,Your age on the indicated date. +avg_bg,Average passive heart rate (in beats per minute). +bmr,Basal Metabolic Rate (in calories). +body_fat,Body fat percentage. +e_caffeine,Caffeine content consumed (in milligrams). +e_calcium,Calcium content consumed (in milligrams). +e_calories,Calories consumed. +e_carbs,Carbohydrates consumed (in grams). +e_cholesterol,Cholesterol consumed (in milligrams). +e_count,Number of meals logged. +e_fat,Fat consumed (in grams). +e_fiber,Fiber consumed (in grams). +e_iron,Percentage of recommended iron consumed (based on a 2000 calorie per day diet). +e_monounsaturated_fat,Monounsaturated fat consumed (in grams). +e_num_drinks,Number of drinks logged. +e_num_foods,Number of meal items logged. +e_num_mealitems_green,Number of meal items logged with a green UP Food Score. +e_num_mealitems_red,Number of meal items logged with a red UP Food Score. +e_num_mealitems_with_score,Number of meal items logged with an UP Food Score. +e_num_mealitems_yellow,Number of meal items logged with a yellow UP Food Score. +e_num_water,Glasses of water logged. +e_polyunsaturated_fat,Polyunsaturated fat consumed (in grams). +e_potassium,Potassium consumed (in milligrams). +e_protein,Protein consumed (in grams). +e_sat_fat,Saturated fat consumed (in grams). +e_sodium,Sodium consumed (in milligrams). +e_sugar,Sugar consumed (in grams). +e_trans_fat,Trans fat consumed (in grams). +e_unsat_fat,Unsaturated fat consumed (in grams). +e_vitamin_a,Percentage of recommended Vitamin A consumed (based on a 2000 calorie per day diet). +e_vitamin_c,Percentage of recommended Vitamin C consumed (based on a 2000 calorie per day diet). +gender,Your specified gender (0=male 1=female). +goal_body_weight,Weight goal (in kilograms). +goal_body_weight_intent,Weight goal preference (0=lose 1=maintain 2=gain). +height,Your specified height (in meters). +m_active_time,Amount of total active time (in seconds). +m_calories,Total number of calories burned during active time (in seconds). +m_distance,Total distance traveled (in meters). +m_inactive_time,Total inactive time (in seconds). +m_lcat,Longest consecutive active time (in seconds). +m_lcit,Longest consecutive inactive time (in seconds). +m_steps,Total number of steps taken. +m_steps_3am,Total number of steps taken (before 3am). +m_total_calories,Total number of calories burned in the day +m_workout_count,Number of workouts logged. +m_workout_time,Length of logged workouts (in seconds). +max_bg,Highest passive heart rate (in beats per minute). +min_bg,Lowest passive heart rate (in beats per minute). +n_asleep_time,Duration of naps/secondary sleep (in seconds). +n_awake,Total time awake during naps/secondary sleep (in seconds). +n_awake_time,Total time awake after waking from naps/secondary sleep (in seconds). +n_awakenings,Number of times awoken during naps/secondary sleep. +n_bedtime,Length of time band in sleep mode during naps/secondary sleep (in seconds). +n_clinical_deep,Length of Deep sleep during naps/secondary sleep (in seconds UP3 and UP4 only). +n_count,Number of naps/secondary sleep entries logged. +n_deep,Length of Sound sleep during naps/secondary sleep (in seconds). +n_duration,Duration of naps/secondary sleep (in seconds). +n_light,Length of Light sleep during naps/secondary sleep (in seconds). +n_quality,Not applicable. +n_rem,Length of REM sleep during naps/secondary sleep (in seconds). +n_to_bed_phr,Average passive heart rate 1 hour before naps/secondary sleep (in beats per minute). +num_readings,Number of background heart rate readings. +o_count,Number of moods logged. +o_mood,Average score for moods logged (10 = lowest 80 = highest). +rhr,Resting heart rate (in beats per minute). +s_asleep_time,Duration of primary sleep (in seconds). +s_awake,Total time awake during primary sleep (in seconds). +s_awake_time,Total time awake after waking from primary sleep (in seconds). +s_awakenings,Number of times awoken during primary sleep. +s_bedtime,Length of time band was in primary sleep mode (in seconds). +s_clinical_deep,Length of primary Deep sleep (in seconds UP3 and UP4 only). +s_count,Number of primary sleep entries logged. +s_deep,Length of primary Sound sleep (in seconds). +s_duration,Duration of primary sleep (in seconds). +s_light,Length of primary Light sleep (in seconds). +s_quality,Not applicable. +s_rem,Length of primary REM sleep (in seconds). +s_to_bed_phr,Average passive heart rate 1 hour before primary sleep (in beats per minute). +weight,Weight (in kilograms). diff --git a/TODO.org b/TODO.org new file mode 100644 index 0000000..d2c848d --- /dev/null +++ b/TODO.org @@ -0,0 +1,6 @@ +https://github.com/crowoy/Health-Analysis +https://github.com/joytafty-work/SleepModel +https://github.com/carleshf/jawboneup2tex +https://github.com/search?l=Jupyter+Notebook&q=s_awakenings&type=Code&utf8=%E2%9C%93 +https://github.com/oshev/colifer/blob/592cc6b4d1ac9005c52fccdfb4e207513812baaa/colifer.py +https://github.com/oshev/colifer/blob/592cc6b4d1ac9005c52fccdfb4e207513812baaa/reportextenders/jawbone/jawbone_sleep.py diff --git a/main.py b/main.py new file mode 100755 index 0000000..8106bd4 --- /dev/null +++ b/main.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python3.6 +# TODO +from csv import DictReader +from itertools import islice + +from typing import Dict + +# sleep = [] +# with open('2017.csv', 'r') as fo: +# reader = DictReader(fo) +# for line in islice(reader, 0, 10): +# sleep +# print(line) + +import numpy as np +import matplotlib.pyplot as plt +from numpy import genfromtxt +import matplotlib.pylab as pylab + +pylab.rcParams['figure.figsize'] = (32.0, 24.0) +pylab.rcParams['font.size'] = 10 + + + +dimensions = 3 # Number of dimensions to reduce to +jawboneDataFile = "/L/Dropbox/backups/jawbone/2017.csv" # Data File Path + +jawboneDataFeatures = "Jawbone/features.csv" # Data File Path +featureDesc: Dict[str, str] = {} +for x in genfromtxt(jawboneDataFeatures, dtype='unicode', delimiter=','): + featureDesc[x[0]] = x[1] + +def filterData_Jawbone (data): + #Removes null data (and corresponding features) + data = data[0:,:] + # for i in range(16): + # data = np.delete(data, 0, 1) + # print(data) + h, w = data.shape + data = np.where((data == ''), 0, data) + allZero = [np.all(np.delete([0 if col[i] == '' else col[i] for col in data], [0]).astype(float) + == 0) for i in range(w)] + allSame = [np.all(np.delete([0 if col[i] == '' else col[i] for col in data], [0]).astype(float) + == np.delete([0 if col[i] == '' else col[i] for col in data], [0]).astype(float)[0]) for i in range(w)] + empty = np.logical_or(allZero, allSame) + n = [i for i in range(np.array(empty).size) if empty[i] == True] + return np.delete(data, n, axis=1) + +dataAll = filterData_Jawbone(genfromtxt(jawboneDataFile, dtype='unicode', delimiter=',')) +features = dataAll[0] +features = [ + 's_light', # 'light sleep' from app + 's_awake', # 'woke up' from app (how many times you were awake) + 's_deep' # 'sound sleep' from app +] +# TODO filter more carefully... + + +def getIndex (data, features): + index = [] + for f in features: + index.append(np.where((data[0] == f) == True)[0][0]) + return index + +def getFeatures (data, features): + h, w = data.shape + index = getIndex(data, features) + extracted = np.zeros(h-1) + for i in index: + temp = np.delete([0 if col[i] == '' else col[i] for col in data], [0]).astype(float) + temp /= np.amax(temp) + extracted = np.vstack((extracted, temp)) + extracted = np.delete(extracted, 0, 0) + return extracted + + +# print(dataAll) +data = getFeatures(dataAll, features) + + +def remNull(x, y): + nx = np.where(x == 0) + ny = np.where(y == 0) + nulli = np.concatenate((nx[0], ny[0])) + x = np.delete(x, nulli, 0) + y = np.delete(y, nulli, 0) + return x, y + +def calculateVar(x, y) -> float: + x, y = remNull(x,y) + if len(x) == 0: + # TODO needs date? + print("Warning") + return 0.0 # TODO ??? + meanX = np.mean(x) + meanY = np.mean(y) + n = float(x.shape[0]) + print(n) + return ((1/n)*(np.sum((x-meanX)*(y-meanY)))) + # return ((1/(n + 1))*(np.sum((x-meanX)*(y-meanY)))) # TODO fixme.. + +def calculateCov(data): + h, w = data.shape + cov = np.zeros([h, h]) + + for i in range(h): + for j in range(h): + cov[i][j] = calculateVar(data[i], data[j]) + return cov + + +# In[119]: +# a = np.array([[1, 2, 3], [1, 2, 3]]) +# print(a) +# print(calculateCov(a)) +# print(np.cov(a)) +# print("VAR") +# print(np.var(a[0])) + +# print("DATA") +# print(data) + +# print("NPCOV") +# print(np.cov(data)) + +# cov = calculateCov (data) +# print("COV") +# print(cov) +cov = np.cov(data) # TODO ??? + + +# In[120]: + + +def plotFeatures (title, label1, label2, feature1, feature2): + plt.scatter(feature1, feature2) + + plt.title(title) + plt.xlabel(label1) + plt.ylabel(label2) + + plt.xlim(0, 1) + plt.ylim(0, 1) + + plt.show() + +def plotMatrix(data): + r, c = data.shape + c=2 + fig = plt.figure() + plotID = 1 + for i in range(c): + for j in range(c): + f1 = getFeature(data, data[0][i]) + f2 = getFeature(data, data[0][j]) + ax = fig.add_subplot( c, c, plotID ) + ax.scatter(f1, f2) + ax.set_title(data[0][i] + ' vs ' + data[0][j]) + ax.axis('off') + plotID += 1 + plt.show() + +def plotMatrix1(features, data): + for f in features: + print(f"{f}: {featureDesc[f]}") + r, c = data.shape + fig = plt.figure() + plotID = 1 + for i in range(r): + for j in range(r): + ax = fig.add_subplot( r, r, plotID ) + x,y = remNull(data[i], data[j]) + ax.scatter(x, y, s=2) + ax.set_title(features[i] + ' vs ' + features[j], fontsize=15) + ax.tick_params(axis='x', which='major', labelsize=8) + ax.tick_params(axis='y', which='major', labelsize=8) +# ax.set_xlim(0,1) +# ax.set_ylim(0,1) + plotID += 1 + plt.show() + + +# In[121]: + + +# plotMatrix1(features, data) + + +# In[ ]: + + +def rankF(features, cov): + n = len(features) + eigenV = np.linalg.eig(cov) + eigVal = np.matrix(eigenV[0]) + eigVec = np.matrix(eigenV[1]) + order = (n-1) - np.argsort(eigVal) + + rankFeatures = np.empty(n, dtype='