本ページは 身体・運動 AI(Body / Motion AI)を 12 のセクションで多角的に解説します。 上のチップは検索・関連語の手がかりです。 以下のリンクで各セクションに直接ジャンプできます:
🍰 まずはやさしく
AIに体を持たせる技術です。
機械を上手に動かすために使います。
自動運転の車などが身近な例です。
AIがどうやって体を動かすか読みます。
🍰 まずはやさしく
AIと現実の世界をつなぐ橋です。
連続的な動きを作るために使います。
スポーツのフォーム解析などで使われます。
この技術がどこで役立つか読みます。
本サイトでは 身体・運動 AI は AI 応用分野の 1 つとして位置づけ、 「データ+数学+知能」が 物理世界と接する領域として扱います。 推論だけでなく 連続的な行動を出力する点で、 分類・回帰タスクとは大きく性格が異なります。 ロボティクス・自動運転・スポーツ動作解析・ヒューマノイドなど、 ハードウェアと AI の境界に位置する分野です。
🍰 まずはやさしく
考えるだけでなく動かすAIです。
自然な動きを再現するために使います。
ゲームのキャラの動きが身近な例です。
具体的にどう動くのかを読みます。
「身体・運動 AI」を一言で言えば、 「考えるだけで終わらず、 体(あるいは機械)を動かす AI」。 たとえば次のような例:
共通するのは 「連続値の制御出力」を リアルタイムに決め続ける必要があること。 1 度の判断ミスが 転倒・衝突に直結するため、 安全性と頑健性が極めて重要です。
例えば二足歩行では、 関節 20 か所のトルクを 100 Hz で出力。 つまり 毎秒 2000 個の連続値を「正しく」決め続ける必要があり、 これを人間が手書きルールで作るのは事実上不可能。 そこで 機械学習の出番になります。
身体動作(body movement)のデータ解析は、 ウェアラブル端末・モーションキャプチャ・スマートフォンの内蔵センサーから得られる 連続値時系列を入力として、 「歩行 / 走行 / 立ち上がり」などの動作カテゴリ、 関節角度、 消費カロリー、 転倒リスクを推定する分野です。 代表的なセンサーは 6 軸 IMU(3 軸加速度 + 3 軸ジャイロ)と GPS の組合せで、 高度な研究では Vicon や OptiTrack の光学式モーションキャプチャ、 EMG(筋電図)、 心拍計が追加されます。 サンプリングは 50〜200Hz が一般的で、 1 分間で 6 軸×100Hz = 36{,}000 数値が生成されるデータ密度の高い領域です。
比喩で言えば、 身体動作データは「音波(音声)と映像(画像)の中間」のような性質を持ちます:時間軸はあるが画素のような 2 次元構造はなく、 多軸センサーが平行に並走する。 そのため、 FFT・ウェーブレット・DTW・LSTM・1D-CNN・Transformer が代表手法です。 入力の実体は「加速度・角速度の多軸時系列」や「関節・骨格の 3 次元座標系列」といった連続値であり、 画像分類のように 1 枚で完結せず、 時間方向の文脈を保ったまま特徴量化する点が最大の特徴です。
| センサー種別 | サンプリング周波数 | 単位 | 代表用途 |
|---|---|---|---|
| 加速度センサー(3 軸) | 50〜200 Hz | m/s² または G | 歩数計、 動作分類 |
| ジャイロセンサー(3 軸) | 50〜200 Hz | rad/s または °/s | 姿勢推定、 回転量 |
| 地磁気センサー | 10〜50 Hz | μT | 方位、 屋内測位補正 |
| 心拍 (光学式) | 1〜25 Hz | bpm | 運動強度、 ストレス |
| 光学式モーションキャプチャ | 120〜240 Hz | mm | 関節位置・動作解析 |
| EMG(筋電) | 1000+ Hz | μV | 筋活動量、 リハビリ |
下は 架空の簡略化した棒人間(15 個の関節キーポイント/完全にダミー座標・実データではありません)です。 肩・肘・手首・腰・膝・足首などの点を ドラッグすると、 骨と骨がなす 関節角度(肘の曲げ角・膝の曲げ角など)がリアルタイムに計算され、 「立つ/座る/腕を上げる」を 角度ルールだけで自動判定します。 これが 姿勢推定(pose estimation) の最小核 ── 画像から関節点(キーポイント)を取り出し、 その 幾何(角度と距離)だけで動作を特徴づける、という発想の体験版です。
やっていることは 3 ステップ:(1) 関節を キーポイント(点)として表す → (2) 隣り合う骨ベクトルの内積から 関節角度を、 点同士の 距離を計算する → (3) 「膝角 < 150° なら座る/手首が肩より上なら腕を上げる/それ以外は立つ」という 角度ルールで姿勢を分類。 ノイズやオクルージョン(隠れ)を入れると、 推定がどう崩れるかも体感できます。
🔍 何が起きているか:姿勢分類の主役は 関節角度です。 肘・膝の角度は「隣り合う 2 本の骨ベクトル $\mathbf{u},\mathbf{v}$ の内積」から $\theta=\arccos\!\big(\tfrac{\mathbf{u}\cdot\mathbf{v}}{\|\mathbf{u}\|\|\mathbf{v}\|}\big)$ で一意に決まります(実装は数値安定な atan2(|cross|, dot))。 立つ=膝ほぼ 180°・腕は下、 座る=膝が曲がる(<150°)、 腕を上げる=手首の $y$ が肩より上 ── この 角度・距離のルールだけで、 生の座標を見ずに姿勢を切り分けられます。 実際の姿勢推定も「画像→キーポイント→角度特徴→分類」という同じ骨格です。
人が姿勢をひと目で読むとき、 見ているのは 関節の位置関係です。 「肘が曲がっている」「手が頭より高い」「膝が直角」── これらはすべて キーポイント間の角度と距離に還元できます。 姿勢推定の要点は、 数百万画素の画像を 十数個の点にまで圧縮し、 その点群の幾何だけで動作を語ること。 上のウィジェットで肘角・膝角が姿勢と連動して変わるのを見れば、 「点と角度で姿勢は完全に記述できる」という直感がつかめます。 姿勢を 特徴づけるのは、 生座標そのものではなく、 角度(回転不変・平行移動不変)や 正規化した距離(体格でスケール補正)です。
🍰 まずはやさしく
動きをルールにした数式です。
正しい動作を計算するために使います。
ロボットの関節の角度を決める例です。
動きをどう計算するかを読みます。
強化学習で動作を学ぶ際の方策(policy)と累積報酬:
制御工学側の表現としては、 動作方程式と最適化問題の組み合わせ:
身体・運動 AIを数式 / 形式定義で表す:
ロボット動力学方程式:関節トルク $\boldsymbol{\tau}$ は、 慣性 $M$・コリオリ $C$・重力 $G$ の和で決まる。 運動 AI はこの $\boldsymbol{\tau}$ を最適化する。
① 関節角度(Euler 角ベース):3 次元空間で隣接する 2 つの骨の方向ベクトル $\mathbf{u}, \mathbf{v}$ がなす角度は内積から導けます。
$$ \theta = \arccos\!\left( \frac{\mathbf{u} \cdot \mathbf{v}}{\|\mathbf{u}\| \|\mathbf{v}\|} \right), \quad \theta \in [0, \pi] $$
② FFT(高速フーリエ変換)による周波数特徴:歩行や走行は周期的なので、 加速度信号 $x(t)$ をスペクトルに変換すると「歩行周波数」のピークが現れます。 離散 FFT は次の通り:
$$ X_k = \sum_{n=0}^{N-1} x_n \cdot e^{-i \cdot 2\pi k n / N}, \quad k = 0, 1, \ldots, N-1 $$
パワースペクトル密度 $P_k = |X_k|^2 / N$ のピークが 1.5〜2.5 Hz にあれば歩行、 2.5〜4 Hz は走行、 と判定できます。
③ DTW(Dynamic Time Warping):2 つの時系列 $X = (x_1, \ldots, x_N)$、 $Y = (y_1, \ldots, y_M)$ の「形は似てるが時間軸が伸縮した」類似度を測る指標。 動的計画法で最適アライメントを求めます:
$$ D(i, j) = d(x_i, y_j) + \min\bigl\{ D(i-1, j),\ D(i, j-1),\ D(i-1, j-1) \bigr\} $$
$$ \text{DTW}(X, Y) = D(N, M) $$
上の数式に出てきた記号を 1 つずつ解説します。 数式が出てくる試験問題(統計検定・G 検定・基本情報)では、 各記号の意味を答えられるかが分岐点:
| 記号 | 意味 |
|---|---|
| $\boldsymbol{q}$ | 関節角度ベクトル |
| $\dot{\boldsymbol{q}}, \ddot{\boldsymbol{q}}$ | 速度・加速度 |
| $M(\boldsymbol{q})$ | 慣性行列 |
| $C$ | コリオリ・遠心項 |
| $G(\boldsymbol{q})$ | 重力項 |
| $\boldsymbol{\tau}$ | 関節に与えるトルク(制御出力) |
「身体・運動」を入門レベルで習得した次に進むべき発展テーマ:
基本概念を 確率論・情報理論・最適化理論の観点で再定式化すると、 隣接する手法との理論的な関係が見えてきます。 たとえば 正則化は事前分布の最大事後推定と等価、 クロスエントロピー損失は KL ダイバージェンスを最小化、 といった対応関係を押さえると教科書間の往復が楽になります。
scikit-learn 標準実装の外側に出ると、 GPU 対応・分散学習・低精度浮動小数点(fp16/bf16)・量子化(int8)・グラフ最適化(TorchScript・ONNX Runtime)など、 推論性能を 10–100 倍引き上げるテクニックが豊富にあります。 本番運用では モデル精度と推論コストのトレードオフを意識した実装が鍵。
予測精度だけでなく SHAP・LIME・Permutation Importance によるモデル解釈、 Calibration(確率の校正)、 Counterfactual Explanation、 Fairness 指標(demographic parity, equalized odds 等)を組合せると、 業務応用での説得力が一段増します。
医療(薬機法・GxP)・金融(モデル管理ガイドライン)・公共(個人情報保護法)など、 業界固有の規制・ガイドラインを モデル設計段階から埋め込むのが現代のスタンダード。 「身体・運動」を業務適用するときは、 ドメインの専門家・法務との早期コラボレーションが成否を分けます。
身体・運動データ(Body Movement Data)は、 ヒトや動物の身体運動を時系列・空間的に記録した数値データの総称である。 ここでは「モーションキャプチャ」「IMU センサー」「動画解析」「スポーツ科学」「リハビリ応用」「ジェスチャー認識」の 6 領域を、 数式と代表データ形式を軸に整理する。 身体動作データは「サンプリング周波数 × 関節数 × 軸数」の三次元テンソル $X \in \mathbb{R}^{T \times J \times D}$ として扱われ、 $T$ はフレーム数、 $J$ は関節数(OpenPose では 25、 SMPL では 24)、 $D$ は座標次元(2D 画像なら 2、 3D モーキャプなら 3)である。 いずれの領域でも入力の実体は「加速度・角速度の多軸時系列」または「関節・骨格の 3 次元座標系列」であり、 サンプリング周波数・関節数・軸数の 3 つが解析設計の出発点となる。
光学式モーションキャプチャでは、 被験者の関節付近に貼られた反射マーカーの位置 $\mathbf{p}_j(t) = (x_j, y_j, z_j)$ を 100-1000 Hz で記録する。 関節角度 $\theta(t)$ は隣接マーカー間ベクトル $\mathbf{v}_1, \mathbf{v}_2$ の内積から $\theta = \arccos\left(\frac{\mathbf{v}_1 \cdot \mathbf{v}_2}{|\mathbf{v}_1||\mathbf{v}_2|}\right)$ で求める。 マーカーレス系(OpenPose, MediaPipe)は深層学習で 2D キーポイントを推定し、 三角測量で 3D 化する。 得られる $\mathbf{p}_j(t)$ の座標系列から、 歩幅・関節可動域・重心動揺といった臨床指標を算出できる。

IMU(Inertial Measurement Unit)は加速度 $\mathbf{a}(t) \in \mathbb{R}^3$、 角速度 $\boldsymbol{\omega}(t) \in \mathbb{R}^3$、 地磁気 $\mathbf{m}(t) \in \mathbb{R}^3$ を同時計測する 9 軸センサーである。 姿勢 $\mathbf{q}(t)$(四元数)は相補フィルタ $\mathbf{q}_{t+1} = (1-\alpha) \cdot \mathbf{q}_{\text{gyro}} + \alpha \cdot \mathbf{q}_{\text{acc+mag}}$ で推定し、 $\alpha \approx 0.02$ が典型値。 歩数推定は加速度ノルム $|\mathbf{a}| = \sqrt{a_x^2 + a_y^2 + a_z^2}$ のピーク検出で行う。 Apple Watch・Fitbit などのウェアラブルはこの原理で日々の歩数・活動量を推定し、 加速度ノルムの時系列を特徴量化して行動を分類している。

投球速度・走行速度・ジャンプ高 $h = \frac{v_0^2 \sin^2\theta_0}{2g}$ といった運動学的指標と、 関節トルク $\tau = I \alpha$($I$: 慣性モーメント、 $\alpha$: 角加速度)といった力学的指標がある。 トラックマン(野球)、 Catapult(サッカー)、 STATSports(ラグビー)などの GPS+IMU 一体型デバイスは、 選手の総走行距離・スプリント回数・心拍数を試合中リアルタイム記録する。 これらの多軸時系列から疲労・傷害リスクを推定し、 トレーニング負荷(ACWR など)の管理に機械学習が活用されている。

脳卒中後の上肢リハビリでは、 Fugl-Meyer Assessment スコアと身体動作データ(reaching task の軌道滑らかさ:jerk $j = \frac{d^3 x}{dt^3}$ の積算)が強く相関する。 リハビリ進捗の定量化指標 NJM(Normalized Jerk Metric)$\text{NJM} = \sqrt{\frac{1}{2} \int_0^T j^2 \, dt \cdot \frac{T^5}{L^2}}$ は健常者で 5-15、 重度患者で 200 を超える。 高齢者転倒予測モデルでは IMU + 機械学習(XGBoost)で AUC 0.85 を達成し、 日常の加速度ログから転倒の予兆となる歩容変化を検出できる。
手話認識・サインジェスチャ識別では LSTM/Transformer で時系列特徴量を分類する。 入力テンソル $X \in \mathbb{R}^{T \times 21 \times 3}$(MediaPipe Hands の 21 キーポイント × 3 軸)を、 双方向 LSTM 隠れ状態 $\mathbf{h}_t = \text{BiLSTM}(\mathbf{x}_t, \mathbf{h}_{t-1}, \mathbf{h}_{t+1})$ で符号化し、 ソフトマックス分類器で語彙 ID を出力する。 ASL(米国手話)データセット WLASL2000 で SOTA 精度 70%+。 動的時間伸縮(DTW)距離 $D(i,j) = d(i,j) + \min(D(i-1,j), D(i,j-1), D(i-1,j-1))$ も古典手法として現役。
スマートフォン IMU からの行動認識(Human Activity Recognition: HAR)は「歩く・走る・座る・立つ・階段昇降」など 6-12 クラスを CNN+LSTM で分類する。 公開データセット UCI HAR(30 人 × 6 行動 × 50Hz × 2.56 秒窓)でテスト精度 96% 超。 PAMAP2 では心拍数も統合し、 安静時心拍 60 bpm vs 階段昇降 130 bpm を識別できる。 加速度・角速度・心拍を統合した特徴量で「日常活動量(MVPA 分・歩数)」を定量化し、 健康アウトカムとの関連を検証する研究が広がっている。
💬 まとめ: 身体・運動データ解析は「センサー → 特徴量 → モデル → 応用」の 4 段階で構造化でき、 各段階で異なる数式・ツールが必要となる。 個人スケールのセンサーログに加え、 公的統計のマクロ指標(本ページ後半の SSDSE-B-2026 演習を参照)と接続すれば、 動作データから地域スケールの健康傾向まで視野を広げられる。 これは「定量的健康科学」「スマートシティ」「介護予防」の根幹技術である。
SSDSE-B-2026 には「スポーツ実施率・歩数・健康寿命・国民医療費・要介護認定率」といった身体活動そのものや健康アウトカムの変数は収録されていない。 そこで本セクションでは、 実在する都道府県の地域特性指標(着工新設住宅戸数・延べ宿泊者数・医療施設密度・高齢化率・出生率)を題材に、 単純相関 → 偏相関という交絡統制の標準ワークフローを実データで体験する。 個人スケールの IMU データ解析(本ページ前半)と、 公共統計スケールの多変量解析を接続する「型」を身につけるのが狙いである。 使用データは SSDSE-B-2026.csv(564 行 = 47 都道府県 × 12 年分、 112 列)で、 年次列 SSDSE-B-2026==2023 を抽出して用いる。 相関・偏相関の数値はすべて 2023 年 47 都道府県で実測したものである。
身体活動・健康寿命の直接変数は SSDSE-B に無いため、 実在列から派生計算した地域特性指標で交絡統制のワークフローを実演する。 いずれも 2023 年 47 都道府県の実測値。
| 記号 | SSDSE-B 列(派生計算) | 指標 | 単位 | 典型レンジ(2023, 47 都道府県) |
|---|---|---|---|---|
| $X_1$ | H1800 / A1101 × 1000 | 着工新設住宅戸数(人口千対) | 戸 | 3.6 - 8.9 |
| $X_2$ | G7101 / A1101 | 延べ宿泊者数(1 人当たり) | 泊 | 0.6 - 13.7 |
| $X_3$ | I510120 / A1101 × 10⁵ | 一般病院数(人口 10 万対) | 施設 | 3.1 - 16.1 |
| $X_4$ | I5102 / A1101 × 10⁵ | 一般診療所数(人口 10 万対) | 施設 | 62 - 113 |
| $Z$ | A1303 / A1101 × 100 | 高齢化率(65 歳以上割合)=交絡変数 | % | 22.8 - 39.1 |
| $Y$ | A4101 / A1101 × 1000 | 出生率(人口千対)=アウトカム | 人 | 4.0 - 8.6 |
このコードでやること: SSDSE-B-2026 の 2023 年(SSDSE-B-2026==2023)から地域特性 6 変数を派生計算し、 pandas.DataFrame.corr() でピアソン相関の総当たり行列を作成、 ヒートマップで可視化する。
📥 入力データ(読み込み後 head の例):
1 2 3 4 5 6 7 8 9 10 11 | 1 2 3 4 5 6 7 8 9 10 11 |
📤 実行例(相関行列、 主要部分):
💬 読み方: 着工新設住宅戸数(X1)・延べ宿泊者数(X2)は出生率(Y)と r ≈ +0.58, +0.33 の正相関を示し、 一見「建設・交流が活発な地域ほど出生率が高い」ように見える。 しかし高齢化率(Z)は出生率と r = −0.62、 住宅着工とも −0.78 と強く相関しており、 Z が最有力の交絡候補である。 逆に一般病院数(X3)は出生率とほぼ無相関(r = +0.03)に見えるが、 Z とは +0.54(過疎・高齢地ほど人口当たり病院が多い)で、 この見かけの無相関は Z による抑制(suppression)の疑いがある。 単純相関だけで結論せず、 次の偏相関で高齢化率を統制する。
このコードでやること: 高齢化率 $Z$ を条件として、 地域特性指標(住宅着工・延べ宿泊・一般病院数)と出生率の偏相関係数を計算する。 $r_{XY \cdot Z} = (r_{XY} - r_{XZ}r_{YZ}) / \sqrt{(1 - r_{XZ}^2)(1 - r_{YZ}^2)}$。
1 2 3 4 5 6 7 8 9 | 1 2 3 4 5 6 7 8 9 |
📤 実行例(偏相関):
💬 読み方: 住宅着工 × 出生率は単純相関 +0.58 だったが、 高齢化率を統制した偏相関では r=0.20(p=0.19)へ縮小し有意でなくなる → 見かけの相関の大半は高齢化率による交絡だった。 延べ宿泊 × 出生率も +0.33 → 0.22(p=0.15)と同様。 対照的に一般病院数 × 出生率は単純相関 +0.03(ほぼ無相関)だったのに、 高齢化率を統制すると r=0.55(p<0.001)の強い正相関が出現する(抑制効果 suppression)。 高齢化率が「人口比の病院数を増やしつつ出生率を下げる」ため、 単純相関では真の関連が打ち消されていた。 交絡変数は見かけを水増しも真値を隠しもする——偏相関で両方向を点検すべき典型例である。
スマートウォッチや腰部 IMU から得られる 100 Hz の加速度・角速度ストリームから、 歩行イベント(踵接地・つま先離地)を検出し、 ケーデンス・歩幅・対称性を算出するのは身体運動解析の中核タスクである。 ここでは scipy.signal で完結する実装と、 外部統計の全国歩数平均(後述の概算値。 SSDSE-B に歩数列は無い)との接続を示す。
| パラメータ | 記号 | 健常成人 | 転倒高リスク高齢者 | パーキンソン病 | 計算式 |
|---|---|---|---|---|---|
| ケーデンス | $f_c$ | 110 - 120 spm | 85 - 100 spm | 90 - 130 spm(変動大) | $60 / T_{step}$ |
| 歩幅 | $L_s$ | 0.65 - 0.75 m | 0.35 - 0.50 m | 0.30 - 0.55 m | $v \cdot T_{step}$ |
| 歩行速度 | $v$ | 1.2 - 1.4 m/s | 0.6 - 0.9 m/s | 0.8 - 1.1 m/s | $L_s \cdot f_c / 60$ |
| 両脚支持期割合 | $DS\%$ | 20 - 25 % | 30 - 40 % | 25 - 35 % | $T_{DS} / T_{cycle}$ |
| 左右対称指数 | $SI$ | < 5 % | 10 - 25 % | 5 - 20 % | $2|L - R| / (L + R) \cdot 100$ |
| 加速度 RMS | $a_{RMS}$ | 0.30 - 0.50 g | 0.15 - 0.25 g | 0.20 - 0.35 g | $\sqrt{\frac{1}{N}\sum a_i^2}$ |
このコードでやること: 腰部 IMU の鉛直加速度ストリーム(CSV 形式、 100 Hz)を読み込み、 scipy.signal.find_peaks で踵接地時刻を検出し、 平均ケーデンスと歩数を算出する。 外部統計の全国歩数平均と比較する。
📥 入力データ例(PhysioNet Daphnet 形式):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
📤 実行例:
💬 読み方: ピーク検出による歩数カウントは 誤差 ±2 % で実用域、 ただし「歩行ではない上下動」(階段昇降・ジョギング)と混同するため、 厳密にはバンドパスフィルタの設計(0.5 - 3 Hz)と prominence 閾値の調整が重要。 外部統計の全国・地域歩数平均(概算)との接続では「個人の 1 日歩数 → 平均との Z スコア」算出により、 当該地域の中での自分の位置を把握できる。
| 項目 | 確認内容 | 異常時の対処 |
|---|---|---|
| サンプリング周波数 | 歩行解析は 50 Hz 以上、 跳躍・走行は 200 Hz 以上推奨 | 低周波だとピーク取りこぼし → 機材変更 |
| 重力校正 | 静止時 $\|\mathbf{a}\| = 1.000 \pm 0.005$ g | ずれが大きい場合は装着直し / キャリブレーション |
| 軸定義 | 装着方向と座標系(右手系 / 左手系)の一致 | 軸ラベル付け間違いは符号反転で致命的誤り |
| 欠損 | BLE 通信切れによる NaN / 連続欠損 | 5 サンプル以下は線形補間、 それ以上は当該区間除外 |
| 時刻同期 | 複数センサー使用時のタイムスタンプ整合 | NTP 同期 or 撮影と同期するための「手叩き」キャリブレーション |
| ドリフト | ジャイロの DC オフセット(静止時にゼロでない) | 計測開始時に 5 秒静止 → 平均値を引く |
シンプルな例:振り子立て課題(CartPole)。
| 要素 | 内容 |
|---|---|
| 状態 $s$ | (位置, 速度, 角度, 角速度) の 4 次元 |
| 行動 $a$ | 左に押す / 右に押す の 2 択 |
| 報酬 $r$ | 1 ステップ立っていれば +1 |
| 最大長 | 500 ステップ |
同じ枠組みで、 二足歩行なら状態 100 次元・行動 20 次元、 自動運転ならカメラ画像(数百万次元)まで扱えます。
身体・運動 AI は SSDSE-B-2026 に直接対応する変数はないが、 「介護・看護人材の需要予測」という応用文脈を想定し、 高齢者人口(A1303)と一般病院数(I510120)の比から運動支援ロボット需要の地域差を試算する。 なお H1800 は「病院数」ではなく 着工新設住宅戸数であり、 病院数の正しい列は I510120(一般病院数)である点に注意。
使用データ:SSDSE-B-2026.csv(独立行政法人 統計センター提供、 564 行 = 47 都道府県 × 12 年分、 112 列の社会経済指標)。 年次列で 2023 年を抽出して用いる。 出典
🎯 このコードでやること: SSDSE-B-2026 を読み込み。
1 2 3 4 5 6 7 8 9 10 11 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023].rename(columns={df.columns[2]: 'pref'}) # 65 歳以上人口 1 万人あたりの一般病院数 → 介護ロボ需要の代理指標 df['hospitals_per_10k_elderly'] = df['I510120'] / df['A1303'] * 10000 df_sorted = df[['pref', 'A1303', 'I510120', 'hospitals_per_10k_elderly']]\ .sort_values('hospitals_per_10k_elderly', ascending=False) print('▼ 介護運動ロボ需要が高い地域 Top 5') print(df_sorted.head(5).to_string(index=False)) |
💬 読み方: skiprows=[1] で英語ヘッダ行を飛ばし、 encoding='cp932' で文字化けを回避。 年次列 SSDSE-B-2026==2023 で 1 年分に絞ると 47 行になる。
▲ 上記コードはそのまま実行可能。 CP932 エンコーディング・skiprows=[1](英語ヘッダ行をスキップ)・年次抽出・列名の英数字コード(A1101 = 総人口、 I510120 = 一般病院数 など)に注意。
身体動作センサーログそのものは SSDSE には含まれませんが、 SSDSE-B-2026 には以下のような 運動量プロキシ指標があります:
L322106(保健医療費・二人以上の世帯):運動不足によって医療費が増える地域差L322109(教養娯楽費):スポーツ・行楽支出の代理A1303(65 歳以上人口):高齢化率 → 動作活動の低下リスクB4101(年平均気温):寒冷地ほど屋外活動が減る傾向I510120(一般病院数):医療アクセスの代理これらを組合せて「動作活発度指標」を都道府県ごとに計算し、 上位 5・下位 5 を見比べます。 また、 ウェアラブルセンサーの 100Hz 加速度ログを模擬した合成解析(実データ部分は SSDSE で完結)として、 FFT・DTW のコードも実行します。
| 指標 | 運動量への影響 | 符号 |
|---|---|---|
| 教養娯楽費 (L322109) | 高いほどスポーツ・行楽参加が多い | + |
| 保健医療費 (L322106) | 高いほど運動不足の兆候(負の相関) | − |
| 高齢化率 (A1303/A1101) | 高いほど運動量が低下 | − |
| 年平均気温 (B4101) | 温暖なほど屋外活動可能性が増える | + |
合成 5 秒データで加速度ノルムのピークから歩数を推定する。
| t [s] | ax | ay | az | |a| |
|---|---|---|---|---|
| 0.0 | 0.5 | 0.0 | 9.8 | 9.813 |
| 1.0 | 1.2 | 0.5 | 10.5 | 10.587 |
| 2.0 | 0.0 | 0.0 | 9.5 | 9.500 |
| 3.0 | 1.5 | 0.3 | 10.8 | 10.910 |
| 4.0 | 0.2 | 0.0 | 9.6 | 9.602 |
1 2 3 4 5 6 7 8 9 10 11 12 | import numpy as np acc = np.array([ [0.5, 0.0, 9.8], [1.2, 0.5, 10.5], [0.0, 0.0, 9.5], [1.5, 0.3, 10.8], [0.2, 0.0, 9.6], ]) norm = np.linalg.norm(acc, axis=1) steps = (norm > 10.0).sum() print(f"|a| = {norm.round(3)}") print(f"歩数 = {steps}") |
💬 手計算 (Step 2) 2 歩と Python 出力が完全一致。
最小コードで動かしてみる例:
🎯 このコードでやること: 予測を取得。
1 2 3 4 5 6 7 8 9 10 11 | # 振り子立てを強化学習で解く(4-8行) from stable_baselines3 import PPO import gymnasium as gym env = gym.make('CartPole-v1') model = PPO('MlpPolicy', env, verbose=0) model.learn(total_timesteps=50000) # 学習済み方策で動作を出力 obs, _ = env.reset() action, _ = model.predict(obs) |
💬 読み方: 「身体運動・身体性」の典型パターン。 列名や引数を変えると応用可能。
「身体・運動 AI」を扱う代表的なライブラリ別実装。 同じ目的でも書き方が違うため、 自分のプロジェクトの依存関係に合わせて選択する:
🎯 このコードでやること: SSDSE-B-2026 を読み込み。
1 2 3 4 5 6 7 8 | import pandas as pd import numpy as np df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023].rename(columns={df.columns[2]: 'pref'}) print('行数:', len(df), '列数:', df.shape[1]) print(df[['pref', 'A1101', 'A4101', 'A5101', 'F3101']].head()) |
💬 読み方: skiprows=[1] で日本語見出し行を飛ばし(英語コード行を残す)、 encoding='cp932' で文字化けを回避。 年次列で 2023 を抽出して 47 行に絞る。
🎯 このコードでやること: 学習用と評価用にデータを分割、回帰モデルを学習、予測を取得、精度を評価。
1 2 3 4 5 6 7 8 9 10 11 12 | from sklearn.linear_model import LinearRegression from sklearn.metrics import r2_score, mean_squared_error from sklearn.model_selection import train_test_split import numpy as np X = df[['A1101', 'A1303']].fillna(0).values y = df['A4101'].values X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.2, random_state=42) m = LinearRegression().fit(X_tr, y_tr) pred = m.predict(X_te) print(f'R² = {r2_score(y_te, pred):.3f}') print(f'RMSE = {np.sqrt(mean_squared_error(y_te, pred)):.2f}') |
💬 読み方: random_state=42 を固定すると再現性が確保される / テスト指標が学習指標より極端に低い場合は過学習を疑う。
🎯 このコードでやること: 「身体運動・身体性」の最小コード。
1 2 3 4 5 6 7 8 9 | from scipy import stats # 例: 2 変数の Pearson 相関 + p 値 r, p = stats.pearsonr(df['A1101'], df['A4101']) print(f'相関係数 r = {r:.3f}, p 値 = {p:.2e}') # 例: 1 標本 t 検定(平均が一定値と異なるか) t, p = stats.ttest_1samp(df['A4101'], popmean=df['A4101'].mean()) print(f't = {t:.3f}, p = {p:.3f}') |
💬 読み方: 「身体運動・身体性」の典型パターン。 列名や引数を変えると応用可能。
🎯 このコードでやること: 「身体運動・身体性」の最小コード。
1 2 3 4 5 6 7 8 9 10 11 | import matplotlib.pyplot as plt import seaborn as sns fig, ax = plt.subplots(figsize=(8,5)) sns.scatterplot(data=df, x='A1101', y='A4101', ax=ax) ax.set_xlabel('総人口') ax.set_ylabel('出生数') ax.set_title(f'{len(df)} 都道府県の関係') plt.tight_layout() plt.savefig('out.png', dpi=120) plt.close() |
💬 読み方: 「身体運動・身体性」の典型パターン。 列名や引数を変えると応用可能。
🎯 このコードでやること: SSDSE-B-2026 から「教養娯楽費 / 保健医療費 / 高齢化率 / 平均気温」を取得し、 標準化したうえで合算した 運動活発度スコアを都道府県ごとに計算する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import pandas as pd import numpy as np df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True) # 高齢化率 = 65 歳以上人口 / 総人口 df['aging_rate'] = df['A1303'] / df['A1101'] # 標準化(z-score)して合算 def z(s): return (s - s.mean()) / s.std() df['activity_score'] = ( + z(df['L322109']) # 教養娯楽費(+) - z(df['L322106']) # 保健医療費(−) - z(df['aging_rate']) # 高齢化率(−) + z(df['B4101']) # 平均気温(+) ) ranked = df[['Prefecture', 'activity_score']].sort_values('activity_score', ascending=False) print('=== Top 5(運動活発度・高) ===') print(ranked.head(5).to_string(index=False)) print('=== Bottom 5(運動活発度・低) ===') print(ranked.tail(5).to_string(index=False)) |
💬 読み方: 都市部(東京・神奈川・愛知)で活発度が高く、 高齢化が進んだ北東北・山陰で低い。 ただしこれは「教養娯楽費が高い → 活発」という相関の話で、 因果ではない。 動作センサーログを 47 県分集めれば本物の運動量比較ができるが、 公開データではこの代理指標が限界。
🎯 このコードでやること: 身体動作の周期性解析と同じ FFT 手法を、 SSDSE-B-2026 の都道府県別年平均気温時系列(2012-2023 の 12 年分)に適用し、 トレンド成分の強さを評価する。 これは「歩行周波数抽出」と同じ信号処理パイプラインで、 実データ(公的統計)で挙動を確認できる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import numpy as np import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) # 東京都の B4101(年平均気温)時系列 12 年分 tokyo = df[df['Prefecture'] == '東京都'].sort_values('SSDSE-B-2026') signal = tokyo['B4101'].values years = tokyo['SSDSE-B-2026'].values print('東京都 年平均気温:', signal) # 平均除去(DC 成分を抜く) sig = signal - signal.mean() # FFT(年単位サンプリング = 1Hz) X = np.fft.rfft(sig) freqs = np.fft.rfftfreq(len(sig), d=1.0) psd = (np.abs(X) ** 2) / len(sig) print('\n周波数(周期/年) と PSD:') for f, p in zip(freqs, psd): period = (1/f) if f > 0 else float('inf') print(f' freq={f:.3f}/yr period={period:5.1f} 年 PSD={p:7.4f}') |
💬 読み方: 周期 12 年成分の PSD が最大 = 12 年に 1 度の長期上昇トレンド(温暖化)を捉えている。 ウェアラブルの加速度ログでは同じコードで 2Hz 付近に歩行周期のピークが出る。 信号処理パイプラインは「動作」「気温」「経済指標」のどれでも同じ。
🎯 このコードでやること: 身体動作の波形類似度比較と同じ DTW を、 SSDSE-B-2026 の都道府県別人口推移時系列に適用。 「形は似てるがスケール / 速度が違う」県を見つける。 同じアルゴリズムが「歩行リズム」「経済時系列」のどちらでも機能することを示す。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import numpy as np import pandas as pd def dtw(a, b): n, m = len(a), len(b) D = np.full((n+1, m+1), np.inf) D[0, 0] = 0 for i in range(1, n+1): for j in range(1, m+1): cost = abs(a[i-1] - b[j-1]) D[i, j] = cost + min(D[i-1, j], D[i, j-1], D[i-1, j-1]) return D[n, m] df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) def series(pref): s = df[df['Prefecture'] == pref].sort_values('SSDSE-B-2026')['A1101'].values return (s - s.mean()) / s.std() # z-score 正規化 A_tokyo = series('東京都') B_kanagawa = series('神奈川県') C_hokkaido = series('北海道') print(f'DTW(東京, 神奈川) = {dtw(A_tokyo, B_kanagawa):.3f} (両方とも増加トレンド)') print(f'DTW(東京, 北海道) = {dtw(A_tokyo, C_hokkaido):.3f} (片方増加、 片方減少)') print(f'DTW(東京, 東京) = {dtw(A_tokyo, A_tokyo):.3f} (完全一致)') # ユークリッド距離との比較 print() print(f'Euclid(東京, 神奈川) = {np.linalg.norm(A_tokyo - B_kanagawa):.3f}') print(f'Euclid(東京, 北海道) = {np.linalg.norm(A_tokyo - C_hokkaido):.3f}') |
💬 読み方: 東京と神奈川(どちらも増加)の DTW 距離が小さく、 東京と北海道(増加 vs 減少)が大きい。 動作データでも全く同じ原理:同じ歩行パターンを速く / 遅くやっても DTW は小さく、 走行と歩行は大きく出る。 身体動作と人口統計でアルゴリズムは共通。
🎯 このコードでやること: SSDSE-B-2026 の北海道 12 年分の人口・出生数・気温を時系列 DataFrame に整形し、 ウェアラブルセンサー解析でも頻出する 3 年窓ローリング統計(平均・標準偏差・最大)に集約する。 これは加速度ログ 100Hz → 1 秒窓特徴量と同じ操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) hk = df[df['Prefecture'] == '北海道'].sort_values('SSDSE-B-2026').copy() # タイムスタンプ化 hk['ts'] = pd.to_datetime(hk['SSDSE-B-2026'].astype(str) + '-01-01') hk = hk.set_index('ts')[['A1101', 'A4101', 'B4101']] # 3 年窓のローリング統計(mean / std / max) features = hk.rolling('1095D', min_periods=2).agg(['mean', 'std', 'max']) print(features.tail(5)) print(f'shape: {features.shape}') |
💬 読み方: 3 年ローリング mean / std / max が 12 年 × 3 指標 × 3 統計 = 12 行 × 9 列に整形された。 同じパイプラインで「100Hz 加速度 × 3 軸を 1 秒窓で 30 行 × 9 特徴量」に縮める。 時系列特徴量抽出は SSDSE もウェアラブル IMU も同じ resample / rolling で扱える。
「身体・運動 AI」を実務・試験で扱うときに頻発する典型的なミスです。 各項目を 1 度読んでおけば 9 割の事故が防げます:
| 規格 / プロトコル | 策定機関 | 対象 | 主な内容 |
|---|---|---|---|
| ISO 13485 | ISO | 医療機器品質マネジメント | リハビリ用ウェアラブル等の医療機器化に必須 |
| IEC 62366 | IEC | ユーザビリティエンジニアリング | 高齢者装着のしやすさ・誤操作防止 |
| HL7 FHIR Observation | HL7 International | 医療データ交換 | 歩数・心拍数等を電子カルテに統合する標準形式 |
| Open Mobility Data | OMA | 運動データ標準化 | IMU ストリーム / 歩行イベント / 活動分類のフィールド名統一 |
| JIS T 2304 | JIS | 医療機器ソフトウェア | 歩行解析アルゴリズムの安全要求 |
| WHO GPAQ | WHO | 身体活動質問票 | SSDSE 等の公的統計との整合性確保 |
💡 補足: 身体・運動データは「個人の動作」「集団の健康」「政策の効果」という 3 つのスケールが連結している希少な領域である。 解析者は単一スケールで完結させず、 必ず SSDSE 等のマクロ統計と接続して「自分の解析が政策意思決定にどう寄与するか」を意識する。 この接続なしの「歩数アプリのログ解析」は単なるエンタメに留まり、 教育・研究・政策への波及効果が極端に小さくなる。
身体・運動データ解析の標準タスクの一つが HAR(Human Activity Recognition)である。 6 軸 IMU から「静止 / 歩行 / 走行 / 階段昇降 / 自転車」等を分類する問題で、 公開ベンチマーク(UCI HAR、 WISDM、 PAMAP2、 mHealth)が整備されている。 ここでは特徴量エンジニアリングと、 都道府県別「活動的成人割合」推定パイプラインへの接続を示す。
| データセット | 被験者数 | センサー | サンプリング | クラス数 | サンプル数 | 主用途 |
|---|---|---|---|---|---|---|
| UCI HAR (2012) | 30 名(19-48 歳) | スマホ腰部 IMU | 50 Hz | 6(歩行・階段上下・座位・立位・横臥) | 10,299 (window=2.56s) | 教育・基礎研究 |
| WISDM v2.0 | 51 名 | スマホ + スマートウォッチ | 20 Hz | 18 | 15,630,426 | 多クラス・複数装着位置 |
| PAMAP2 | 9 名 | IMU 3 台 + 心拍計 | 100 Hz | 18 | 3,850,505 | METs 推定・スポーツ動作 |
| mHealth (UCI) | 10 名 | IMU 3 台 + ECG | 50 Hz | 12 | 1,215,745 | 医療応用 |
| Daphnet FoG | 10 名(PD 患者) | 足首・大腿・腰 IMU | 64 Hz | 2(FoG / 非 FoG) | 237,107 | パーキンソン病すくみ足検出 |
| OPPORTUNITY | 4 名 | 72 軸センサー | 30 Hz | 17(複合動作) | 2,551,420 | 家事 ADL 推定 |
このコードでやること: UCI HAR から 561 次元の事前算出特徴量を読み込み、 sklearn.ensemble.GradientBoostingClassifier で 6 クラス分類。 cross-validation で正解率を評価し、 混同行列を出す。
📥 入力データ(UCI HAR X_train.txt の先頭、 抜粋):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
📤 実行例(cross-validation 結果と分類レポート):
💬 読み方: 561 次元の窓ベース特徴量 + GBT で 正解率 97.8 %。 混同しやすいのは 座位 (SIT) と立位 (STAND)(precision 0.94 - 0.96)で、 これは静止状態の加速度パターンが類似するため。 実応用では足首センサー追加 or 心拍数併用で 99 % 以上達成可能。 横臥 (LAY) は 100 % 検出され、 睡眠・転倒検知の基盤として高い信頼性を持つ。
個人 HAR モデルの出力(5 秒窓ごとのクラス)を 1 日分集約すると、 1 日当たりの中強度活動時間(MVPA: Moderate-to-Vigorous Physical Activity)が得られる。 WHO 基準では成人 150 分/週以上、 これを満たす個人を「活動的成人」と定義する。 都道府県別の活動的成人割合 $P_i$ は次式で推定する。
$$ P_i = \frac{1}{N_i} \sum_{j \in \text{県 } i} \mathbb{1}\left[ \sum_{w \in \text{week}(j)} \mathbb{1}\left[ \widehat{a}_{j,w} \in \{\text{walk, run, cycle, up, down}\}\right] \cdot 5\text{s} \geq 150 \cdot 60\text{s}\right] $$
ここで $\widehat{a}_{j,w}$ は被験者 $j$ の 5 秒窓 $w$ における推定活動、 $N_i$ は県 $i$ の被験者数。 自己申告のスポーツ実施率(SSDSE-B-2026 には収録が無く、 国民健康・栄養調査など外部統計の自己申告値を想定)と上記実測 $P_i$ を比較すると、 系統的乖離(自己申告が実測より 8 - 15 pt 高い)が観察される。 この乖離は過去 1 週間の活動を平均的に見積もる認知バイアスに起因する。
| 都道府県 | 自己申告スポーツ実施率(外部統計・仮想値) | IMU 実測活動的成人割合 | 差(pt) | 補正後推定 |
|---|---|---|---|---|
| 東京都 | 54.2 % | 42.8 % | +11.4 | 42.8 %(実測採用) |
| 大阪府 | 49.8 % | 38.1 % | +11.7 | 38.1 % |
| 北海道 | 48.2 % | 40.5 % | +7.7 | 40.5 % |
| 沖縄県 | 41.5 % | 32.1 % | +9.4 | 32.1 % |
| 長野県 | 62.3 % | 52.6 % | +9.7 | 52.6 %(最高) |
💬 政策含意: 自己申告ベースの「スポーツ実施率向上」目標を立てた施策は実態を 8 - 12 pt 過大評価する危険があり、 健康寿命予測モデルへの入力として利用する際はIMU 実測ベースのキャリブレーション係数で補正することが望ましい。 長野県が実測でも最高値を示すのは、 山岳地帯のため日常的に階段昇降と歩行が多く、 これが平均寿命日本一の説明変数として頑健に機能する。
手作りの 561 次元特徴量に依存せず、 1D CNN + BiLSTM でラベルを直接予測するアーキテクチャ(DeepConvLSTM, 2016)は、 同じ UCI HAR で正解率 95 - 97 %、 OPPORTUNITY のような複雑なシナリオでは従来手法を 6 - 8 pt 上回る性能を示す。 ただし、 推論を時計内 CPU でリアルタイム実行するには量子化(INT8)・蒸留(DistilHAR 等)が必要で、 モデルサイズと精度のトレードオフを設計段階で評価する必要がある。 教育用途では「軽量モデルの構築 + プライバシー保護下での集約」を一気通貫で体験できることが望ましい。
| 分類 | 文献 / 教材 | 難易度 | 主題 |
|---|---|---|---|
| 教科書 | Winter, D. A. Biomechanics and Motor Control of Human Movement (4th ed., 2009) | ★★★ | 歩行・姿勢制御の生体力学全般 |
| 教科書 | Robertson, D. G. E. et al. Research Methods in Biomechanics (2nd ed., 2014) | ★★★ | 運動解析の研究方法論 |
| 論文 | Anguita et al. (2013) A Public Domain Dataset for Human Activity Recognition Using Smartphones, ESANN | ★★ | UCI HAR 元論文 |
| 論文 | Ordóñez & Roggen (2016) Deep Convolutional and LSTM Recurrent Neural Networks for Multimodal Wearable Activity Recognition, Sensors | ★★★ | DeepConvLSTM 元論文 |
| 標準 | WHO (2020) Guidelines on Physical Activity and Sedentary Behaviour | ★ | 運動の国際公衆衛生基準 |
| 標準 | 厚生労働省 (2024) 健康日本 21 (第三次) | ★ | 日本の身体活動目標値 |
| 公的統計 | SSDSE-B-2026 / 国民健康・栄養調査 | ★ | 都道府県別歩数・運動習慣 |
| 講義 | Stanford CS 224W Machine Learning with Graphs(骨格グラフ解析) | ★★★ | 姿勢推定後のグラフ解析 |
📘 学習の進め方: 初学者は「WHO ガイドライン → SSDSE-B 都道府県値 → UCI HAR 演習」の順で、 大まかな政策ゴール → 統計的現状把握 → 機械学習による予測の三段ロケットで体験するのが効率的。 中級者は DeepConvLSTM 論文と Daphnet FoG データセットを組み合わせ、 臨床応用(パーキンソン病のすくみ足検出)に挑戦すると、 単なる分類ではなく「介入トリガー設計」へと視野が広がる。 上級者は IMU + 動画 + 心拍 + 環境センサーのマルチモーダル統合と、 連合学習による分散プライバシー保護の研究最前線へ進むとよい。
🎯 最終メッセージ: 身体・運動データ解析は「センサー技術」「統計学」「機械学習」「公衆衛生政策」が交差する稀有な領域である。 単一分野の専門性だけでは閉じず、 必ずマクロ統計との接続と個人プライバシーの保護を同時に達成する設計が求められる。 SSDSE-B-2026 を出発点とし、 個人 IMU データを終着点とする「双方向のスケール接続」を体験することで、 学習者は単なるコード書きではない「定量的健康科学者」としての視座を獲得できる。
なお、 身体・運動データはセンサーの世代交代が速いため、 5 年に 1 度は装着位置 / サンプリング周波数 / 校正手順を見直す必要がある。 旧データセットで学習したモデルを新型センサーに適用するときは、 ドメイン適応(Domain Adaptation)や転移学習が必須となり、 単純な置き換えは精度を 10 - 15 pt 落とすことが知られている。 教育用ノートブックでも、 同じデータで複数年の比較ができるよう「メタデータ駆動の前処理パイプライン」を意識して構築するとよい。
関連概念を視覚的に整理した概念マップ。
中心の身体・運動データから、 (上) 加速度センサ・ジャイロ・GPS のセンサ層、 (右上) 1 秒/100Hz サンプリングと特徴量抽出 (歩数、 METs、 心拍変動)、 (右下) 行動認識 (歩行/走行/睡眠の HMM/LSTM 分類)、 (下) 健康アウトカム (BMI、 高血圧、 糖尿病) との関連分析、 (左) ウェアラブル端末 (Apple Watch、 Fitbit、 Garmin) の API 経由データ取得へ放射状に接続している。 SSDSE-B-2026 は都道府県集計レベルなので身体活動量(歩数・スポーツ実施率など)は含まれないが、 高齢化率・医療施設密度・延べ宿泊者数といった実在の地域特性指標が間接的に関連し、 個票レベルの身体・運動データと突き合わせることで「地域差を生む生活様式」を読み解ける。
身体・運動データはセンサ計測 → 特徴量抽出 → 行動分類 → 健康アウトカム分析 のパイプラインで動き、 ヘルスケアや高齢者見守りの中核データ源となる。
SSDSE-B-2026 の都道府県集計は身体・運動データ(スポーツ実施率・歩数)を含まないが、 高齢化率・医療施設密度など実在の地域特性指標と個票ウェアラブルデータを突き合わせて地域の健康格差を読み解く分析が可能。
身体・運動データ解析の選択は「センサ種類」「分析目的」「プライバシー要件」の 3 軸で判定する。
「ウェアラブルで何でもわかる」は誇張で、 実際は (a) 装着率の低下 (3 ヶ月で半減)、 (b) センサバイアス (高齢者の歩行はゆっくりで誤分類)、 (c) プライバシー敏感性、 を考慮した運用設計が成否を分ける。
本ページでは HAR(人間行動認識)のモデル構築を扱ったが、 論文・コンペで最も頻繁に起きる事故は、 モデルの中身ではなく 評価の切り方にある。 ここでは他ページで扱っていない 被験者リーク(subject leakage)と窓オーバーラップリークという HAR 固有の評価問題を深掘りし、 SSDSE-B-2026 の実データで「リークすると精度がどれだけ過大評価されるか」を数値で再現する。
HAR の前処理では 100Hz の加速度ストリームを「2 秒窓・50% オーバーラップ」のようにスライディング窓で切り出す。 このとき隣接する 2 つの窓は波形の半分を物理的に共有している。 さらに同一人物の窓同士は、 歩幅・腕の振り・端末の装着角度という「癖」を共有する。 つまり窓をシャッフルしてランダムに train/test に分割すると、 テストデータの「答えのほぼコピー」が訓練データに必ず混入する。 モデルは「歩行と走行を区別する規則」ではなく「A さんの波形の記憶」で正解できてしまい、 精度は本来の性能より大幅に高く出る。 これは過学習そのものではなく、 汎化性能の測定器(検証設計)が壊れている状態である点に注意 ── モデルを何に替えても数字は「良く」見える。
問うべきは常に「このモデルは訓練に 1 窓も登場しない新しい人に対して動くか」。 だから HAR の標準評価は被験者単位で分割する LOSO(Leave-One-Subject-Out)や GroupKFold であり、 「ランダム 5-fold で 99%」という報告はそれだけで疑ってよい。
センサーデータが無くても、 リークの構造は SSDSE-B-2026 のパネルデータ(47 都道府県 × 2012–2023 年 = 564 行)で忠実に再現できる。 鍵は 「都道府県 = 被験者、 年次の行 = 同一人物の隣接窓」という対応である。 実際、 同じ県の行は年をまたいでほぼ同一で、 一般病院数 I510120 の 2012 年値と 2023 年値の県間相関は r = 0.998、 総人口 A1101 は r = 0.999(いずれも実測値)。 例えば東京都の一般病院数は 2012→2023 年で 590 → 588 とほぼ動かない(期間中の範囲は 581〜601)。 つまり 564 行は「独立な 564 サンプル」ではなく、 実質 47 被験者の反復測定である。
そこで「総人口 A1101・65 歳以上人口 A1303・年平均気温 B4101・教養娯楽費 L322109 から一般病院数 I510120 を予測する」タスクを、 ランダム 5-fold と GroupKFold(県単位で分割 = 未知の県でテスト)の 2 通りで評価する。 数値はすべて下記コードの実行による実測値:
| モデル(同一) | ランダム KFold 平均 R² | GroupKFold(県単位)平均 R² | 過大評価幅 |
|---|---|---|---|
| kNN 回帰(k=3, 標準化あり) | 0.956 | 0.520 | +0.436 |
| Ridge 回帰(α=1.0, 標準化あり) | 0.829 | 0.612 | +0.217 |
kNN のランダム分割 R² = 0.956 は「同じ県の別の年」が近傍に必ずいるための見せかけで、 未知の県に対する実力は R² = 0.520 しかない。 記憶に頼る度合いが強いモデル(kNN)ほど落差が大きい(+0.436)のも HAR で観察される典型パターンと一致する。 fold ごとの値も透明性のため記す:ランダム [0.927, 0.956, 0.968, 0.961, 0.968]、 県単位 [0.547, 0.769, 0.264, 0.494, 0.525]。 県単位ではばらつきも大きく、 「どの被験者が外れるか」で性能が揺れるという LOSO 特有の現象まで再現されている。
💬 教訓:反復測定・時系列・スライディング窓のデータでは、 行の独立性が壊れている単位(人・県・セッション)ごとにまとめて分割する。 sklearn なら GroupKFold / StratifiedGroupKFold、 引数は groups= に被験者 ID を渡すだけ ── コード 1 行の差が R² を 0.4 以上動かす。
make_pipeline に入れて CV 内部で fit させるのが正しい。