Example #1
0
def main():
    from data.model.records import KEYS_ALL_HEALTH_RECORDS
    from trainer.dnn_trainer import DNNTrainer
    from auth.fitbit_authenticator import FitbitAuthenticator
    from datetime import timedelta
    from fitbit import Fitbit
    from data.data_loader import DataLoader
    from data.provider.fitbit_data_provider import FitbitDataProvider
    import fitbit as fitbit
    from datetime import date
    import pandas as pd
    import tensorflow as tf
    from data.dataset_generator import DatasetGenerator

    from plotter import plotter

    auth = FitbitAuthenticator("../configs/fitbit_auth_config.json")
    auth.authenticate_in_browser()

    fitbit = fitbit.Fitbit(auth.client_id,
                           auth.client_secret,
                           access_token=auth.access_token,
                           refresh_token=auth.refresh_token,
                           system=Fitbit.METRIC)

    start_date = date(year=2020, month=1, day=1)
    end_date = date.today() - timedelta(days=1)

    data_provider = FitbitDataProvider(fitbit, start_date, end_date)

    loader = DataLoader(data_provider)
    loader.generate_records()

    plotter.plot_all_records(loader.records)

    loader.write_to_csv("../data/raw/health_records.csv")

    pd.set_option('display.max_columns', 15)

    data_frame = pd.read_csv("../data/raw/health_records.csv")
    data_frame = data_frame.fillna(data_frame.mean())
    data_frame = data_frame.drop(columns=['record_date'])

    # Check dataset stats
    print(data_frame.describe().transpose())

    last_record = data_frame.tail(1)
    print('Most recent health record:\n', last_record)

    # Set the modified values for my personal goal
    my_goal_changes = {'weight': 65}

    # Merging the most recent record with the modified values
    my_goal = last_record.copy()
    for key, value in my_goal_changes.items():
        my_goal[key] = value
    print('My goal merged with most recent health record:\n', my_goal)

    record_keys = KEYS_ALL_HEALTH_RECORDS

    # Skip the modified keys, there is no need to predict overwritten records
    for key in my_goal_changes.keys():
        record_keys.remove(key)

    prediction_results = 'Results for my goal {}'.format(my_goal_changes)

    tf.keras.backend.clear_session()
    tf.random.set_seed(60)

    for key in record_keys:
        dataset = DatasetGenerator(data_frame, target_feature=key)
        dataset.split(train_ratio=0.75, valid_ratio=0.15, test_ratio=0.10)

        trainer = DNNTrainer(dataset, key)

        model = trainer.train()

        # Drop the target feature that we are train for
        my_goal_input = my_goal.drop(columns=[key])

        prediction = model.predict(my_goal_input)

        feature_prediction = 'Predicted {} value for my goal: {}'.format(
            key, prediction)
        prediction_results += '\n' + feature_prediction

    print(prediction_results)
class TestDataLoader:
    TEST_CSV_FILE = 'test_health_records.csv'

    @pytest.fixture(autouse=True)
    def setup(self, mocker: MockerFixture):
        data_provider = MockDataProvider()
        mock = mocker.patch.object(data_provider, 'get_heart_records')
        mock.return_value = {
            date(year=2020, month=1, day=1): {
                'resting_heart': 60
            }
        }
        mock = mocker.patch.object(data_provider, 'get_body_records')
        mock.return_value = {
            date(year=2020, month=1, day=1): {
                'weight': 75,
                'fat': 15.12,
                'bmi': 21.12
            },
            date(year=2020, month=1, day=2): {
                'weight': 74,
                'fat': 14.12,
                'bmi': 20.12
            }
        }
        mock = mocker.patch.object(data_provider, 'get_sleep_records')
        mock.return_value = {
            date(year=2020, month=1, day=1): {
                'sleep_duration': 480,
                'sleep_efficiency': 80
            }
        }
        mock = mocker.patch.object(data_provider, 'get_activity_records')
        mock.return_value = {
            date(year=2020, month=1, day=2): {
                'total_calories': 1600,
                'active_calories': 400,
                'sedentary_minutes': 600,
                'lightly_active_minutes': 10,
                'fairly_active_minutes': 10,
                'highly_active_minutes': 10
            }
        }

        self.data_loader = DataLoader(data_provider)

        yield self.data_loader

        if os.path.exists(self.TEST_CSV_FILE):
            os.remove(self.TEST_CSV_FILE)

    def test_generate_records(self):
        self.data_loader.generate_records()

        assert self.data_loader.records == {
            date(year=2020, month=1, day=1): {
                'resting_heart': 60,
                'weight': 75,
                'fat': 15.12,
                'bmi': 21.12,
                'sleep_duration': 480,
                'sleep_efficiency': 80,
                'total_calories': None,
                'active_calories': None,
                'sedentary_minutes': None,
                'lightly_active_minutes': None,
                'fairly_active_minutes': None,
                'highly_active_minutes': None
            },
            date(year=2020, month=1, day=2): {
                'resting_heart': None,
                'weight': 74,
                'fat': 14.12,
                'bmi': 20.12,
                'sleep_duration': None,
                'sleep_efficiency': None,
                'total_calories': 1600,
                'active_calories': 400,
                'sedentary_minutes': 600,
                'lightly_active_minutes': 10,
                'fairly_active_minutes': 10,
                'highly_active_minutes': 10
            }
        }

    def test_write_to_csv(self):
        self.data_loader.generate_records()
        self.data_loader.write_to_csv("test_health_records.csv")

        with open(self.TEST_CSV_FILE, newline='') as csv_file:
            reader = csv.reader(csv_file)
            row_first = next(reader)
            assert row_first == [
                'record_date', 'resting_heart', 'weight', 'fat', 'bmi',
                'sleep_duration', 'sleep_efficiency', 'total_calories',
                'active_calories', 'sedentary_minutes',
                'lightly_active_minutes', 'fairly_active_minutes',
                'highly_active_minutes'
            ]

            row_second = next(reader)
            assert row_second == [
                '2020-01-01', '60', '75', '15.12', '21.12', '480', '80', '',
                '', '', '', '', ''
            ]

            row_third = next(reader)
            assert row_third == [
                '2020-01-02', '', '74', '14.12', '20.12', '', '', '1600',
                '400', '600', '10', '10', '10'
            ]