ワークアウトの停滞を時系列予測で予測する方法(Python)
単純なワークアウト記録を超えます。Python、Pandas、Prophetを使った時系列予測で、将来の筋力向上を予測し、ワークアウトのプラトー事前に対処する方法を学びましょう。
このページの内容
すべての方にある程度の経験があると思います。あなたは積極的に健身房に通い、バーベルに重量を加え毎週ますます強くなっていると感じているとします。そして、突然、あなたの進捗が停滞します。かつて感じられていた重量が不可能に重いものに変わり、何週間も同じ数値で足踏みすることになります。このフラストレーションを伴う体験は、トレーニングの停滞期(プラトー)として知られており、あらゆるレベルの経験を持つ筋力トレーニング者にとって一般的な障壁です。
しかし、プラトーが来る前にそれを予測することができればどうでしょうか?この詳細なチュートリアルでは、Pythonで時系列予測を使用して将来の筋力向上を予測する方法、そして更重要的是、いつプラトーに達する可能性が高いかを特定する方法を探索します。このチュートリアルを終える頃には、トレーニング進捗を理解するための実用的でデータに基づくアプローチが手に入ります。
ベンチプレスの1RM(最大反復一回重量)を予測し、予測を分析して利益が横ばいになると予想される時期を正確に特定するモデルを構築します。これにより、ボリューム、強度、または必要なデロード(減量期)の調整など、トレーニングプログラムの積極的に変更を行うことができます。
これは開発者にとって関係があります。なぜなら、データサイエンスの原則の実用的で現実世界での応用例だからです。自分で生成できる具体的なデータを扱い、コードが個人的なフィットネスの目標に与える直接的な影響を見ることができます。
前提条件:
- Pythonとpandasライブラリの基本理解。
- 機械学習の基本概念への精通。
- Python(3.6以上)とJupyter Notebookまたはお気に入りのIDE。
- 次のライブラリがインストールされていること:
pandas、numpy、plotly、prophet。
問題の理解
データ用語では、トレーニングの停滞期とは、進捗率(筋力曲線の傾き)がゼロに近づく期間です。プラトーを「感じる」ことはできますが、より厳密なアプローチは、進捗を時系列でモデル化し、パフォーマンスが停滞する可能性が高い時期を予測することです。
ノートやスプレッドシートでワークアウトを追跡する従来の方法は、行ったことの記録には最適ですが、後ろ向きです。时系列予測により、先を見通すことができます—過去のデータに基づく将来予測が可能です。
Facebookのコアデータサイエンスチームが開発した人気の時系列予測ライブラリであるProphetを使用します。Prophetは、欠損データ(誰しも健身房を休むことがあります)に対して堅牢であり、トレンドや季節性を適切に処理し、予測を初めて使用する人にとっても比較的使いやすい)など、このタスクに適しています。
前提条件
始める前に、環境をセットアップしましょう。必要なPythonライブラリをインストールする必要があります。
pip install pandas numpy prophet plotly
- pandas & numpy:データ操作と数値演算用。
- prophet:使用する予測ライブラリ。
- plotly:インタラクティブな可視化の作成用。
ステップ1:合成ワークアウトデータセットの生成
現実世界のワークアウトログは乱雑である可能性があります。このチュートリアルでは、進捗の期間とプラトーに続く筋力トレーニング者の旅をモデル化する、きれいで合成のデータセットを作成します。これにより、モデルの動作更容易に見ることができます。
何をしているか
2つの列を持つpandas DataFrameを作成します:ds(ワークアウトの日付)とy(追跡している指標)。この例では、yはベンチプレスの推定1RMです。1RMは、レップ数が変わっても進捗の一貫した尺度を提供するため、筋力を追跡するのに最適な指標です。一般的なEpley公式を使用して推定します:1RM = 重量 × (1 + レップ数 / 30)。
実装
このデータを生成するPythonスクリプトを書きましょう。数ヶ月間、週3回トレーニングする筋力トレーニング者をシミュレートします。
# src/data_generation.py
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
def generate_workout_data():
"""
進捗とプラトーをシミュレートする合成ワークアウトデータセットを生成します。
"""
start_date = datetime(2024, 1, 1)
# 週3回で9ヶ月間のトレーニングをシミュレート
dates = pd.to_datetime([start_date + timedelta(days=i*2.33) for i in range(108)])
# 初期筋力
initial_1rm = 135 # ポンド
# フェーズ1:初心者利益(最初の4ヶ月)- 迅速で一貫した進捗
newbie_gains_period = int(108 * 0.45)
newbie_gains = np.linspace(0, 55, newbie_gains_period)
# フェーズ2:中級者の利益(次の3ヶ月)- 遅い進捗
intermediate_period = int(108 * 0.30)
intermediate_gains = np.linspace(5, 15, intermediate_period)
# フェーズ3:プラトー(最後の数ヶ月)- 最小限の利益
plateau_period = int(108 * 0.25)
plateau_gains = np.random.uniform(0, 1.5, plateau_period)
# 利益を組み合わせてノイズを追加
total_gains = np.concatenate([newbie_gains, intermediate_gains, plateau_gains])
noise = np.random.normal(0, 2, len(dates))
# 経時的な推定1RMを計算
estimated_1rm = initial_1rm + total_gains + noise
df = pd.DataFrame({'ds': dates, 'y': estimated_1rm})
df['y'] = df['y'].round(1)
return df
workout_df = generate_workout_data()
print(workout_df.head())
print("--- 最後の5件のエントリ ---")
print(workout_df.tail())
仕組み
このスクリプトは、ワークアウトのタイムラインを作成し、筋力トレーニング者の旅路の3つの異なるフェーズをシミュレートします:
- 初心者利益:迅速で直線的な筋力増加の期間。
- 中級者の利益:筋力トレーニング者がより経験豊かになるにつれて進捗が遅くなります。
- プラトー:筋力向上が最小限になり、変動します。
データをよりリアルにするためにランダムなノイズを追加します。健身房での「良い日」と「悪い日」は現実です!
期待される出力
ds y
0 2024-01-01 00:00:00 133.5
1 2024-01-03 07:55:12 136.9
2 2024-01-05 15:50:24 138.8
3 2024-01-07 23:45:36 139.7
4 2024-01-10 07:40:48 141.4
--- 最後の5件のエントリ ---
ds y
103 2024-09-02 15:50:24 206.5
104 2024-09-04 23:45:36 205.8
105 2024-09-07 07:40:48 207.2
106 2024-09-09 15:36:00 206.0
107 2024-09-12 00:00:00 206.8
ステップ2:履歴データの可視化
予測を開始する前に、パターンを理解するためにデータを可視化することが重要です。
実装
# src/visualization.py
import plotly.express as px
def plot_historical_data(df):
fig = px.line(df, x='ds', y='y', title='Bench Press 1RM Progression Over Time',
labels={'ds': 'Date', 'y': 'Estimated 1RM (lbs)'})
fig.update_layout(template="plotly_white")
fig.show()
plot_historical_data(workout_df)
仕組み
これは、シミュレートされた筋力トレーニング者の進捗を示すインタラクティブなプロットを生成します。最初の急激な曲線、平坦化、そして最終的なプラトーを明確に確認できます。
(プロットの外観のサンプル画像)
ステップ3:予測モデルの構築とトレーニング
さあ、 excitingな部分です!Prophetを使用して予測を作成します。Prophetはデータが特定の形式であることを要求します:日付列はds、値列はyと名付けられている必要があり、これはすでに完了しています。
何をしているか
Prophetモデルをインスタンス化し、履歴データに合わせてフィットさせ、予測を保持するための「未来」DataFrameを作成します。
実装
# src/forecasting.py
from prophet import Prophet
# モデルを初期化
# changepoint_prior_scaleはトレンドの柔軟性を調整するのに役立ちます。
# 値が高いほど、トレンドにより柔軟になります。
model = Prophet(changepoint_prior_scale=0.5, yearly_seasonality=False, weekly_seasonality=True, daily_seasonality=False)
# モデルにデータをフィットさせる
model.fit(workout_df)
# 将来予測用のDataFrameを作成(例:次の3ヶ月)
future = model.make_future_dataframe(periods=90)
# 予測を生成
forecast = model.predict(future)
# 予測の最後の数行を表示
print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail())
仕組み
Prophet(...):Prophetモデルのインスタンスを作成します。ワークアウトスケジュールは多くの場合週次のパターンがあるため、週次季節性を有効にしました。changepoint_prior_scaleを増加させ、急速な成長からプラトーへのトレンドの変化をより適切にキャプチャできるようにしました。model.fit(workout_df):モデルが履歴データからパターンを学習する場所です。make_future_dataframe(periods=90):Prophetは90日間延長したDataFrameを作成します。model.predict(future):これは予測(yhat)と不確実性区間(yhat_lower、yhat_upper)で未来のDataFrameを入力します。
期待される出力
ds yhat yhat_lower yhat_upper
202 2024-12-07 19:12:00 210.034785 205.860111 214.364426
203 2024-12-08 19:12:00 209.689408 205.158756 213.784411
204 2024-12-09 19:12:00 209.914285 205.479532 214.072972
205 2024-12-10 19:12:00 210.158564 205.795817 214.394158
206 2024-12-11 19:12:00 210.228532 205.908851 214.469447
ステップ4:予測の分析によるプラトーの予測
予測があることは素晴らしいですが、目標はプラトーを特定することです。プラトーは、進捗の変化率がゼロに近づくときに発生します。Prophetは、予測内のtrend成分を提供しており、これを分析できます。
何をしているか
予測とそのコンポーネントを可視化します。次に、進捗が停滞する時期を定量的に特定するために、予測されたトレンドの日次変化率を計算します。
実装
# src/analysis.py
from prophet.plot import plot_plotly
# 予測をプロット
fig1 = model.plot(forecast)
# インタラクティブなバージョンを使用
# fig1_interactive = plot_plotly(model, forecast)
# 予測コンポーネントをプロット(トレンドと季節性)
fig2 = model.plot_components(forecast)
# --- プラトー検出 ---
# トレンドの日次変化を計算
forecast['trend_change'] = forecast['trend'].diff()
# トレンドの変化が無視できるようになる日付を特定(例:1日あたり0.1ポンド未満)
plateau_start_date = forecast[forecast['trend_change'] < 0.1].iloc[0]['ds']
print(f"潜在的なプラトーは約次から始まると予測されています:{plateau_start_date.date()}")
# プラトー用に予測プロットにマーカーを追加
import matplotlib.pyplot as plt
# プロットから図と軸を取得
ax = fig1.gca()
# プラトーの開始を示す垂直線を追加
ax.axvline(plateau_start_date, color='r', linestyle='--', lw=2)
ax.text(plateau_start_date, workout_df['y'].min(), ' Plateau Predicted', color='r')
plt.show() # プラトー線を含むプロットを表示
仕組み
Prophetのplot関数は予測を可視化することを容易にします。黑点は実際のデータを示し、濃い青線は予測(yhat)を示し、薄い青の領域は不確実性区間を示します。
プラトー検出の鍵はforecast['trend'].diff()を計算することです。これにより、根底にある筋力トレンドの日次変化が得られます。次に、この変化が小さな閾値(この場合は0.1ポンド)を下回る最初の日期を見つけます。これが予測されるプラトーの始まりです。予測プロットに垂直線として追加すると、変更が必要な時期の強力な視覚的な指標が得られます。
すべてをまとめる
履歴データ、予測、予測されたプラトーポイントを1つのグラフで完全な図を確認しましょう。プロットの赤い破線は、モデルが向上が停止すると予測する正確な時期を示します。
(赤いプラトー線を含む予測プロットの外観のサンプル画像)
この可視化は非常に強力です。過去の進捗と、将来の進捗の統計的に裏付けられた予測(停滞のポイントを含む)を見ることができます。
代替アプローチ
- ARIMA:時系列予測用の別の強力なモデルクラスは、ARIMA(自己回帰和分移動平均モデル)です。ARIMAモデルは 매우 효과적일 수 있지만、パラメータ(p、d、q)を正しく調整するにはより多くの統計的知識 часто требывается。Prophetは一般的により自動化されており、初心者に易于使用です。
- LSTMニューラルネットワーク:ワークアウトデータにより複雑で非線形のパターンについては、長期短期記憶(LSTM)ネットワークを調べることができます。これは再帰型ニューラルネットワークの一種です。ただし、これには著しく多くのデータが必要であり、実装はかなり複雑になります。
結論
筋力進行を予測し、更重要的是、ワークアウトプラトーの開始を予測するために、時系列モデルを正常に構築しました。予測トレンドの変化率を分析することで、トレーニングを調整する必要があるというデータに基づいた事前警告を取得できます。
これは始まりに過ぎません。この同じ方法論を他のエクササイズに適用し、ワークアウト容量などの異なる指標を追跡したり、睡眠の質や1日のカロリー摂取量などの外部要因(Prophetの回帰因子)を組み込んでより精巧なモデルを構築したりできます。
それでは、ワークアウトの記録を始めましょう!Pythonとデータサイエンス、少しの努力で、フィットネスの旅を次のレベルに引き上げることができます。✨
リソース
- Prophet Official Documentation
- A Guide to Time Series Forecasting with Prophet in Python 3
- Time Series Forecasting with ARIMA Models in Python
クイックリファレンス
| 側面 | 主要情報 |
|---|---|
| トピック | 開発 |
| 関連性 | 患者教育と認識 |
| 行動 | 医療サービス提供者と相談してください |
| 頻度 | ケアチームのおすすめに応じて |
| 証拠 | 現在の臨床ガイドラインに基づいています |
よくある質問
Q:これが自分に適用されるかどうかはどうやってわかりますか? A:個人的な病歴と家族歴について医療サービス提供者と相談し、個々のリスク要因を評価し、適切な次のステップを決定してください。
Q:医師に何と聞けばよいですか? A:良い質問には次のようなものがあります:「私の結果はどういう意味ですか?」「私のオプションは何ですか?」「どのような生活習慣の変更が有帮助ですか?」「いつフォローアップする必要がありますか?」
Q:帮助できる生活习惯の変更はありますか? A:ほとんどの健康状態は、基本的な対策から利益を得ます:バランスの取れた栄養、定期的な運動(週150分以上)、質のいい睡眠(7〜9時間)、ストレス管理、タバコの回避。
医療に関する免責事項
この記事は教育目的のみを目的としており、医学的アドバイスを提供ものではありません。健康、治療、またはケアに関する決定する前に、常に資格のある医療サービス提供者にご相談ください。個々の状況は異なり、一人に適切なことが別の人には適切でない場合があります。
救急医療の状況にある場合は、直ちに911(またはお使いの地域の緊急番号)に電話してください。