본문 바로가기
Python Library/HeartPy

[HeartPy] PPG 신호 분석

by goatlab 2022. 8. 24.
728x90
반응형
SMALL

PPG 신호 분석

 

HeartPy를 사용하여 일반 PPG 신호를 분석하는 방법을 알아본다. 이를 위해 HeartPy와 함께 패키지된 예제 데이터 세트를 사용한다.

 

# First let's import
import heartpy as hp
import matplotlib.pyplot as plt

# first let's load the clean PPG signal
data, timer = hp.load_exampledata(0)

# and visualise
plt.figure(figsize=(12,4))
plt.plot(data)
plt.show()

 

HeartPy는 제공된 데이터 세트를 로드할 수 있는 함수 load_exampledata()와 함께 제공된다. 튜플 (데이터, 타이머)을 반환한다. 여기서 'timer'는 타이머 열 (ms 또는 datetime)이다. 사용 가능한 타이머 열이 없으면 튜플이 반환되지만 타이머 배열은 비어 있다.

HeartPy에는 세 가지 데이터 세트가 포함되어 있다.

 

0 : 100.0Hz로 샘플링된 짧고 매우 깨끗한 PPG 신호
1 : 약간 더 긴 (~2분) PPG 신호, 첫 번째 세 번째 신호 누락, 나머지 신호에서 랜덤 noise spike
2 : 검지의 펄스 센서와 Arduino를 사용하여 운전 시뮬레이터에서 주행하는 동안 '야생에서' 기록된 긴 (~11.5분) PPG 신호

 

hp.process를 실행하면 working_data (피크 위치 및 피크 피크 간격과 같이 액세스할 수 있는 작업 데이터 포함)와 measure (계산된 출력 측정 포함)의 두 가지 dict가 반환된다.

문서에서 이것을 'wd'와 'm'으로 줄인다.

 

# run the analysis
wd, m = hp.process(data, sample_rate = 100.0)

 

Heartpy에는 시각화 기능을 하는 hp.plotter(wd, m) 기능이 포함되어 있다. 함수에서 working_data와 measure dict를 지정해야 한다.

hp.plotter(wd, m)를 호출하기 전에 matplotlib에 그림 크기 같은 매개변수를 지정하는 경우 지정된 그림 크기가 사용된다.

 

# set large figure
plt.figure(figsize=(12,4))

# call plotter
hp.plotter(wd, m)

# display measures computed
for measure in m.keys():
    print('%s: %f' %(measure, m[measure]))

bpm: 58.898848
ibi: 1018.695652
sdnn: 65.760061
sdsd: 34.866925
rmssd: 64.737231
pnn20: 0.863636
pnn50: 0.409091
hr_mad: 40.000000
sd1: 45.758077
sd2: 82.926832
s: 11921.000816
sd1/sd2: 0.551789
breathingrate: 0.161095

 

두 번째 포함된 데이터 세트로 이동하여 살펴본다.

 

data, timer = hp.load_exampledata(1)

plt.figure(figsize=(12,4))
plt.plot(data)
plt.show()

 

이것은 의도적으로 만든 더 까다로운 신호이다. 센서를 장착하기 전과 장착하면서 기록을 시작했기 때문에 처음에는 신호가 없다. 신호가 시작된 후 녹화 중에 센서를 강제로 움직여서 노이즈가 몇 번 급증한다. 이는 참가자가 'in the wild'을 기록할 때 발생할 수 있는 상황을 모방하고, 실수로 센서 케이블을 잡아당기는 경우에도 마찬가지이다.

HeartPy는 이러한 종류의 것을 상자에서 꺼낼 수 있도록 설계되었다.

 

sample_rate = hp.get_samplerate_mstimer(timer)

wd, m = hp.process(data, sample_rate)

# plot
plt.figure(figsize=(12,4))
hp.plotter(wd, m)

# display measures computed
for measure in m.keys():
    print('%s: %f' %(measure, m[measure]))

bpm: 62.376304
ibi: 961.903744
sdnn: 64.613519
sdsd: 29.871930
rmssd: 57.069746
pnn20: 0.797297
pnn50: 0.486486
hr_mad: 47.010333
sd1: 40.344402
sd2: 81.621935
s: 10345.227446
sd1/sd2: 0.494284
breathingrate: 0.155994

 

sample_rate는 타이머 열(ms 값)에서 계산되었다. 어떤 sample_rate로 신호가 샘플링되었는지 몰랐기 때문에 이것은 사전에 중요하다. 모든 측정은 표본 비율을 아는 것에 달려 있다.

HeartPy는 ms-timer를 기반으로 샘플링 속도를 계산하는 hp.get_samplate_mstimer()와 datetime 값을 기준으로 sample_rate를 계산하는 hp.get_samplate_datetime()의 두 가지 함수로 제공된다.

 

이제 datetime 문자열을 사용하여 시간을 인코딩하는 'in the wild' 기록를 살펴본다.

 

data, timer = hp.load_exampledata(2)

print(timer[0])
2016-11-24 13:58:58.081000

 

샘플링 속도를 계산할 때 get_samplate_datetime() 문자열 형식을 지정해야 한다 (기본적으로 HH:MM:SS.ms).

 

sample_rate = hp.get_samplerate_datetime(timer, timeformat='%Y-%m-%d %H:%M:%S.%f')

print('sample rate is: %f Hz' %sample_rate)
sample rate is: 100.419711 Hz
wd, m = hp.process(data, sample_rate, report_time = True)

# plot
plt.figure(figsize=(12,4))
hp.plotter(wd, m)

# let's zoom in on a bit
plt.figure(figsize=(12,4))
plt.xlim(20000, 30000)
hp.plotter(wd, m)

# display measures computed
for measure in m.keys():
    print('%s: %f' %(measure, m[measure]))
Finished in 0.248689 sec

bpm: 97.325149
ibi: 616.490194
sdnn: 57.916589
sdsd: 30.173744
rmssd: 38.181375
pnn20: 0.320281
pnn50: 0.086345
hr_mad: 29.874613
sd1: 26.997110
sd2: 75.178572
s: 6376.189507
sd1/sd2: 0.359106
breathingrate: 0.258103

 

https://github.com/paulvangentcom/heartrate_analysis_python/blob/master/examples/1_regular_PPG/Analysing_a_PPG_signal.ipynb

 

GitHub - paulvangentcom/heartrate_analysis_python: Python Heart Rate Analysis Package, for both PPG and ECG signals

Python Heart Rate Analysis Package, for both PPG and ECG signals - GitHub - paulvangentcom/heartrate_analysis_python: Python Heart Rate Analysis Package, for both PPG and ECG signals

github.com

 

728x90
반응형
LIST