はじめに
LLMにブログで何が足りていないか聞いてみたら、可視化の部分で説明不足が多いというフィードバックを得たので、生活リズムの可視化・定量化を例として記事にしてみたいと思います。
データの可視化や定量化指標の作成を簡単に表現してみたという記事です。
皆さん生活リズム整ってますか?
目的
今回の目的は、生活リズムがどれだけ整っているか、可視化して数値化してみるという試みをします。
取得データ
1時間のうち起きている時間を1、寝ている時間を0としてデータをとります。
0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 .....
のように単なる1と0の羅列のデータになります。
このデータに意味を持たせていきます。
規則的、正常なリズム、異常なリズムの3パターン用意する事にしました。
処理
可視化
まず、可視化です。
とりあえず一日24時間なので、24時間ごとに区切って、カラーマップにしてみます。
白色が起きている時間になっています。
これだけで、生活リズムが一目瞭然ですね。
数値化
ここからこのリズムの乱れを数値化してみたいと思います。
各時間ごとに平均と標準偏差(どのくらいデータがばらついているか)を計算してみました。
黒線が平均値になっていて、起きている確率になります。
そして、黒線の上下についているバーが標準偏差の大きさとなっています。
規則的なものは完全に標準偏差が0に、正常なリズムでは朝と夜にのみばらついていて、異常なリズムでは、どの時間でもデータがばらついている事がわかります。
このグラフを見てここでは、分散の平均値を取得してみました。
規則的:0.0
正常 :0.07358011472052108
異常 :0.43742635648567135
どうでしょう、異常時だと数値が、高くなる事がわかります。
一か月毎とかに計測して、計算していくとどの程度、リズムが乱れているか、管理できると思います。
さいごに
生活リズムを例にとって、こんな感じの研究していますという紹介でした。
数値化の良し悪しってありますけどね。
実際の可視化や定量化は、文脈を考えてやる必要があり、図を使った文脈の可視化なんかもしたいと思っています。
ちなみに今回のものは、思いつきで適当に作った指標なので、研究データ等はないと思います。
マニアックかと思いますが、ご興味あれば質問やご連絡ください。
(おまけ)コード
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib_fontja
np.random.seed(0)
days = 30
hours = 24
def generate_life_pattern(type_name):
data = []
for d in range(days):
if type_name == "regular":
sleep_start = 23
sleep_end = 7
elif type_name == "slightly_irregular":
sleep_start = (23 + np.random.choice([-1, 0, 1])) % 24
sleep_end = (7 + np.random.choice([-1, 0, 1])) % 24
else: # highly_irregular
sleep_start = np.random.randint(0, 24)
sleep_length = np.random.randint(5, 9)
sleep_end = (sleep_start + sleep_length) % 24
row = []
for h in range(hours):
if sleep_start < sleep_end:
asleep = sleep_start <= h < sleep_end
else:
asleep = h >= sleep_start or h < sleep_end
row.append(0 if asleep else 1)
data.append(row)
return pd.DataFrame(data, columns=[f"h{h}" for h in range(hours)])
regular = generate_life_pattern("regular")
slightly = generate_life_pattern("slightly_irregular")
irregular = generate_life_pattern("highly_irregular")
print(regular.head())
print(slightly.head())
print(irregular.head())
print(np.array(regular).flatten())
print(np.array(slightly).flatten())
print(np.array(irregular).flatten())
plt.figure(figsize=(10,4))
plt.suptitle('生活リズム')
plt.axis('off')
plt.subplot(1,3,1)
plt.title('規則的')
sns.heatmap(regular, cbar=False)
plt.xlabel('時間')
plt.ylabel('日にち')
plt.subplot(1,3,2)
plt.title('正常なリズム')
sns.heatmap(slightly, cbar=False)
plt.xlabel('時間')
plt.ylabel('日にち')
plt.subplot(1,3,3)
plt.title('異常なリズム')
sns.heatmap(irregular, cbar=False)
plt.xlabel('時間')
plt.ylabel('日にち')
plt.tight_layout()
plt.figure(figsize=(10,4))
plt.suptitle('生活リズム')
plt.axis('off')
plt.subplot(1,3,1)
plt.title('規則的')
r_mean = np.mean(regular,axis=0)
r_std = np.std(regular,axis=0)
plt.errorbar(range(24),r_mean, r_std,capsize=5, fmt='-', markersize=3, ecolor='black', markeredgecolor = "black", color='k')
plt.xlabel('時間')
plt.ylim([-0.2,1.4])
plt.subplot(1,3,2)
plt.title('正常なリズム')
s_mean = np.mean(slightly,axis=0)
s_std = np.std(slightly,axis=0)
plt.errorbar(range(24),s_mean, s_std,capsize=5, fmt='-', markersize=3, ecolor='black', markeredgecolor = "black", color='k')
plt.xlabel('時間')
plt.ylim([-0.2,1.4])
plt.subplot(1,3,3)
plt.title('異常なリズム')
i_mean = np.mean(irregular,axis=0)
i_std = np.std(irregular,axis=0)
plt.errorbar(range(24),i_mean, i_std,capsize=5, fmt='-', markersize=3, ecolor='black', markeredgecolor = "black", color='k')
plt.xlabel('時間')
plt.ylim([-0.2,1.4])
plt.tight_layout()
plt.show()
print(f"規則的:{np.mean(r_std)}")
print(f"正常 :{np.mean(s_std)}")
print(f"異常 :{np.mean(i_std)}")
コードは GitHub に置いてあります:

