1. Intro
애플 워치는 사용자의 신체에서 발생하는 다양한 정보를 수집 및 가공하여 우리에게 제공하고 있습니다.
가공된 정보를 확인하는 것도 좋지만, 직접 가져와서 학습시켜보는 것도 재미있을 것 같아서 일단 데이터를 추출하고 정리해보았다.
2. 애플 워치에서 fitness data 가져오기
애플 워치에서 데이터를 가져오는 방법에 대한 자세한 설명은 공식 홈페이지에서 찾을 수 있다.
iPhone 사용 설명서
Apple에서 직접 제공하는 iPhone에 관한 모든 정보가 여기에 담겨 있습니다. 이 설명서는 iPhone의 사용 방법과 놀라운 기능을 소개합니다.
support.apple.com
위 페이지로 들어가서 iPhone의 건강 앱에서 데이터 공유하기 페이지를 검색해서 찾아가면, 최하단에 XML 포맷으로 건강 및 피트니스 데이터 공유하기 메뉴를 찾을 수 있습니다.
xml 데이터에서 확인할 수 있는 vital sign은 다양하지만, 추출하는 과정은 동일하므로, 심장 박동수(bpm)를 기준으로 추출하는 과정을 살펴보자.
3. xml 데이터 살펴보기
<Record
type="HKQuantityTypeIdentifierHeartRateVariabilitySDNN"
sourceName="Isaac" sourceVersion="8.4"
device="<<HKDevice: 0x282808320>, name:Apple Watch, manufacturer:Apple Inc., model:Watch, hardware:Watch6,2, software:8.4>"
unit="ms"
creationDate="2022-02-03 11:17:00 +0900"
startDate="2022-02-03 11:15:59 +0900"
endDate="2022-02-03 11:16:59 +0900"
value="28.5493">
<MetadataEntry
key="HKAlgorithmVersion" value="2"/>
<HeartRateVariabilityMetadataList>
<InstantaneousBeatsPerMinute bpm="79" time="오전 11:16:00.49"/>
<InstantaneousBeatsPerMinute bpm="84" time="오전 11:16:02.75"/>
<InstantaneousBeatsPerMinute bpm="86" time="오전 11:16:03.44"/>
<InstantaneousBeatsPerMinute bpm="86" time="오전 11:16:04.14"/>
<InstantaneousBeatsPerMinute bpm="84" time="오전 11:16:04.85"/>
<InstantaneousBeatsPerMinute bpm="86" time="오전 11:16:05.55"/>
<InstantaneousBeatsPerMinute bpm="89" time="오전 11:16:06.22"/>
<InstantaneousBeatsPerMinute bpm="91" time="오전 11:16:06.88"/>
<InstantaneousBeatsPerMinute bpm="87" time="오전 11:16:07.57"/>
<InstantaneousBeatsPerMinute bpm="87" time="오전 11:16:13.97"/>
<InstantaneousBeatsPerMinute bpm="86" time="오전 11:16:14.67"/>
<InstantaneousBeatsPerMinute bpm="83" time="오전 11:16:15.40"/>
<InstantaneousBeatsPerMinute bpm="82" time="오전 11:16:16.13"/>
<InstantaneousBeatsPerMinute bpm="83" time="오전 11:16:16.85"/>
<InstantaneousBeatsPerMinute bpm="82" time="오전 11:16:17.58"/>
<InstantaneousBeatsPerMinute bpm="80" time="오전 11:16:18.33"/>
<InstantaneousBeatsPerMinute bpm="76" time="오전 11:16:19.11"/>
<InstantaneousBeatsPerMinute bpm="84" time="오전 11:16:24.10"/>
<InstantaneousBeatsPerMinute bpm="84" time="오전 11:16:24.81"/>
<InstantaneousBeatsPerMinute bpm="84" time="오전 11:16:25.52"/>
<InstantaneousBeatsPerMinute bpm="83" time="오전 11:16:26.24"/>
<InstantaneousBeatsPerMinute bpm="82" time="오전 11:16:26.98"/>
<InstantaneousBeatsPerMinute bpm="81" time="오전 11:16:27.72"/>
<InstantaneousBeatsPerMinute bpm="84" time="오전 11:16:28.44"/>
<InstantaneousBeatsPerMinute bpm="87" time="오전 11:16:29.12"/>
<InstantaneousBeatsPerMinute bpm="87" time="오전 11:16:29.81"/>
<InstantaneousBeatsPerMinute bpm="87" time="오전 11:16:30.50"/>
<InstantaneousBeatsPerMinute bpm="87" time="오전 11:16:31.19"/>
<InstantaneousBeatsPerMinute bpm="81" time="오전 11:16:33.36"/>
<InstantaneousBeatsPerMinute bpm="79" time="오전 11:16:34.12"/>
<InstantaneousBeatsPerMinute bpm="77" time="오전 11:16:34.90"/>
<InstantaneousBeatsPerMinute bpm="89" time="오전 11:16:44.72"/>
<InstantaneousBeatsPerMinute bpm="87" time="오전 11:16:45.41"/>
<InstantaneousBeatsPerMinute bpm="85" time="오전 11:16:46.12"/>
<InstantaneousBeatsPerMinute bpm="83" time="오전 11:16:46.84"/>
<InstantaneousBeatsPerMinute bpm="83" time="오전 11:16:47.57"/>
<InstantaneousBeatsPerMinute bpm="82" time="오전 11:16:48.30"/>
<InstantaneousBeatsPerMinute bpm="81" time="오전 11:16:49.04"/>
<InstantaneousBeatsPerMinute bpm="85" time="오전 11:16:54.10"/>
<InstantaneousBeatsPerMinute bpm="80" time="오전 11:16:57.86"/>
<InstantaneousBeatsPerMinute bpm="80" time="오전 11:16:58.61"/>
<InstantaneousBeatsPerMinute bpm="80" time="오전 11:16:59.36"/>
</HeartRateVariabilityMetadataList>
</Record>
- xml 파일은 <Record>로 시작해서 </Record>로 끝나고, <Record>에는 type, device등의 정보를 포함하고 있고, 하위에는 <MetadataEntry>와 <HeartRateVariabilityMetadataList>를 포함하고 있다.
- <HeartRateVariabilityMetadataList>에는 <InstantaneousBeatsPerMinute>를 포함하고 있고, 여기에 우리가 원하는 bpm정보와 심장 박동을 체크한 시간을 확인할 수 있다.
4. 추출 코드
1) 라이브러리 가져오기
import xml.etree.ElementTree as etree
import pandas as pd
import matplotlib.pyplot as plt
- 기본인 pandas와 matplotlib외에 xml parsing을 위해 etree가 필요하며, etree에 대한 정보는 파이썬 공식 페이지에서 확인할 수 있다.
2) 데이터 추출하기
tree = etree.parse('/content/drive/MyDrive/Colab Notebooks/20220223/data.xml')
root = tree.getroot()
records = list(root)
- 로컬 환경이 아닌 구글 colab을 쓰다보니 저런 경로가 지정되으니 각자의 환경에 맞춰서 변경하면 된다.
- xml 파일을 트리 형태로 변경해주고, 최상단인 root로 가서 찾아가는 방식으로 접근할 예정이다.
3) 일자 정보 추출하기
date = root.attrib["startDate"]
year = int(date[0:4])
month = int(date[5:7])
day = int(date[8:10])
- 심장 박동수(bpm)은 밀리 세컨드 단위로 나누어져 있지만, 일자 정보는 root인 record에 있으므로 우선 일자 정보를 가져와야 한다.
- 일자 정보는 creationData 태그, startData 태그, endData 태그에서 찾을 수 있으나, 일 단위로 체크하는게 아닌 한 모두 같기 때문에 어떤 정보를 사용해도 무방하다.
root.attrib["startDate"]를 실행하면 attribute인 "2022-02-03 11:15:59 +0900"리 문자열(str)로 반환된다.
연(year), 월(month), 일(day)를 각각 쪼개주자.
4) 심장 박동수(bpm) 추출하기
data_list = []
for record in records:
if record.tag == 'HeartRateVariabilityMetadataList':
for data in record:
if '오전' in data.attrib['time']:
time = data.attrib['time'].replace('오전', '').strip()
ampm = "AM"
else:
time = data.attrib['time'].replace('오후', '').strip()
ampm = "PM"
bpm = int(data.attrib['bpm'])
data_list.append([year, month, day, ampm, time, bpm])
- records는 list이고, <MetadataEntry>와 <HeartRateVariabilityMetadataList>가 들어있다. 우리가 원하는 것은 <HeartRateVariabilityMetadataList>에 있으므로 tag정보를 비교하여 일치하는 경우에만 추출 작업을 진행한다.
- record도 list이고, <InstantaneousBeatsPerMinute bpm="79" time="오전 11:16:00.49"/>와 같은 정보를 포함하므로 이제 하나씩 data에 할당하여 추출 작업을 진행해야 한다.
- data.attrib['time']를 실행하면 "오전 11:16:00.49"와 같은 문자열을 반환하므로 필요에 맞게 추출하면 된다.
- 한글 정보인 '오전'과 '오후'는 영문 AM, PM으로 변환하고, 시간은 datetime을 이용해서 변환할 수 있으나, 그것은 내일의 나에게 맡기고 여기는 원래의 문자열을 저장하기로 한다.
- for data in record를 최초 실행하면, data_list에는 [2022, 2, 23, "AM", "11:16:00.49", 79]가 저장된다.
5) dataframe에 저장
col = ["year", "month", "day", "AMPM","time","bpm"]
df = pd.DataFrame(data=data_list, columns=col)
- 위에서 저장한 순서에 맞게 col을 지정하고 data_list와 함께 넣어주면 아래와 같이 저장된다.
6) 시각화하기
plt.plot(df['time'], df['bpm'])
plt.xlabel('time')
plt.ylabel('bpm')
plt.show()
- 살벌하게 얄팍한 수준의 시각화인데, x축에 시간정보를 쌩으로 넣으니 보이지도 않게 결과가 나왔다.
- 시작 시간(startDate)과 종료 시간(endDate)의 차이만 넣어줘야 되겠지만, 대충 이렇게 뽑아낼 수 있다는 걸 원하는 것이므로 정말 대충시각화를 해보았다.
- 시작 시간과 종료 시간 차이는 1분인데, 심장박동수가 76에서 90까지 변동하는 것으로 보아 편안한 휴식 상태는 아닐 것으로 생각해볼 수 있겠다.
반응형
'아모른직다' 카테고리의 다른 글
AttributeError: module 'keras.optimizers' has no attribute 'RMSprop' 에러 해결하기 (0) | 2022.02.15 |
---|---|
터져나가는 책장을 정리해보자.(feat. 북스캔) (0) | 2022.02.09 |
쏟아지는 일 완벽하게 해내는 법(GTD, Getting Things Done) (1) | 2022.01.26 |
1년 안에 AI 빅데이터 전문가가 되는 법 (0) | 2022.01.24 |