楽しみながら健康チャレンジ!データと健康のつながりを体感する社内イベント「ウェルリンピック」とは

今回は、テックドクターで開催した社内イベント「ウェルリンピック」(Well-lympics)をご紹介します。

ウェルリンピックは、参加者が種目ごとに分かれて競い合ったり協力したりしながら、生活改善をするイベントです。

参加メンバーは「睡眠」「リラックス」「消費カロリー」の3つの種目からひとつを選び、それぞれスマートウォッチのFitbitを着用してウェアラブルデータ(※)を記録。競技ごとの基準に沿ってデータの分析を行いながら、開催期間の2週間の間に生活改善ナンバーワンを目指します。

ウェアラブルデータ……スマートウォッチを代表とするウェアラブル端末で測定された生体情報等のデータ

開催の目的

スライド資料
使用したスライド資料より

ウェルリンピックの目的はいくつかありますが、ここでは2つを紹介します。ひとつは社員が楽しみながら健康を推進すること。もうひとつは、私たちデータサイエンスチームの、健康に関するデータを扱う仕事に関するものです。

私たちは、日々ウェアラブルバイスから得られるデータを分析しています。そこで心がけているのが、「目の前の数値がすべてだと考えないこと」です。数字の向こうには身体の変化・身体の状態があるからです。

日中の歩数が減少したり、横になっている時間が増えたりする背景には、疾患や体調不良が存在します。数字の変化を通して患者様の状態を想像することこそが、分析の出発点になると私たちは考えています。

そう考えたとき、最も身近で理解しやすいデータは何でしょうか。それは、自分自身の身体から得られる情報です。

そこで弊社では、自分自身や身近な人の状態とデータを結びつけて考える習慣をつける目的で、社内イベント「ウェルリンピック」を開催しました。

取り組み紹介

今回のウェルリンピックでは、「睡眠」「リラックス」「消費カロリー」の3つの種目を実施しました。

スライド資料
使用したスライド資料より

ここからは種目ごとに、どんな取り組みをしたかを紹介していきます。

「睡眠」:改善のトップを狙おう!

睡眠種目では、「睡眠の質」改善を競い合いました。

レギュレーション

厚生労働省が作成した「成人のためのGood Sleepガイド」によれば、良い睡眠には「量(時間)」と「質(休養感)」が重要とされています。今回は生活リズムを大きく変える「量」ではなく、「質」に重点を置きました。

評価基準として、睡眠効率(ベッドにいる時間の何%の間、睡眠できているか)を採用しました。自分の2週間前の平均睡眠効率を基準として、期間中毎日の改善ポイント(%)の累積が得点になります。

上位3名には睡眠にまつわるプレゼントを用意し、楽しみながら取り組める仕組みを整えました。

期間中の過ごし方

メンバーそれぞれ工夫を凝らし、就寝前のスマートフォン使用を控えたり、ヨガや瞑想を取り入れたりと、生活に取り入れやすい改善活動を行いました。

毎日、各自の睡眠効率を共有し、睡眠の質に影響を与える要因を考察。それを互いに共有することで、自分の行動を振り返る機会としました。

さらに、改善累積ポイントのランキングも公開。楽しみながら競争心も刺激し、参加者全員が意欲的に取り組める環境を整えました。

結果

最もうまくいったメンバーでは、11日間で累積27.2ポイントの改善が見られました!

特に効果が実感された取り組みとしては、

  • 就寝前のTVドラマ視聴を控えること
  • 熱帯夜対策(室温調整など)

が挙げられます。

就寝前の行動が目を冴えさせ、入眠を遅らせ、睡眠効率を低下させることが考えられ、こうした行動を控えることが効果的である示唆が得られました。また、夏の開催という背景もあり、室温対策や寝室環境の整備が夜中の中途覚醒を減らす効果に寄与した可能性があります。

一方で、ライフイベントや騒音といった自身ではコントロールできない外的要因により、改善が難しかったメンバーもいました。
しかし、全員が睡眠の質向上に前向きに取り組み、改善意識を高められたことは、本イベントの成果と言えます。

グラフ
栄えある金メダリスト、累積改善ポイントが最も高かったメンバーのデータ。「就寝直前のネットフリックスを止めるのが効果的だった」とのことです
ホワイトノイズマシン
一位のメンバーには商品として安眠グッズ(ホワイトノイズマシン)が贈呈されました。(写真はAmazon商品ページより)

「リラックス」:リラックス度の自己ベストに挑む

リラックス種目は、リラックス度の自己ベストを更新することが目標です。
各社員が自分がリラックスできる活動(リラックス施策)を考え、生活に取り入れました。

レギュレーション

リラックス施策は毎日おなじ時間帯・所要時間で続けられる15分程度の内容で、途中で変更することも可能とし、リラックスの対象時間帯は6:00から23:45の間で行いました。

評価方法は、毎日の時間ごとのストレス度の変化を計算し、ストレス度が減少するほどリラックスできたと評価しました。
運動中のデータはストレス度の測定に影響するため除外し、対象時間帯のうち安静時心拍数の範囲内のデータを選択しました。
また、各参加者の過去のデータと照らし合わせて正規化処理をすることで個人ごとのばらつきを抑え、ストレス度の変化をわかりやすくしました。

期間中の過ごし方

毎日、前日分のストレス度の推移のグラフを作成しました。
下の図のように最もストレスが高かった時間帯3つ(Top3)と、ストレスが低かった時間帯3つ(Low3)を示すことで、各社員にどのような行動がストレス値の高低に繋がっていたかメモしてもらいます。

効果のあるリラックス施策は続け、効果がなさそうな場合は変えるなど、ベストなリラックス施策を模索してもらいました。

グラフ
ストレス度の推移グラフの例
結果

リラックス施策を行うことでストレス度が下がり効果を実感できた社員と、そうでない社員がいました。

ストレス度が下がった施策の例としては、

  • 好きな飲み物を飲みながらドラマを見る
  • 静かに音楽を聞く
  • 瞑想

などがあり、これらの施策はリラックスに効果的なのではないかと考えられました。

また、リラックス施策を行った時間以外でストレス値が下がっていた例として、

  • 自宅やオフィスに着く
  • 会議が終わる
  • 仕事が終わる
  • 家族のお手製のパンを食べる

などがありました。

逆に今回あまり効果的でなかったリラックス施策としては、

  • 音楽を聴く
  • 読書

などがありました。

データを可視化することで、普段自分が意識していない「リラックスしている瞬間」を実感することができました。

バスボム
リラックスアイテムの1つとしてみんなで購入したバスボム

「消費カロリー」: メンバー全体で目標達成へ

消費カロリー種目は、参加者全員が一つのチームになる協力種目です。「消費カロリー合計で目標をクリアする」ことが目標です。

レギュレーション

参加者は自分が継続可能な運動を選び、2週間にわたり実践。国が推奨する1日の運動量である300kcal(1日1万歩相当)の消費を、ひとりあたりの1日の目標に設定しました。

全体としては、参加者10人が11日間(検証期間)取り組み、合計33000kcalを消費するのが目標です。

※Fitbitから得られるデータは1日の合計消費カロリーのため、取り組みを始める前に、参加者それぞれに身長・体重・年齢から基礎代謝を算出してもらいました。1日の合計消費カロリーからその基礎代謝を差し引いたものを運動による消費カロリーとして定義しました。

期間中の過ごし方

ウォーキングやジョギングをはじめ、ジムでの筋トレなど、楽しみながら継続できる運動が多く取り入れられました。
また参加者同士で進捗を共有し励まし合うことで、自然とチームの団結力が高まりました。

2日に1回ほど、参加者ごとの消費カロリーを共有し、「〇〇さんの消費カロリーが高いけどどんな運動をしているのか?」などと他メンバーの運動内容を参考にしたり、「この日は天気が良かったからたくさん歩いた」「調子が悪かったから無理せず休んだ」といった進捗の振り返りも行いました。

スマホのヘルストラッカーの画面キャプチャ
自分の運動状況を送り合うなど楽しく進めました
結果

合計33000kcalの消費を目指しましたが、最終的には目標を大きく上回り、90000kcal近い消費カロリーを記録しました!

期間の後半には全体的に消費カロリーが減少傾向になりましたが、最終日には参加者全員が盛り返し、最終的にどのメンバーも1日平均300kcalを上回る消費を達成。

定期的なフィードバックとチームメンバー同士の励まし合いが功を奏し、期間中には「これまでより運動量が増えた」「日常的に身体を動かす習慣がついた」との声が挙がりました。

チーム全体で協力しての取り組みが、モチベーション向上や健康習慣の定着に大きく貢献したのではないかと思います。

消費カロリーが多かったメンバーにはジムに行っている人が多く、活動内容としては筋トレや有酸素運動で高い心拍数の状態をキープするのが良さそうという意見が出ました。

グラフ
日ごとの累計運動消費カロリーの推移(赤が目標、青が測定値)
グラフ
メンバーごとの日ごとの運動消費カロリー

※消費カロリーはFitbitの合計消費カロリーから基礎代謝を差し引くことで算出しましたが、Fitbitの詳細な仕様が不明なため、実際の消費カロリーより多めの値が出ているかもしれません。もしかしたら、平均心拍数が高めの参加者では、消費カロリーが高めに算出される可能性も考えられます。

得られた気づきと次へのステップ

今回の「ウェルリンピック」を通じて、社員の健康意識とデータへの理解が一層深まる結果となりました。

参加者からはこんな声がありました。

  • ウェアラブルデータの記録の重要性があらためてわかった。
  • データをちゃんと見て、改善する動きが取れて良かった。
  • 自分のデータをよく見たことで、データと体調の関係をもっと知りたくなった
  • 健康について他の社員と話し、コミュニケーションを取る機会が増えた。

総じて、データを通じて自身の体調や生活習慣を振り返る良いきっかけとなったようです。また、「健康とデータの橋渡し」というイベントの目的も少なからず達成できたと感じます。

ウェルリンピックは継続的に開催していきたいと思います。

今後は、現在の年1回から数ヶ月に1回など開催頻度を増やして継続的な健康促進を目指したり、期間も今回の2週間よりも長くする、また他の種目に参加中のメンバーとの交流を増やしたりすることで、より多くの学びや発見が期待できそうです。
さらに深いインサイトを得られるよう、一層工夫を凝らしていきたいと思います。

まとめ

データ分析を通してデータと健康を結びつける試みとして、社員一人ひとりの意識醸成とスキル向上につながった今回のウェルリンピック。あらためて「データは体調のサインを示す」ということを、私たちに実感させてくれました。

データが示す「体調のサイン」とその背景を一つ一つ解き明かすことは、体調不良や疾患への理解を深め、新たなdBM(デジタルバイオマーカー)の開発につながります。

※デジタルバイオマーカー……デジタルデバイスで測定した『日常データ』をもとにした、病気の早期発見や治療につながる客観的指標

そして何より、悩みを抱える多くの方々の助けになることを願い、私たちは日々研究・開発に取り組んでいます。
ウェルリンピックは、そんな私たちにとって健康データ分析の視野を広げる第一歩となったのではないかと思います。

似顔絵
書いた人:瀬川

PyCon JP 2024参加レポート&良かったセッション紹介

はじめまして、バックエンドエンジニアの伊藤です。

9月に開催されたPython のカンファレンスイベント「PyCon」に、テックドクターのバックエンドエンジニア3人で参加してきました。

今回はその体験記として、イベントの様子や気になった発表などをレポートします。

PyConとは

PyConについて、公式サイトではこのように説明されています。

PyCon JP は、Python ユーザが集まり、PythonPython を使ったソフトウェアについて情報交換、交流をするためのカンファレンスです。 PyCon JP の開催を通じて、Python の使い手が一堂に集まり、Python にまつわる様々な分野の知識や情報を交換し、新たな友達やコミュニティとのつながり、仕事やビジネスチャンスを増やせる場所とすることが目標です。

PyCon JP 2024 より引用

ひとことで言えば、Pythonにまつわる情報を共有することがメインのイベントです。具体的には大きく2つの要素で構成されます。セッションとスポンサーブースです。

セッション

Pythonユーザーによるスライド発表です。Pythonにまつわるノウハウや活用事例、課題解決や関連ツールの紹介など、多岐にわたる発表があります。

1つのセッションは時間にして30分ほど。登壇者はセッションは4つの会場で並行して行われるため、効率的に情報収集するためには事前にタイムテーブルを見ておき、会場を移動しながら興味のある発表を聞くのがおすすめです。発表資料の一部がこちらに掲載されていますので、今回参加できなかった方もどんな内容か知ることができます。

スポンサーブース

スポンサーブースは、PyConに出資したスポンサー企業が自分たちの魅力を紹介するためのブースです。こちらはセッションとは違い常設ブースとなっており、PyCon参加者は誰でも立ち入ることができます。ノベルティを配っている企業も多く、お祭りの屋台のような形で楽しめました。

ブースの写真
Forkwellさんの「恐怖の鳥釣り」ブース。Pythonにちなんで、ヘビの釣り竿でアヒルちゃんを釣るというゲームをやっていました。
ブースの写真
KRAKENさんのブース。アンケート回答でかわいいクラーケンの指人形がもらえました。
ブースの写真
GlobalWayさんのブース。トートバッグ等を配布されていました。
ブースの写真
Findyさんのブース。モバイルバッテリーやお守りが当たるガチャくじを実施されていました。
ノベルティの写真
たくさんのノベルティをいただきました!

PyConに参加した目的

今回は個人的な参加ではなく、テックドクターの社員として、2つの目的でPyConに参加しました。

ひとつはほかの参加者の皆さんと同じく、Pythonについての理解を深めることです。

もうひとつは、スポンサー協賛の検討です。テックドクターでは日頃からお世話になっているPythonのコミュニティ発展に貢献するため、PyConへのスポンサー協賛を検討しています。PyCon自体の雰囲気を知ることと、スポンサーになるとどのようなことが行えるのかなど検討材料の収集を行いました。

良かったセッション

テックドクターからは私(伊藤)以外に、星野、魚木が参加しました。二人とも私と同じバックエンドエンジニアですが、それぞれPythonの経験年数は違います。またPyConは3人とも初参加でした。ここでは今回は私と星野が選んだ、良かったセッションをご紹介します。

伊藤(Python経験 7年)の印象に残ったセッション

「MLOps in Mercari Group’s Trust and Safety ML Team」

発表者等: Calvin Janitra Halim, Ayato Toyokuni(株式会社メルカリ)

メルカリさんのMLOpsのアーキテクチャについての発表です。
最近テックドクターでも機械学習モデルの本番利用に向けたシステムの構築を行っており、試行錯誤しながら進めている段階のため、非常に参考になるセッションでした。

アーキテクチャ図がふんだんに用いられていることで、複雑な構成も視覚的にも論理構造的にもわかりやすく、参考にしやすいと感じました。また英語での発表だったものの、図のおかげで理解しやすかったです。

弊社のアーキテクチャはよりシンプルな作りでも問題ないはずですが、先人の事例と比較することで方向性が大きく間違っていないことを確認できたのは、大きな収穫でした。(伊藤)

星野(Python経験 3年、Pythonでの大規模開発経験なし)の印象に残ったセッション

「あなたのアプリケーションをレガシーコードにしないための実践Pytest入門」

発表者:fujine (みずほリサーチ&テクノロジーズ株式会社 先端技術研究部)

Pythonに限らずテスト全般の内容が幅広く含まれた発表でした。テストをあまり書いたことがない人でもわかりやすかったのではないかと思います。

導入部の切り口も面白く、「レガシーコードとは」から始まる冒頭にまず興味を惹かれました。その後、データベースや時刻処理などのありがちなテストパターンにどう対処するかについて詳しく解説され、実践的なケースに対する理解が深まりました。

また、Pytestの小技も紹介され、今後テストを作成する際に参考になりそうな内容でした。Pytest初心者の私にとっては、今後使うであろうトピックスがまとまっており学びが多かったです。(星野)

全体の感想

個人としてもテックドクターとしても初のPyCon JPへの参加でしたが、まずは参加すること自体が楽しいイベントだと思いました。星野からも「久しぶりのテックカンファレンスで純粋に楽しかった」というコメントがありました。

セッションはここでは2つだけご紹介しましたが、それ以外にも良いものがたくさんありました。全体の傾向としては、Python初級者から中級者向けの発表が多かったように思います。(あくまで推測ですが)Pythonの利用用途が広範囲になっているので、間口を広くとるために初学者向けのセッションを多くしたのかもしれません。

カンファレンスイベントに敷居の高さを感じる人もいるかもしれませんが、少なくともPyConは、Pythonを使いはじめたばかりの人が気軽に参加しても得られるものが多くありそうです。

上級者が参加する場合は、初心者向けのセッションに当たって物足りない思いをしないように、あらかじめタイムテーブルを見て自身のレベルにあったセッションを選んでおくとより効率的な情報収集を行えそうです。

スポンサー出展について

将来的な出展を意識してスポンサーブースを回ってみると、単にノベルティをばらまくのではなく、ブースの方々が来場者を飽きさせないように配布方法やタイミングなどいろいろと工夫されていることがわかり、面白かったです。

また、何を目的にスポンサーをするのかで、どこに重きを置くのかが変わってきそうだと感じました。
例えば会社の知名度を上げたいという目的であれば、豪華なスポンサーブースを作るよりも、セッションに何人か登壇する方が結果として印象に残りやすいように思います。

まとめ

来年のPyCon JPは広島での開催だそうです。今回の体験を踏まえて、実際にスポンサーをするのか検討していきたいと思います。

運営事務局の皆さん、発表者・出展者の皆さん、楽しく役に立つカンファレンスをありがとうございました。

似顔絵
書いた人:伊藤

「意味のある外れ値」のデータ解析 〜極端に高い心拍数を定量的に評価する〜

こんにちは。データサイエンスチームの坂本と申します。

みなさん、データ処理における「外れ値」と聞くと、真っ先に除外すべきものというイメージをお持ちではないでしょうか。実は、必ずしもそうとはいえない場合もあるのです。

TechBlog第八回では、ウェアラブルデータ(※)解析の面白さを知っていただくために、この「外れ値」をめぐるひとつの事例をご紹介したいと思います。

ウェアラブルデータ……スマートウォッチを代表とするウェアラブル端末で測定された生体情報等のデータ

ウェアラブルデータの分析手法

ウェアラブルデータの分析では、目的に応じてさまざまな手法を使います。

代表的なものには、2つの群の差を取り扱う手法(t検定、分散分析等)や、データとデータの関連性を捉える手法(相関分析、一般化線形モデル等)、反復測定を考慮した手法(マルチレベル分析等)、分類や予測に適した手法(機械学習、深層学習等)、グループ分けに適した手法(クラスター分析等)などがあります。

これらの手法を駆使してデータの切り口を工夫したり、的確な分析手法を選択したり、ときには分析手法自体をオーダーメイドすることで、データからいろいろな情報を抽出することができます。

ウェアラブルデータは非常に豊かな情報源です。同じデータに対しても、さまざまなアイデアと手法を駆使することで、多様な研究に使える・発展する可能性を秘めています。言いかえれば、解析者が自身のアイデアでデータの持つ可能性を広げられる点こそが解析の面白さでもあります。

未知なる可能性を秘めたウェアラブルデータの解析。なかでも今回注目したいのが、先ほども触れた「外れ値」です。

眠っている男性のイメージ

極端に高い心拍数の捉え方

研究やデータ解析において、「外れ値」は除外対象として捉えられるのが一般的です。外れ値が、たとえばセンサーの誤作動といったような「適切に測定されなかったことに由来するノイズ」である場合、それを含めて分析してしまうと、結論に誤りが生じてしまう可能性があるためです。

しかし、一見すると除外対象のように思える「外れ値」も、ノイズとは異なる重要な意味を持っている場合があります。それを本稿では「意味のある外れ値」と表現しています。

たとえば、解析対象のデータが「前方に道路を横切る歩行者が現れてから、運転者がブレーキを踏むまでの時間」であったとします。このようなケースでは、ブレーキを踏むまでの平均時間よりも、極端な踏み遅れ(=意味のある外れ値)が重要な意味を持つことになります。事故につながるリスクが格段に高い現象だからです。意味のある外れ値がどのような条件の時に生じやすいのか。運転者が強い眠気を感じていたのか、歩行者を視認しにくい特別な交通状況があったのか……がわかれば、対策を立てることができます。

こう考えると、意味のある外れ値を除外せず、研究することの重要性がよくわかると思います。

同じくして、「極端に高い心拍数」にも重要な意味があると考えられます(もちろん、測定ミスの場合を除いて)。その背景には、急激な運動、動機や息切れの発生、心疾患などの病気や、手術後で弱った身体への負担、強度の緊張の発生など、さまざまな理由が想像できます。極端に高い心拍数の発生を定量的に評価することができれば、さまざまな研究への応用が期待できそうです。

では、実際に「定量的に評価する」方法にはどのようなものがあるでしょうか?

指数−ガウス分布

外れ値のような極端に大きな値を除外せず、解析的に考慮するための手法の一つに、「指数−ガウス分布(執筆者訳。一般的にはex-Gaussian Distributionや Exponentially Modified Gaussian Distribution等と呼ばれる)」を用いた分析があります。先ほど例に挙げた「ブレーキを踏むまでの時間」など、反応にかかる所要時間の分析に用いられることがあります。

指数−ガウス分布は、基本的なデータのばらつき部分を表現する正規分布と、外れ値に相当する成分を表現する指数分布とを合成(畳み込み積分により導出)した確率分布です。「山なりで右に裾が長い(重い)分布」という特徴的な形状を持ちます(図1)。

グラフ
図1 正規分布・指数分布・指数−ガウス分布の例 (μ=25, σ=3, τ=10の場合)

合成元となる正規分布の平均(μ)と分散(または標準偏差σ)、指数分布の期待値(τ、場合により、その逆数のλ)がパラメータであり、特に「外れ値の大きさや出現頻度に関する情報」をパラメータτで捉えることができます。データが指数−ガウス分布にしたがう(近似できる)と仮定し、パラメータ推定を実施することで、これらを定量化することができます。

睡眠中の心拍数データの分析

図2は、特定の期間に測定された、睡眠中の心拍数の度数分布です。2名分の実際の測定データ(※)を可視化しています。

※ 社内メンバーの提供データであり、お預かりした研究データではありません。

グラフ
図2 睡眠中の心拍数の度数分布

※最小値と最大値を破線、中央値を実線で示しています。

横軸は1分あたりの心拍数です。その心拍数が睡眠中の何分間、観測できたかを表すのが縦軸です。グラフからは、Bさんのみ1分あたり100以上の心拍数が観測されていることがわかります(赤矢印の箇所)。

Aさんは、睡眠中の最小心拍数が約50、最大心拍数が約80です。測定データはこの区間において「山なりで、右に裾が長い(重い)形状」で分布していることがわかります。

他方、Bさんも「山なりで、右に裾が長い(重い)形状」であることに変わりはありませんが、その裾がAさんよりも長い(重い)です。最大値も180を超えており、ときおり極端に高い心拍数が観測されていることがわかります。

「睡眠中の1分あたりの心拍数が80を超えたものは極端な値(=外れ値)」として、その割合を求めるなどの方法も考えられます。ただ、個人によって心拍数の平均値などが違うことを考えると、一律に「心拍数が80を超えたもの」のようなしきい値を決めるのではなく、個人差を考慮できる何らかの統計分析手法を適用した方がよいでしょう。

そこで今回は、AさんとBさんの2名について、それぞれのデータを用いて指数−ガウス分布のパラメータを推定します。統計解析環境R(version4.3.3)と、ハミルトニアンモンテカルロ法(NUTSアルゴリズム)を搭載したソフトウェアSTAN(version 2.32.2)を使用します(iteration = 2000, warmup = 1000, thinning = 4, chains = 4, total samples = 1000)。分析モデルの詳細は、本稿末尾をご覧ください。

分析結果

パラメータ推定の結果、全てのパラメータについて適切に推定できていることが確認できました(Rhat統計量<1.01、実効サンプルサイズ>10%、モンテカルロ標準誤差/標準偏差 < 10%)。

実際の度数分布と事後予測分布を重ね、視覚的にチェックしてみましょう(図3)。

※事後予測分布…既に観測されたデータに基づいて、将来のデータや新しい観測がどのような値をとるかを予測するために使う分布。ここでは先ほどパラメータ推定した指数−ガウス分布のこと。

グラフ
図3 視覚的事後予測チェック(Visual Posterior Predictive Checks)

※破線は測定データの最小値と最大値を示す。

図3では、実際の測定データの度数分布(ヒストグラム)と、曲線で示した事後予測分布(5つのiterationを無作為に抜粋)を重ねて表示しています。指数−ガウス分布によって、睡眠中の心拍数のばらつきかた(分布)を的確に捉えられていると判断してよさそうです。

次に、パラメータの推定結果も見ていきましょう。推定の結果、Aさんより、Bさんの方が、外れ値の頻度や大きさを表すパラメータτの値が高いことが確認されました(δ(τA - τB) = -0.508[-0.887, -0.1234])。結果を図4に示します。

グラフ
図4 指数−ガウス分布を用いた睡眠中心拍数のパラメータ推定結果

※点は事後分布の期待値(Expected A Posteriori)を示し、エラーバーは95%信用区間(Credible Interval)を示します。

技術の応用と研究への発展

このように、指数−ガウス分布を用いた解析は、「意味のある外れ値」を定量的に評価する際に有用だと考えられます。

さらにここから、さまざまな分析モデルへと発展させることもできそうです。「年齢が高くなるほど、パラメータτの値が高くなる」ことを仮定した回帰モデルや、「対照群より疾患群の方がパラメータτの値が高い」という個人と集団の階層性を仮定した分析モデル、そして、「手術直後からの3ヶ月間でパラメータτの推定値が徐々に低下した」などを取り扱う時系列モデルなど、やり方次第で多くの研究に貢献できる可能性があります。

もちろん、適用範囲は「極端に高い心拍数」だけではありません。極端に長い睡眠時間の発生や、極端に多い運動量など、さまざまな測定データに対して活用できる可能性があります。

「極端に高い」や「極端に長い」がキーワードになる現象を取り扱う際には、指数−ガウス分布の活用を検討してみてください。ウェアラブルデータを用いた詳細な研究等のご相談は、ぜひ弊社まで。

分析モデルとスクリプト(.stanファイル)

分析モデルを記載したStanスクリプト

// ExGaussian.stan

// 入力データ
data {
  int<lower=0> N;     // 対象者数(今回はN=2)
  int<lower=0> r;      // 観測したすべての心拍数の数(レコード数)
  int<lower=1> ID[r];   // 観測レコードに対応した対象者のID番号(A=1, B=2)
  vector[r] Y;          // 観測した1分ごとの心拍数の値
  int Const;            // 心拍数のスケールを調整する定数(今回はConst = 60)
}

// データの前処理
transformed data {
  // 0付近の正の実数で安定した推定をするために、スケールを秒単位に。
  vector[r] rescaled_Y;
  rescaled_Y = Y / Const;
}

// 推定パラメータ
parameters {
  // 個人ごとのパラメータ
  vector[N] mu;
  vector<lower=0>[N] sigma;
  vector<lower=0>[N] tau;
}


// モデル
model {
  // 事前分布
  mu ~ normal(0, 10);
  sigma ~ student_t(3, 0, 1);
  tau ~ gamma(0.01, 0.01);
  // 尤度関数
  for(i in 1:r) {
    // stanでは指数-ガウス分布の引数にλを使用するため、1/τを所与する
    rescaled_Y[i] ~ exp_mod_normal(mu[ID[i]], sigma[ID[i]], inv(tau[ID[i]]));
  }
}

// 事後予測分布の生成
generated quantities {
  vector[r] predY;
  for(i in 1:r) {
    // 生成した予測分布を元のスケールに戻す
    predY[i] = Const * exp_mod_normal_rng(mu[ID[i]], sigma[ID[i]], inv(tau[ID[i]]));
  }
}


似顔絵
書いた人:坂本

HealthKitを使ってAppleデバイス向け健康管理アプリ開発を始める方法

こんにちは。プロダクト開発チームでネイティブアプリの開発を担当している大嶋です。

この記事では、Appleが提供する健康データ管理のためのフレームワークであるHealthKitを活用し、健康管理アプリを開発する方法について解説します。

HealthKitを利用することで、iOSおよびwatchOSアプリがユーザーの健康やフィットネスデータを収集・管理できるようになります。具体的には、iPhoneやAppleWatchが収集したデータをアプリから読み込んだり、逆にアプリで収集したデータをHealthKit経由で蓄積することも可能です。

これから健康やフィットネスに関するアプリを開発したいと考えている方は、ぜひ本記事を参考にしてください。

Apple公式サイト「ヘルスケアとフィットネス」より引用

HealthKitの概要

HealthKitは、ユーザーの同意のもとでアクティビティ・心拍数・体重・栄養・睡眠などのデータを統合し、Appleの「ヘルスケア」アプリや「フィットネス」アプリで一元管理するためのフレームワークです。

例えば、月次の運動量を確認するとか、睡眠の質を確認するといった機能のアプリを比較的簡単に作ることができます。

データはデバイス内部のローカルストレージに保存されるため、ユーザーの健康データを安全に管理できます。

HealthKitを使用する利点としては、下記の3点が挙げられます。

  • データが統合管理できる
    「ヘルスケア」アプリで様々な情報を統合的に閲覧・管理できるため、ユーザーが自身の健康状態を把握しやすくなります。
  • プライバシー保護がしやすい
    データへのアクセスにはユーザーの明示的な許可が必要なため、データの利用や共有は厳密に管理されます。フレームワーク側でそれらの機能が実装されているので、アプリ側の設計で考慮する必要がありません。
  • サードパーティアプリと連携可能
    データを直接蓄積したアプリ以外のアプリからも、HealthKitを介してデータにアクセスすることができます。より広範囲な健康管理が可能です。

HealthKitを使ったアプリ開発の準備(Xcodeでの設定)

ここからは、実際の使用方法を紹介していきます。
HealthKitの利用の前に、Xcodeでの設定が必要です。以下の手順で設定を行います。

  1. CapabilityにHealthKitを追加
    プロジェクトのターゲット設定から「HealthKit」を有効化します。
  2. Info.plistにHealthKit関連の項目を追加
    HealthKitを使用するためには、Info.plistにHealthKitの利用目的を記載します。利用目的は、特にリリース時にはユーザーが理解できるように丁寧に記述する必要があります。

HealthKit実装サンプルの解説

次に、実際のHealthKitの実装についてもサンプルコードとともにご紹介します。実装例はGitHubに公開しているので、以下のリンクから確認してみてください。

github.com

アプリの概要

このサンプルアプリは、以下の3つの健康データを表示します。

  • 歩数:当日の合計歩数を表示します。
  • 平均心拍数:当日の平均心拍数をBPM(beats per minute)で表示します。
  • 睡眠時間:当日の睡眠時間(in bedの時間)を時間単位で表示します。
サンプルアプリの画面

また、画面にある「データを更新」ボタンを押すと、最新のデータが取得され、表示が更新されます。

アプリ開発において、考慮すべき項目がいくつかあります。

HealthKitの権限管理

概要のパートでプライバシー保護について書きましたが、HealthKitを利用する際には、ユーザーから必要なデータのアクセス権を得る必要があります。これを行うのがrequestAuthorizationメソッドです。

func requestAuthorization(completion: @escaping (Bool, Error?) -> Void) {
    let stepType = HKObjectType.quantityType(forIdentifier: .stepCount)!
    let heartRateType = HKObjectType.quantityType(forIdentifier: .heartRate)!
    let sleepType = HKObjectType.categoryType(forIdentifier: .sleepAnalysis)!
    let readTypes: Set = [stepType, heartRateType, sleepType]
    
    healthStore.requestAuthorization(toShare: nil, read: readTypes) { (success, error) in
        completion(success, error)
    }
}

requestAuthorizationメソッドでは、取得したいデータタイプをreadTypesセットで指定し、HealthKitの権限を求めます。ここでは、ユーザーの「歩数」「心拍数」「睡眠データ」にアクセスするための権限をリクエストしています。

このメソッドが実行されると、ユーザーの端末にHealthKit連携を許可するかどうかのポップアップが表示されます。

表示されるポップアップ画面の例

このメソッドが成功すると(=ユーザーが許可すると)、アプリはこれらのデータタイプに対してアクセス可能となります。

※ユーザーが許可しなかった場合は、アプリ側から再度アクセスを取ることはできません。「ヘルスケア」アプリから指標別にアクセス許可を取ることになります。

データ取得のクエリ

HealthKitでは、健康データを取得するためにクエリを使用します。ここでは、期間内の歩数データの合計を例にして、データ取得の方法を解説します。

歩数データの合計値を取得するためには、HKStatisticsQueryを使用します。これは平均値や合計などの統計値を計算するクエリです。今回は、合計を計算するためのオプション(.cumulativeSum)を指定します。

func fetchStepCount() {
    let stepType = HKQuantityType.quantityType(forIdentifier: .stepCount)!
    let startDate = Calendar.current.startOfDay(for: Date())
    let predicate = HKQuery.predicateForSamples(withStart: startDate, end: Date(), options: .strictStartDate)

    let query = HKStatisticsQuery(quantityType: stepType, quantitySamplePredicate: predicate, options: .cumulativeSum) { _, result, error in
        if let sum = result?.sumQuantity() {
            DispatchQueue.main.async {
                self.stepCount = sum.doubleValue(for: HKUnit.count())
            }
        }
    }
    healthStore.execute(query)
}

サンプルアプリでは、このクエリが返す合計値をstepCountプロパティに反映しています。

他の健康データ(心拍数や睡眠データ等)も、HealthKitが提供するクエリのオプションを変えることで簡単に取得できます。まずは基本的なクエリの使い方を習得して、徐々に応用してみてください。

データの同期や更新の遅延について

Apple WatchiPhone間でデータを同期する場合、バックグラウンドでデータのやり取りが行われます。基本的には、バッテリー消費やシステム負荷が考慮され適切なタイミングで更新が行われますが、以下の点は注意が必要だと思います。

  • 同期のタイミングについて
    両デバイスが適切と判断したタイミングで同期が行われるため、同期が遅延していると感じることがあるかもしれません。一方、 ユーザーの明示的なアクションに対しては即時にデータが更新されます。例えば同期ボタンを配置し、押されたタイミングでHealthKitデータの同期をトリガーすることが可能です。
  • バッテリー消費に注意
    データの頻繁な更新はバッテリー消費につながるため、必要に応じて更新頻度を見直すことも検討しましょう。例えばユーザーによる同期ボタンの連打を抑止するなどの対策は有効です。

まとめ

HealthKitを活用すれば、ユーザーの健康データを効率的に管理し、アプリの付加価値を高めることができます。さらに進化した健康管理アプリを目指していきましょう!

今回はHealthKitを用いた健康管理アプリ開発の概要と実装方法の一部をご紹介しました。ぜひこの内容を参考に、ご自身のアプリにHealthKitを取り入れてみてください。

参考

HealthKit | Apple Developer Documentation



書いた人:大嶋

女性にとって、自分の体調が「わかる」未来を目指して〜Ladynamicプロジェクトのご紹介〜

こんにちは、データサイエンスチームの瀬川です。

私は以前、病院で理学療法士として働いていました。
日々患者さんと接する中で感じたのは「自身の不調がより早期に発見でき、他者にもわかりやすく伝えられる」ことがとても重要であるということです。
それを可能にしたいという想いから、現在はデータサイエンティストの立場で、身体の状態を可視化し、誰もが自分の体調を理解しやすくなる未来を目指しています。

今回のTechBlog第六回では、私が進めている「女性の月経周期に関連するデータの可視化」に焦点を当て、その取り組みについてご紹介していきます。


「Ladynamic」プロジェクトと、女性ヘルスケアの課題について

弊社には女性メンバーのみで構成された「Ladynamic」というプロジェクトがあり、女性の視点に立った課題提起とデータ解析に取り組んでいます。

女性がキャリアを築きながら社会で活躍する機会はますます増えています。リーダーシップを発揮する場面や、専門分野での高い貢献が期待される場面も多く、さまざまな分野で女性がその力を発揮しています。

一方で見逃されがちなのが、女性特有の体調不良や疾患にまつわる問題です。
たとえば月経前症候群PMS)、月経困難症、さらには更年期症状など、月経周期に関わる症状は仕事や日常生活にも影響を及ぼします。
またもう一つの問題として、これらの症状に悩む女性は多いものの、その悩みを他者に相談することにためらいを感じたり、自分の症状を「たいしたことない」と思い込んでしまったりするケースも少なくありません。

このような課題に立ち向かうために、私たちが立ち上げたのが「Ladynamic」プロジェクトです。

このプロジェクト名は、「Lady(女性)」と「Dynamic(生き生きと)」の2つの言葉の組み合わせでできています。テックドクターの得意分野であるウェアラブルデータの活用とデジタルバイオマーカー(※)の開発という手段を用いて、女性がより健康的で生き生きとした生活を送れる未来を実現するためのプロジェクトです。

※デジタルバイオマーカー……ウェアラブルバイスで測定した『日常データ』をもとにした、病気の早期発見や治療につながる客観的指標(過去記事参照

スマートウォッチなどのウェアラブルバイスの強みは、長期間の連続した生体データを取得できる点にあります。測定の手間も、測定忘れの心配もありません。
ここで収集したデータを活用して、女性特有のデジタルバイオマーカーを開発することができれば、女性が自分の体調を予測・管理する大きな助けとなるはずです。

では具体的にどんなデータの解析を行っているのか、その一例をご紹介します。



女性に関連するデータ解析の紹介①:安静時の心拍数が月経周期と連動している?

まず、社内の女性1名に睡眠、脈拍、活動量に関するデータを数ヶ月にわたって蓄積してもらいました。

これに加え、被験者にはアンケートで月経開始日と終了日を記入してもらい、ウェアラブルバイスデータの推移と月経周期の関係性を可視化しました。

図1:ウェアラブルバイスデータと月経周期のグラフ。安静時心拍数は上段。

黄体期排卵後から次の月経が始まるまでの期間)を月経開始前の7日間、卵胞期(月経が終わってから排卵までの期間)を月経終了後の5日間と定義しました。
ウェアラブルバイスデータは1日単位に集約し、日ごとのデータとして使用しました。
※グラフに使用したデータは、1日のデータ取得率が70%を超えるもののみを採用しています。

月経期は背景を赤色、黄体期は青色、卵胞期は緑色で色分けしています。
注目してほしいのは一番上の折れ線グラフです。これは安静時心拍数の推移を表しています。
月経期が始まると月経終了日に向けて安静時心拍数が下がっていき、卵胞期を経て黄体期に向かって再度上がっていく周期性がわかるでしょうか。

月経周期に合わせて基礎体温が周期的に変動することは、一般的によく知られています。今回のグラフからは、安静時心拍数にも同じように月経周期に関連した周期性がある可能性が示唆されました。

女性に関連するデータ解析の紹介②:ウェアラブルバイスデータで月経痛の定量化ができる?

次にご紹介するのは、月経痛の定量化に関する取り組みです。
月経痛は個人差が大きいですが、それを定量化する手段が少ないことが課題です。

そこで私たちは社内の女性メンバーを対象に、月経痛が生じるごとに、月経痛に関するアンケートに回答してもらいました。
アンケートには、月経痛の強さに関する設問(MDQ(※)を参考に5段階評価)や、月経痛の持続時間の設問が含まれています。その回答から、痛みが軽く持続時間が短い人を「月経痛の軽い人」、痛みが強く長時間続く人を「月経痛の重い人」として定義しました。

MDQ……月経前や月経中にともなう症状を測定する尺度

次に、「月経痛の軽い人」と「月経痛の重い人」を1名ずつ選出し、それぞれの月経期(痛み無し)/月経期(痛み有り)/卵胞期/黄体期の期間に、ウェアラブルバイスデータの違いがあるかどうかを箱ひげ図で可視化しました。

図2(a) 「月経痛が重い人」の期間別箱ひげ図
図2(b) 「月経痛が軽い人」の期間別箱ひげ図

※アンケートとウェアラブルバイスのデータは3周期分のデータを使用しました。

月経期においては、「月経痛の重い人」では痛み無し期よりも痛み有り期の安静時心拍数が高い傾向があります。しかし「月経痛の軽い人」ではそれが逆転しています。

また、両者ともに黄体期は卵胞期よりも安静時心拍数が高いですが、「月経痛の重い人」は「月経痛の軽い人」よりも安静時心拍数の変動が大きい傾向がみられました。

今回の解析は「月経痛の重い人」と「月経痛の軽い人」の被験者数が1名ずつであったため、統計的な検定は行わず、可視化に留めました。
しかし今回の結果から期間の安静時心拍数の変動の大きさが月経痛の強さによって違う可能性が見えてきました。

今後は、より多くの被験者を対象にしてデータを集め、統計検定を行いながら月経痛とウェアラブルバイスデータの関係をより詳しく分析していきたいと考えています。


女性が自分の体調を予測・管理し、より健康的で生き生きとした生活を送ることができる未来を目指して

今回は月経周期に関連するウェアラブルバイスデータの可視化について書きましたが、今後はウェアラブルバイスデータから月経開始日や排卵日を予測することにも取り組んでいく予定です。

ウェアラブルバイスで予測が可能になれば、現在広く使われている基礎体温測定の代わりとして、より手軽で正確な月経周期管理が実現できるかもしれません。

私たち「Ladynamic」プロジェクトが目指しているのは、ウェアラブルバイスを通じて自身の体調を把握することで、より多くの女性が自分の体調を理解し対処することができる未来です。
また「自分の症状が軽いのか重いのか分からない」といった悩みに対しても、個人の症状を他者と比較することができれば、必要なケアを受けやすくなるはずです。

今回ご紹介した以外にも、今後は月経前症候群PMS)や月経困難症などの疾患に対するデジタルバイオマーカー開発にも取り組んでいく予定です。

こうした活動を通して、わたしたちはより女性が安心して活躍できる社会の実現を目指していきます。



書いた人:瀬川

Next.js(App router)における開発しやすいディレクトリ構成の例

初めまして、テックドクターでフロントエンド開発を担当している大瀧です。

ディレクトリ構成はコードの可読性やスケーラビリティに関わる重要な要素であると思っています。

しかし、フロントエンドのディレクトリ構成はベストプラクティスが確立されておらず、わりと悩むポイントです。

そこで今回は、Next.jsのApp routerにおいて、弊社で採用しているディレクトリ構成を共有します。この記事がディレクトリ構成に悩む開発者の助けになれば幸いです。

ディレクトリ構成の自由度が高すぎる問題

さきほど「フロントエンドのディレクトリ構成はベストプラクティスが確立されていない」と書きましたが、特にApp routerのディレクトリ構成については、公式ドキュメントで以下のように記載されています。

There is no "right" or "wrong" way when it comes to organizing your own files and folders in a Next.js project.
 
Next.js プロジェクトでファイルやフォルダを整理する方法には「正しい」「間違っている」はありません。

引用元:Routing: Project Organization | Next.js(日本語訳:プロジェクト構成とファイル配置 | Next.js 公式ドキュメント 日本語翻訳プロジェクト

正解も不正解もないと明記されているものの、これは自由度を高める一方で、開発者からすると悩ましいです。実際のプロジェクトにおいては、ある程度ルール化しておかなければコードの品質が保てませんし、保守しづらいコードは開発速度低下を招いてしまいます。

そこで本記事では、テックドクターで私が手がけているHealth Portalというプロダクトの構成を共有します。Health Portalは、クライアント(ヘルスケアアプリやSaMDを開発したい企業)がデジタルバイオマーカー*1を利活用するためのプラットフォームです。JavaScriptフレームワークにNext.js(App router)を採用しています。

Health Portalの技術スタック

前提として、フロントエンドで採用している主なライブラリはざっくり以下のとおりです。

  • Next.js v14
  • Tailwind CSS
  • React Hook Form
  • zod
  • keycloak.js

またAPIはFastAPIで実装しており、通信プロトコルにはREST APIを採用しています。

弊社のディレクトリ構成とその解説

ディレクトリ構成と各ディレクトリの役割

まず、ディレクトリ構成の全体像は以下のとおりです。

src
|
+-- app        # Routing files(Next.jsが標準で提供するファイル)
|
+-- components # 横断的(ドメインに依存しない)なUIコンポーネント
|
+-- features   # 特定のドメイン・機能に関係するコンポーネント
|
+-- hooks      # ドメインに依存しない、横断的なhooks
|
+-- providers  # アプリケーションプロバイダー
|
+-- utils      # 横断的な汎用関数
|
+-- constants  # 横断的な定数
|
+-- types      # 横断的な型定義
|
+-- styles     # スタイリング(css)に関するファイル
|
+-- lib        # ライブラリの処理や標準処理を共通化したコード
|
+-- tests      # 自動テスト関連

 

  • app: ルーティングの責務を持つディレクトリ。Routing files(Next.jsが標準で提供するファイル。page.tsxやlayout.tsxなど)のみを配置します
  • components: ボタンやモーダルなど、再利用可能でドメインに依存しないUIコンポーネントを格納します。
  • features: 特定の機能に関連するファイルを集約し、機能ごとのサブディレクトリに格納しています。例えば、ユーザー管理機能に関連するコンポーネント、hooks、ユーティリティ関数、型定義などをこのディレクトリ内でまとめます。
  • hooks: グローバルに使用されるカスタムフックを格納します。ドメインに依存しない汎用的なロジックはここにまとめます。
  • providers: ReactのContext APIやその他のプロバイダーを配置します。グローバルな状態管理やテーマ設定など、アプリケーション全体で使用されるプロバイダーをここに集約します。
  • utils: 簡潔で再利用可能なユーティリティ関数を格納します。これには、日付処理、文字列操作、API通信など、特定のドメインに依存しない関数が含まれます。
  • constants: アプリケーション全体で使用される定数を格納します。
  • types: TypeScriptの型定義をまとめます。
  • styles: グローバルスタイルやテーマ設定、Tailwind CSSのカスタマイズを含むスタイルシートをここに配置します。
  • lib: プロジェクト内で再利用されるライブラリや、外部ライブラリの実装をここに格納します。
  • tests: ユニットテストや統合テストなど、自動テストに関連するファイルを格納します。

基本的には、Reactアプリ開発のベストプラクティスと言われるbulletproof-reactを参考にしてディレクトリ構成を考えています。

bulletproof-reactについてはmejinさんの記事がとてもわかりやすくまとまっているのでご参照ください。
Reactベストプラクティスの宝庫!「bulletproof-react」が勉強になりすぎる件

肝となるのがfeaturesディレクトリで、ここには機能ごとのファイルが格納されます(詳細は後述)

以前はコンポーネントの粒度毎にディレクトリを分割するAtomic Designが流行ってた印象ですが、ドメイン毎にディレクトリを分類するほうが、フレームワークへの依存度が少なく学習コストやフレームワークの移行ハードルが低いように思います。

またClean Architectureの著者であるRobert C. Martinさんも記事の中で以下のように述べています。

Your architectures should tell readers about the system, not about the frameworks you used in your system.
 
あなたのアーキテクチャが読み手に伝えるべきなのはシステムのことであって、使用したフレームワークのことではありません。

引用元:Clean Coder Blog(日本語訳は筆者)

featuresの切り方について

featuresディレクトリの構成は、名のとおり機能毎にディレクトリを分割しています。

ディレクトリ分割の判断基準としては、オブジェクト指向UIというUI設計思想に基づき、分類しています。 オブジェクト指向UIとは、簡単にいうとオブジェクトを起点にユーザーのアクションが設計されたUIのことで、ここでいうオブジェクトとは「ユーザーが関心を寄せるモノ、ユーザーの操作対象となる名詞」を指します。このオブジェクト(ユーザーの関心事)ごとにディレクトリを分割しています。

例えば、「ユーザーの作成」や「ユーザーの削除」等のアクションがある場合、オブジェクトは「ユーザー」となり、関連するソースコードはuserディレクトリに格納することになります。 オブジェクト指向UIの詳細については、ぜひこちらを読んでみてください。

オブジェクトごとのディレクトリ配下の構造についても、基本的にbulletproof-reactに則っており、下記の図のとおり特定のドメインに依存するコンポーネントを格納します。

features            
|
+-- user            # 特定のドメインに関するディレクトリ
|   |
|   +-- hooks       # 特定のドメインに関するhooks
|   +-- utils       # 特定のドメインに関する汎用関数
|   +-- components  # 特定のドメインに関するコンポーネント
|   +-- types       # 特定のドメインに関する型
|   +-- providers   # 特定のドメインに関するプロバイダー
|   +-- pages       # appディレクトリ配下から呼び出されるページコンポーネントを格納する
|       +-- users_page.tsx
|       +-- user_new_page.tsx
|       +-- ...
+-- ...

しかし、オブジェクトごとのディレクトリすべてが完全に同じ構造を持つ必要はなく、その機能に必要なディレクトリのみを作成します。

appディレクトリとfeaturesディレクトリの対応関係について

features/xxx/pagesに格納されたページコンポーネントがエントリポイントとなり、appディレクトリ配下の対応するpage.tsxから呼び出されます。

app                 
|
+-- users            
|   | 
|   +-- page.tsx     # `features/user/users_page.tsx`を呼び出す
|
features
|
+-- user        
|   |
|   +-- pages 
|       +-- users_page.tsx
|       +-- ...
+-- ...

細かなルールについて

異なるfeature間での依存はNG

各featureは独立して機能するべきであり、他のfeatureに依存しないことで低結合・高凝集なソースコードを実現することができるため、異なるfeature間での依存はNGとしています。

横断的なコンポーネントに特定ドメインの要素を含ませるのはNG

コンポーネントを汎用化し、かつfeatureの凝集度を高めるために、横断的なコンポーネントに特定ドメインの要素を含めるのはNGとしています。

簡単な例ですが、以下のようにButtonコンポーネントにuserドメインを含めると汎用性が落ちてしまいます。

type ButtonProps = {
  user: {
    role: 'admin' | 'user';
  };
} & ButtonHTMLAttributes<HTMLButtonElement>;

const Button: FC<PropsWithChildren<ButtonProps>> = ({ user, children, ...props }) => {
  const buttonClass = user.role === 'admin' ? 'bg-red-500' : 'bg-blue-500';

  return (
    <button {...props} className={buttonClass}>
      {children}
    </button>
  );
};
ファイル名にパスカルケース・キャメルケースを使用しない

MacWindowsではファイル名の大文字小文字を区別しませんが、Linuxではこれを区別するのでファイル名はスネークケースで統一してます。

本構成のメリット

コードリーディング時の認知負荷が下がる

単一の機能毎にディレクトリが分かれているため、コンテキストが統一されコードの理解がし易いと個人的には思っています。

他の開発者とコンフリクトしづらくなる

機能毎にディレクトリが分かれているため、機能修正や追加の際にコンフリクトが起きにくくなります。大規模な開発体制の場合は開発生産性が結構上がるんじゃないかと思います。

フロントエンドエンジニア以外も多少コードリーディングが楽になる

これは実際に確認したわけではないのですが、フロントエンド特有のしきたりではなくドメイン毎にディレクトリが分かれているため、プロダクトそのものの知識があればコードリーディングが楽になるような気がしています。

デメリット・改善点

やっぱりfeaturesディレクトリ配下の切り方が曖昧

オブジェクト指向UIの考え方を参考にfeatureを分類することで、開発者間で一応は共通認識を持つことは出来ているような気はしつつ、明確な線引があるわけではないのでたまに悩んでしまいます。ラクスさんの場合は画面仕様書単位で切り分けているようです。

最終的な画面表示のロジックはfeatures/xxx/pagesではなく、app配下で実装してもいいかも

features/xxx/pagesを作成すると責務の分離ができる反面、該当のページがどのURLに対応するかが分かりづらくなってしまいます。
なので、pageのレンダリング処理に関してはapp配下で実装してもいいかもしれないです。
実際、元VercelのエンジニアであるSteven Teyさんが開発している、dubというプロダクトではapp配下にpage.tsxpage-client.tsxを格納する設計になってます(以下を参照ください)
dub/apps/web/app/app.dub.co/(dashboard)/[slug]/settings/tokens at 35973de925857f4952d7910a2424ffab478ad2cb · dubinc/dub · GitHub

正直なところ、ルーティングとレンダリングの責務を分離することに今のところ大きなメリットを感じていないので、こっちのほうが分かりやすいかも知れません。

*1:ウェアラブル端末やスマホから取得できるデジタルの情報をもとに、病気や治療の変化を可視化するための指標

データ解析で伝える「調子」~心拍・運動・睡眠データから得られる意味

こんにちは。データサイエンスチームの坂本と申します。TechBlog第四回では、日常生活中の心拍や睡眠などのデータを解析する意義や可能性について、分析者の視点からお話しします。

私たちは、スマートウォッチを代表とするウェアラブル端末で測定されたデータの解析を行っています。このデータ解析という行為を少し抽象的に言い換えると、「数字の羅列から意味を見つけ出す技術」であると表現できます。

そこから得られる「意味」とは、いったい何であり、何の役に立つのでしょうか?

心や身体の「調子のバロメータ

私たちが主に取り扱う心拍・運動・睡眠のデータ*1は、いわば心や身体の「調子のバロメータ」です。

これは体温計のようなものだと考えると馴染みやすいかもしれません。37度の微熱だとか、39度近い高熱だといったように、自分の体調やしんどさを家族やお医者さんに伝える時の「言葉」になるものです。

もちろん、体温だけではわからないことも多いです。ですが咳が出る等の周辺の情報と組み合わせることで、その人の心や身体の状態への理解が深まり、病気の診断や、適切な薬の処方に貢献します。

デジタル生体データも、これによく似ています。自分の体の変化を数字でとらえることで、客観的に体調の変化を表すことができます。

病気と健康の「第三の情報源」

これまで、心身の調子は主に「本人の感覚」や「病院での検査」などで捉えられてきました。もちろん現在も、これらは様々な研究や病気の診断などで、最も重要なものとして考慮されています。

しかしその一方で、本人でさえ気づいていない心身の変化や、病院では見えてこない日常生活のしんどさといったものも存在します。それらは見落とされたり、診察の時間中だけで伝えきることが難しいために取りこぼされてきました。実はここに、「本来必要な情報の不足」が発生しています。

デジタル生体データは、いろいろな条件でデータを抽出したりすることで、本人も気づかないような「日々の調子」を捉えることができます。例えば「眠っている時に心拍数が急激に変化している」などは、本人であっても自覚が困難ですが、病気の診断や予防に重要な役割を果たしそうですよね。私たちデータ解析者は、こういった情報をうまく抽出し、わかりやすく活用できるよう、様々な解析をしています。ひとつひとつの開発と検証が進む中で、デジタル生体データは、「病気と健康の第三の情報源」として確立したものになってゆくだろうと予感しています。

図1. デジタル生体データは病気と健康の第三の情報源

データ解析の面白さと様々な工夫

さきほど、デジタル生体データは調子のバロメータであり、体温計のようなものであると表現しました。しかし、体温計の場合、「熱がある」というだけでは、原因が何かまではわかりません。

他方、デジタル生体データの場合、「心拍数が高くなっている」という情報から、その背景理由を推測したり、将来起きる出来事を予測できる場合があります。心拍数が上がる理由の代表例は「運動」「飲酒」「発熱」などですが、細かく分析を進めてゆくと、心拍数の「上昇のしかた」が全て異なっているということを発見(!)したりします。

データ解析では、こういった心拍数の「上昇のしかた」を特定し、データを上手に加工することで、「運動」「飲酒」「発熱」を判別できるようにしたりします。すると、「先月、何日間ほど発熱で寝込んでいたか」や「1ヶ月〜1年でどれくらいお酒を飲んでいたか」が分かるようになります。「風邪を引いて治ったと思っていたけれど、まだ完全には身体の状態が戻っていなかった」ということにも気がついたりします。こういった技術は、本人が生活を振り返ったり、誰かに伝える場合だけでなく、研究などにも応用できると考えられます。

図2. 発熱に反応する心拍バロメータの例

また、スマートウォッチ等で測定されるデジタル生体データには、新しい第三の情報源としての利点がある一方で、いくつかの弱点もあります。着脱などによる測定データの欠落がその一例です。こういったデジタル生体データの特徴に対して、データ解析の視点からは「解析結果の品質を守るための取り組み」が必要になります。

例えば「睡眠不足」という情報を抽出したい時には、毎日の睡眠データが必要になります。しかし、寝ている時にスマートウォッチを外した日や、睡眠中に電池が切れてしまった時には、データの欠落が発生してしまいます。このような場合、データ解析者は「欠損補完」という技術でデータや解析結果の品質をカバーしようと試みることがあります。

欠損補完にも様々な手法が存在し、ケースバイケースで最適な方法が異なります。そこで、「わざとデータを欠落させて、欠損補完をした時の復元度合いを確認する」といった方法で、最適な欠損補完方法を検証したりしています。

図3. 欠損補完の性能比較(一部の手法のみ掲載)

このように生体データ解析では、工夫すればするほど様々な価値が出てきます。株式会社テックドクターには、心理学を勉強してきた私を一例として、様々なバックグラウンド/専門分野を持つデータサイエンティストが所属しています。それぞれの分析者が持つユニークな視点や、得意な技術を活かすことができる領域であり、そんなところも魅力のひとつです。

デジタル生体データの解析は可能性の宝庫

ここまでで紹介できたのはほんの一例に過ぎませんが、デジタル生体データの解析は可能性に満ちています。これからたくさんの発見があり、一つ一つの発見が実用化につながってゆくと予感しています。

実用化の領域は、一人ひとりが関心を持っている事柄(執筆者の場合は、ランニングで心肺機能が回復したかを確認したりすること)をセルフチェックしたり、病院での診察場面や、病気の予防や治療効果に関する研究など、様々だと考えられます。どのような応用例であっても、データや分析結果の品質を守る取り組みは、丁寧に進めていきたいですね。

自分自身の心身の調子を、家族や友人、お医者さんに話すとき。あるいは、研究という取組を通じて、一人ひとりの体験を世界に伝えてゆくときに。デジタル生体データが、「人と人とが理解し合うための言葉」として使われることを願っています。


書いた人:坂本

*1:※ 他にも、様々な種類のデジタル生体指標や、検査データ、アンケートデータなどを幅広く取り扱っています。