mikutaifukuの雑記帳

個人的な雑記帳。データ分析とか読んだ本の感想とか。

Fitbitの心拍数データで異常検知 〜近傍法で異常部位検出〜

概要

「入門 機械学習による異常検知―Rによる実践ガイド」を読んで、自分でもやってみたいと思い、自分のFitbitの心拍数データを使って7章の時系列データの異常検知をやってみました。似たような記事は他にも色々あり*1、二番煎じではありますが自分なりにまとめてみます。

 Fitbitとは

www.fitbit.com

歩数・睡眠状態・心拍数等の様々な活動量を記録してくれるウェアラブルバイスです。一部の企業では、従業員にFitbitを配布して、健康管理なんかもしているみたいです。ちなみに私はFitbit Alta HRを使用していますが、最近発売されたfitbit ionicと呼ばれるスマートウォッチも気になっています。

ダッシュボートは以下のような感じです。

もちろんスマートフォンでも見ることができます。

f:id:mikutaifuku:20180205213157p:plain

使用データ

fitbitは公式APIを提供しているので、そちらからデータを取得しました。

以下の記事を参考にしました。(結構苦労しました)

qiita.com

睡眠時以外は、Fitbitを外していてデータが欠損していたり、運動して急激に心拍数が上がったりと少し扱いにくかったので、睡眠時の心拍数データに絞りました。

可視化

とりあえず以下のように1/8~1/14の睡眠時心拍数データを可視化してみました。

目的は、以下の図の赤丸で囲んでいるような異常値を、近傍法で検出することです。

f:id:mikutaifuku:20180205214759p:plain

  • fitbitの睡眠データから、睡眠開始/終了時間を取得できるので、その時間帯の心拍数のみ取得しています
  • 以下のように「睡眠ステージ」データも取得できますが、今回は使用しません。睡眠開始時間からの数分は「目が覚めた状態」のため心拍数が高くなっていると思われます。

    f:id:mikutaifuku:20180205220146j:plain

  • Rのggplot2を使用しています(赤丸は除く)

それにしても、社会人とは思えないほどよく寝ていますね。大学生のような睡眠時間です。(この週は休暇で休んだり、出張だったりで少しイレギュラーでした。)

近傍法による異常部位検出

計算イメージ
  • 各時刻の観測値をそれぞれ扱うのではなく、w個の隣接した観測値をw次元のベクトルとして表します。
  • 訓練用の時系列Dtrの各要素と、検証用の時系列Dのx(t)の距離を計算します。

イメージ図(参考:「入門 機械学習による異常検知―Rによる実践ガイド」P.196)

f:id:mikutaifuku:20180206152440p:plain

  • 上記で求めた距離(今回はユークリッド距離)のうち、最小なものk個選び、score(異常度)を算出します。scoreはk = 1の時は最近傍までの距離、k > 1の時は近傍距離の平均を考えることとします。

結果

"2018-01-11"を訓練用の時系列データとし、"2018-01-12"を検証用の時系列データとしました。

窓幅 w = 5, 10の2パターン、近傍数 k = 1, 10の2パターンで試した結果、以下のようになりました。

f:id:mikutaifuku:20180206144111p:plain

一番上の心拍数データで示した異常部位に対して対応した箇所でscoreが大きくなっていることがわかります。w = 5, k = 10でやった結果が一番良さそうです。

書籍にも書いてあるように、近傍法を用いた方法はノイズに弱いらしいので、もう少し別の方法を検討する必要があるそうです。 ということで、次回は同じデータに対して「特異スペクトル変換法」で、異常検知をしてみようと思います。

さいごに

今回のエントリでは、Fitbitの心拍数データに対して、近傍法によるアプローチで異常部位を検出しました。

みなさんが、ブログで書いているようにRやPythonのプログラムも公開したいところですが、人様に見せるのが恥ずかしいレベルなので今回は諦めしました。

インターネットから取得できるよく分からないデータよりも、自分のデータを使って分析をした方が楽しいですね。

 

mikutaifuku