ちょっと前からFitbit Sense2を使い始めたので, これをつかって睡眠改善をしたいなとかんがえ始めました. ちょっとFitbit APIリハビリも兼ねて数年前の自分の記事を参考に睡眠記録を取得してみようと思います.

Fitbit APIとPythonで心拍数の取得をする | Futurismo

今回の新しい試みとしては, ChatGPTでどこまで自分でコードを書かないでできるかを検証したいw そのために, 2週間前に登場したCode Interpreterをつかってみます.

Python APIで本日の睡眠ログを取得

とりあえずChatGPTでPythonコード生成. そのままだとrequestsライブラリを使おうとするので, fitbit APIのPython Wrapperである python-fitbitを指定.

#!/usr/bin/env python3

import fitbit
import datetime
from oauthlib.oauth2 import LegacyApplicationClient
from requests_oauthlib import OAuth2Session

# アプリケーションの設定
client_id = ''
client_secret = ''
user_id = ''

# ユーザーの設定
access_token = ''
refresh_token = ''

# OAuth2セッションを作成
auth = OAuth2Session(client_id, token={
    'access_token': access_token,
    'refresh_token': refresh_token,
    'token_type': 'Bearer',
    'expires_in': '-30',
    'expires_at': '-30'
}, client=LegacyApplicationClient(client_id))

# Fitbitクライアントを作成
client = fitbit.Fitbit(client_id,
                       client_secret,
                       oauth2=True,
                       access_token=access_token,
                       refresh_token=refresh_token,
                       system='en_GB')

# 睡眠データを取得
start_date = datetime.date(2023, 7, 30)
end_date = start_date + datetime.timedelta(days=7)
sleep = client.get_sleep(date=start_date)

# 睡眠データを表示
print(sleep)

この生成されたコードに API情報をいれると取得ができる. トークン取得のためのOAuth認証は自前でやるよりもFitbitのdevサイトからの このページ を使うのが便利.

やるじゃないか, ChatGPTとわたしの過去記事. とりあえずデータは取得できたがこれだと私がなにもやらないのでもう少し頑張る.

2週間分の睡眠記録をmatplotlibで可視化する

今度は2週間分のデータを取得してラインチャートを表示.

ありがとうございます。次に2週間分の睡眠記録を取得して可視化したいです。

import matplotlib.pyplot as plt

# 睡眠データを取得
start_date = datetime.date(2023, 7, 14)
end_date = start_date + datetime.timedelta(days=14)

dates = []
total_sleep_times = []

for day in (start_date + datetime.timedelta(n) for n in range((end_date-start_date).days)):
    sleep = client.get_sleep(date=day)
    dates.append(day)
    total_sleep_time = sum([sl['duration'] for sl in sleep['sleep']]) / 3600000  # ms to hours
    total_sleep_times.append(total_sleep_time)

# 睡眠データを可視化
plt.figure(figsize=(10, 5))
plt.plot(dates, total_sleep_times)
plt.xlabel('Date')
plt.ylabel('Total Sleep Time (hours)')
plt.title('Sleep Time over Two Weeks')
plt.show()

Code Interpreterでデータ分析してみる

自分で分析をするのがめんどくさいのでCode interpreterをつかってみる. 現状, APIを叩いた結果をそのまま分析することはできないらしい(外部アクセスができない).

そのため, Fitbitから直接dataをダウンロードしてきたものを利用する. なお2023/07年現在, Google傘下FitbitはGoogleの管理画面からデータをエクスポートできるようだ. 1

過去の全てのデータは Global Export Data というところにjson形式で格納されていた. すごい2015くらいのデータから全てある…

これはFitbitの睡眠データが含まれたjsonファイルです. 解析できますか?

おまかせで睡眠分析してグラフ化してくれますか?

睡眠時間を日にちごとにバーチャートで表示してください。

レム睡眠、浅い睡眠、深い睡眠の割合も考慮しててグラフを改善してください。

これはすごい… さらにCode Interpreter がこのグラフをどうやって出力したかもプルダウン操作でコードが表示されるので, それをJupyter Notebookに貼り付けるとその解析を再現できる.

import json

file_path = "/home/tsu-nera/Downloads/Takeout/Fitbit/Global Export Data/sleep-2023-07-15.json"

# Load the json file
with open(file_path) as file:
    data = json.load(file)

# Create a DataFrame for the sleep duration
duration_df = pd.DataFrame({'dateOfSleep': [record['dateOfSleep'] for record in data],
                            'minutesAsleep': [record['minutesAsleep'] for record in data]})

# Convert string date to datetime
duration_df['dateOfSleep'] = pd.to_datetime(duration_df['dateOfSleep'])

# Sort by date
duration_df = duration_df.sort_values('dateOfSleep')


# Add columns for each sleep stage duration
duration_df['deep'] = [record['levels']['summary']['deep']['minutes'] for record in data]
duration_df['wake'] = [record['levels']['summary']['wake']['minutes'] for record in data]
duration_df['light'] = [record['levels']['summary']['light']['minutes'] for record in data]
duration_df['rem'] = [record['levels']['summary']['rem']['minutes'] for record in data]

# Plot sleep duration by date with sleep stage proportions
plt.figure(figsize=(10, 6))
plt.bar(duration_df['dateOfSleep'], duration_df['deep'], label='Deep', color='#5A9')
plt.bar(duration_df['dateOfSleep'], duration_df['wake'], bottom=duration_df['deep'], label='Wake', color='#933')
plt.bar(duration_df['dateOfSleep'], duration_df['light'], bottom=duration_df['deep'] + duration_df['wake'], label='Light', color='#A77')
plt.bar(duration_df['dateOfSleep'], duration_df['rem'], bottom=duration_df['deep'] + duration_df['wake'] + duration_df['light'], label='REM', color='#39F')
plt.title('Sleep Duration by Date with Sleep Stages')
plt.xlabel('Date')
plt.ylabel('Sleep Duration (minutes)')
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))  # format x-axis label to year-month-day
plt.gca().xaxis.set_major_locator(mdates.DayLocator())
plt.gcf().autofmt_xdate()  # rotate x-axis labels
plt.legend(loc='upper left')
plt.show()

クリティカルにCode Interpreterでのデータ分析を批判してみる

ここまでCode Interpreterに圧倒されてしまった. いやすごいな. データサイエンス革命. わたしのようなそこまでEDAに精通してないながなんとなくできる人もデータ分析ができるようになってしまった.

高度なデータ分析のハードルがパートのおばちゃんでも事務作業でExcelを使いこなす程度まで下がった印象. もちろんExcelを勉強しないと仕えないようにITパスポート並には慣れる必要もある. 3年後にはChatGPT検定という資格が生まれて, その資格があればパート事務作業で有利!とか.

と, ここで驚いていてばかりいてばかりだとよくないのであえて反対方向に批判してみたい.

なにが目的なのかを見失ったデータ分析は無意味

そもそもわたしはなんのためにFitbit睡眠データを分析しているのか? それは最近のグダグダな睡眠を改善したいからだ. 睡眠が安定すれば, それがそのままメンタルの安定にも強く貢献すると考えた. そしてそもそも睡眠改善はメンタル改善の打ち手の手段としてだった.

手作業で十分ならば自動化の罠に気をつける

この1ヶ月は 手作業で毎日GoogleスプレッドシートにFitbitアプリの情報を転機して, それをGoogle Looker Studioで可視化していた. それでだいたいいいのだが, それにしても毎日数分の手入力が面倒なので, というモチベからだった. 2

睡眠改善をしようとしたとき, 追いかけるべき指標はなにかを見極めて, 数個に絞り込み, その数値の改善のみに力を注ぐ. その数値は手作業で毎日にメモ帳に記録してもいい. ポイントは手作業でもいいということだ.

自己改善で必要なライフログデータは1ヶ月もあればいい

なにを改善するかにもよるが, 改善目標に対するデータは過去1ヶ月程度でいい.

Google Fitbit からデータをエクスポートしたとき, 2015年くらいからの睡眠記録や歩数記録があったが, 役に立たないだろう. なんか古い写真が発掘されたような一発屋の懐かしさはあった. できればアプリのスクショが残っていたほうがいい. しかし逆にいえば 2015年からデータが残っていたことに驚いたし, FitbitがGoogle傘下になったことで, データの保存という点でより安心感を得た.

この直近1ヶ月という意味だと, ここには不便を感じる. エクスポートは一括エクスポートなので, 個別のデータが取り出せない. これをやるならばAPIを叩いて範囲をしていしないといけない. さらに欲をいえば, 毎日1回の定期取得がしたい. この1ヶ月の手入力はまあこれでもいいものの, やっぱり面倒だった.

ここの部分をGASで改善することはコスパがいいかもしれない.

ライフログのPersonal ScienceやQuantified Self領域に興味がある

ライフログという響きには昔から魅了されてきた. このブログFuturismoもそれをテーマにした記事もたびたびある. ライフログ x ITというテーマがそそる.

データサイエンスに興味がでてRをいじりはじめたのもそんなモチベだった. 3 Code Interpreterによってデータ分析のしきいはとても下がった. しかし目的なのはなんのためにデータを分析するかだ.

わたしは睡眠改善をしたいし, その延長にはメンタル改善, そしてその先には科学的方法論を用いたPersonal ScienceやQuantified Self4の領域がある. このあたりは海外のムーブメントなので日本の流行は鎮火した感がある. しかし, わたしの興味関心の領域, ライフハックやライフログの目指す方向性はここだ. Code Interpreterでより励まされた. これからもこのテーマに取り組んでいきたい.


  1. https://takeout.google.com/settings/takeout/custom/fitbit. 2023/05くらいまではFitbitのWebUIからしかダウンロードできながったが, 不具合なのか期間の指定によってハングしてダウンロードできなくてけっこうキレていた. バグ放置はもうGoogle UI使うからだったのか. 現状のFitbit ダッシュボードもところどころ古さを感じて心配になってしまうがこれももうすぐGoogle共通のものとして刷新される予感がする. なんならAPI endpointsすら変わるんじゃないかな? ↩︎

  2. ここだけの話ChatGPTはPythonはうまくいったがGASは動かなかった… ↩︎

  3. 2015年の記事. org-table の表で記録した睡眠時間を R で折れ線グラフにして表示する方法 | Futurismo ↩︎

  4. Homepage - Quantified Self, ライフログムーブメントやQuantified Selfは10年前のブームから落ち着いてしまったが, Gary Wolfさんを中心に継続してムーブメントは続いている. このあたりの情報をおっかけていきたい. ↩︎