2. 데이터 탐색

Open In Colab

이전 장에서 시계열 분석에 활용 가능한 딥러닝 모델 구조와 모델 평가지표에 대해 알아보았습니다. 본격적으로 시계열 데이터를 사용하여 분석을 해보기 앞서 2장에서는 분석에 사용될 데이터셋에 대한 탐색과 시각화를 해보겠습니다.

시계열 예측에 사용할 데이터는 코로나 확진자 데이터입니다. 데이터셋은 COVID-19 Data Repository by the Center for Systems Science and Engineering (CSSE) at Johns Hopkins UniversityKaggle: Novel Corona Virus 2019 Dataset 에서 확보했습니다.

Johns Hopkins 대학의 저장소에는 매일 국가별 확진자 현황이 업데이트 되고 있으며, 이를 일자별 레포트 형태로 제공하고 있습니다. 일자별 레포트 양식을 변형해서 가공한 전체 기간의 레포트도 저장소에서 제공합니다. 또한 일자별 레포트 양식을 보존한 상태로 전체 데이터를 합한 데이터를 Kaggle에서 제공하고 있습니다.

2.1절에서 해당 데이터를 다운받고 어떤 변수들로 이루어져 있는지 알아보겠습니다. 그리고 2.2절에서 전세계적으로 유행하고 있는 코로나인만큼 전세계 확진자로부터 추세를 알아보고 2.3절에서 대한민국 확진자를 더 자세하게 탐색해보도록 하겠습니다.

2.1 데이터 다운로드

먼저 코로나 확진자 데이터셋을 내려받도록 하겠습니다. 가짜연구소에서 제공하는 데이터 로더 함수를 사용하여 쉽게 받아볼 수 있습니다.

git clone 명령어를 사용하여 Tutorial-Book-Utils 저장소를 Colab 환경에 다운로드 합니다. \

!git clone https://github.com/Pseudo-Lab/Tutorial-Book-Utils
Cloning into 'Tutorial-Book-Utils'...
remote: Enumerating objects: 24, done.
remote: Counting objects: 100% (24/24), done.
remote: Compressing objects: 100% (20/20), done.
remote: Total 24 (delta 6), reused 14 (delta 3), pack-reused 0
Unpacking objects: 100% (24/24), done.

dataset example

  • 그림 2-1 Tutorial-Book-Utils 저장소 폴더 경로

그림 2-1과 같이 저장소 내의 파일을 모두 다운받고 그 중에 PL_data_loader.py 파일이 위치한 것을 알 수 있습니다. 해당 파일에는 구글 드라이브의 데이터셋을 다운로드 하는 함수가 저장되어 있습니다. --data 파라미터에 COVIDTimeSeries을 입력하면 모델 구축에 활용할 코로나 확진자 수 데이터를 받을 수 있습니다.

!python Tutorial-Book-Utils/PL_data_loader.py --data COVIDTimeSeries
COVIDTimeSeries.zip is done!

다음으로 리눅스 명령어인 unzip을 활용하여 압축파일을 풀어보도록 하겠습니다. -q 옵션을 통해 불필요한 출력물이 나오지 않게 제어 가능합니다.

!unzip -q COVIDTimeSeries.zip

dataset example

  • 그림 2-2 다운로드된 데이터셋 파일

압축까지 풀면 그림 2-2와 같이 covid_19_data.csv 파일과 time_series_covid19_confirmed_global.csv 파일이 다운로드 된 것을 확인할 수 있습니다.

covid_19_data.csv 파일을 활용해 시간에 따른 전세계 확진자 현황을 시각화 해볼 것이며, time_series_covid19_confirmed_global.csv 파일에서 대한민국 데이터를 활용해 확진자 수 변화를 시각화해보겠습니다. 우선 각 데이터를 읽어서 저장된 값을 확인해보겠습니다.

import pandas as pd

all = pd.read_csv('covid_19_data.csv')
confirmed = pd.read_csv('time_series_covid19_confirmed_global.csv')

all는 전세계의 일별 확진자, 사망자, 완치자에 대한 데이터입니다. ObservationDate는 발생 날짜, Province/State, Country/Region는 발생 지역과 국가, Confirmed는 확진자수, Deaths는 사망자수, 그리고 Recovered는 완치자수를 의미합니다. 해당 데이터프레임은 다음과 같습니다.

all
SNo ObservationDate Province/State Country/Region Last Update Confirmed Deaths Recovered
0 1 01/22/2020 Anhui Mainland China 1/22/2020 17:00 1.0 0.0 0.0
1 2 01/22/2020 Beijing Mainland China 1/22/2020 17:00 14.0 0.0 0.0
2 3 01/22/2020 Chongqing Mainland China 1/22/2020 17:00 6.0 0.0 0.0
3 4 01/22/2020 Fujian Mainland China 1/22/2020 17:00 1.0 0.0 0.0
4 5 01/22/2020 Gansu Mainland China 1/22/2020 17:00 0.0 0.0 0.0
... ... ... ... ... ... ... ... ...
172475 172476 12/06/2020 Zaporizhia Oblast Ukraine 2020-12-07 05:26:14 36539.0 337.0 6556.0
172476 172477 12/06/2020 Zeeland Netherlands 2020-12-07 05:26:14 6710.0 104.0 0.0
172477 172478 12/06/2020 Zhejiang Mainland China 2020-12-07 05:26:14 1295.0 1.0 1288.0
172478 172479 12/06/2020 Zhytomyr Oblast Ukraine 2020-12-07 05:26:14 31967.0 531.0 22263.0
172479 172480 12/06/2020 Zuid-Holland Netherlands 2020-12-07 05:26:14 154813.0 2414.0 0.0

172480 rows × 8 columns

confirmed는 국가별 확진자 수에 대한 시퀀스(sequence) 데이터입니다. Country/Region, Province/State는 발생 지역과 국가, Long, Lat는 경도와 위도, 그리고 MM/DD/YYYY는 일자별 확진자 수를 의미합니다. 해당 데이터프레임은 다음과 같습니다.

confirmed
Province/State Country/Region Lat Long 1/22/20 1/23/20 1/24/20 1/25/20 1/26/20 1/27/20 1/28/20 1/29/20 1/30/20 1/31/20 2/1/20 2/2/20 2/3/20 2/4/20 2/5/20 2/6/20 2/7/20 2/8/20 2/9/20 2/10/20 2/11/20 2/12/20 2/13/20 2/14/20 2/15/20 2/16/20 2/17/20 2/18/20 2/19/20 2/20/20 2/21/20 2/22/20 2/23/20 2/24/20 2/25/20 2/26/20 ... 11/9/20 11/10/20 11/11/20 11/12/20 11/13/20 11/14/20 11/15/20 11/16/20 11/17/20 11/18/20 11/19/20 11/20/20 11/21/20 11/22/20 11/23/20 11/24/20 11/25/20 11/26/20 11/27/20 11/28/20 11/29/20 11/30/20 12/1/20 12/2/20 12/3/20 12/4/20 12/5/20 12/6/20 12/7/20 12/8/20 12/9/20 12/10/20 12/11/20 12/12/20 12/13/20 12/14/20 12/15/20 12/16/20 12/17/20 12/18/20
0 NaN Afghanistan 33.939110 67.709953 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 ... 42297 42463 42609 42795 42969 43035 43240 43468 43681 43924 44177 44363 44503 44706 44988 45174 45384 45600 45723 45844 46116 46274 46516 46718 46837 46837 47072 47306 47516 47716 47851 48053 48116 48229 48527 48718 48952 49161 49378 49621
1 NaN Albania 41.153300 20.168300 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 24731 25294 25801 26211 26701 27233 27830 28432 29126 29837 30623 31459 32196 32761 33556 34300 34944 35600 36245 36790 37625 38182 39014 39719 40501 41302 42148 42988 43683 44436 45188 46061 46863 47742 48530 49191 50000 50637 51424 52004
2 NaN Algeria 28.033900 1.659600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 ... 62693 63446 64257 65108 65975 66819 67679 68589 69591 70629 71652 72755 73774 74862 75867 77000 78025 79110 80168 81212 82221 83199 84152 85084 85927 86730 87502 88252 88825 89416 90014 90579 91121 91638 92102 92597 93065 93507 93933 94371
3 NaN Andorra 42.506300 1.521800 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 5437 5477 5567 5616 5725 5725 5872 5914 5951 6018 6066 6142 6207 6256 6304 6351 6428 6534 6610 6610 6712 6745 6790 6842 6904 6955 7005 7050 7084 7127 7162 7190 7236 7288 7338 7382 7382 7446 7466 7519
4 NaN Angola -11.202700 17.873900 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 12680 12816 12953 13053 13228 13374 13451 13615 13818 13922 14134 14267 14413 14493 14634 14742 14821 14920 15008 15087 15103 15139 15251 15319 15361 15493 15536 15591 15648 15729 15804 15925 16061 16161 16188 16277 16362 16407 16484 16562
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
266 NaN Vietnam 14.058324 108.277199 0 2 2 2 2 2 2 2 2 2 6 6 8 8 8 10 10 13 13 14 15 15 16 16 16 16 16 16 16 16 16 16 16 16 16 16 ... 1215 1226 1252 1253 1256 1265 1281 1283 1288 1300 1304 1305 1306 1307 1312 1316 1321 1331 1339 1341 1343 1347 1351 1358 1361 1361 1365 1366 1367 1377 1381 1385 1391 1395 1397 1402 1405 1405 1407 1410
267 NaN West Bank and Gaza 31.952200 35.233200 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 58838 59422 60065 60784 61514 62167 63031 63867 64935 66186 67296 68768 70254 71644 73196 75007 76727 78493 80429 81890 83585 85647 88004 90192 92708 94676 96098 98038 99758 101109 102992 104879 106622 108099 109738 111102 113409 115606 117755 119612
268 NaN Yemen 15.552727 48.516388 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 2071 2071 2071 2071 2072 2072 2072 2078 2081 2083 2086 2090 2093 2099 2107 2114 2124 2137 2148 2160 2177 2191 2197 2217 2239 2267 2304 2337 2383 2078 2079 2081 2082 2083 2083 2084 2085 2085 2087 2087
269 NaN Zambia -13.133897 27.849332 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 16971 16997 17036 17056 17093 17097 17123 17187 17243 17280 17350 17373 17394 17424 17454 17466 17535 17553 17569 17589 17608 17647 17665 17700 17730 17857 17898 17916 17931 17963 18062 18091 18161 18217 18274 18322 18428 18456 18504 18575
270 NaN Zimbabwe -19.015438 29.154857 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... 8561 8610 8667 8696 8765 8786 8829 8897 8945 8981 9046 9120 9172 9220 9308 9398 9508 9623 9714 9822 9822 9950 10129 10129 10424 10547 10617 10718 10839 10912 11007 11081 11162 11219 11246 11358 11522 11749 11866 12047

271 rows × 336 columns

2.2 전세계 데이터 EDA

all을 활용해 전세계 코로나 확진자 수를 시각화 해보도록 하겠습니다. 이 데이터프레임에는 위치를 나타내는 변수가 Province/State(지역)와 Country/Region(국가) 두 가지로 존재합니다. 그 중 국가별 확진자 수를 시각화 하기 위해서 Country/Region 기준으로 해당 국가의 모든 확진자 수를 더해줘야 합니다. 아래 코드를 통해 구현해보겠습니다.

group = all.groupby(['ObservationDate', 'Country/Region'])['Confirmed'].sum()
group = group.reset_index()
group.head()
ObservationDate Country/Region Confirmed
0 01/22/2020 Hong Kong 0.0
1 01/22/2020 Japan 2.0
2 01/22/2020 Macau 1.0
3 01/22/2020 Mainland China 547.0
4 01/22/2020 South Korea 1.0

일자별로 국가별 총 확진자 수가 도출 된 것을 확인할 수 있습니다. 다음으로는 세계지도 위에 국가별 확진자 수가 나타나지도록 애니메이션 효과로 표현해보겠습니다. 이는 plotly.express 패키지를 이용하여 나타낼 수 있습니다.

import plotly as py
import plotly.express as px

먼저 px.choropleth로 지도 레이어를 만들고 .update_layout를 통해 날짜를 업데이트 하는 방식입니다.

각 파라미터의 의미는 다음과 같습니다.

  • location : dataframe에서 위치를 나타내는 column

  • locationmode : 나타낼 국가(‘ISO-3’, ‘USA-states’, ‘country names’중 하나)의 범위

  • color : dataframe에서 그래프로 나타낼 column

  • animation_frame : dataframe에서 애니메이션 효과를 줄 기준 column

재생버튼을 누르면 일별 확진자 그래프를 확인할 수 있습니다.

choro_map=px.choropleth(group, 
                    locations="Country/Region", 
                    locationmode = "country names",
                    color="Confirmed", 
                    animation_frame="ObservationDate"
                   )

choro_map.update_layout(
    title_text = 'Global Spread of Coronavirus',
    title_x = 0.5,
    geo=dict(
        showframe = False,
        showcoastlines = False,
    ))
    
choro_map.show()

처음에는 중국에서 시작되어서 점점 전세계적으로 퍼지는 것을 볼 수 있습니다. 최근에는 북미, 남미, 그리고 인도의 확진자 수가 다른 지역에 비해 많은 것을 확인해볼 수 있습니다.

2.3 대한민국 데이터 EDA

이번에는 confirmed에서 대한민국 데이터만 뽑아보겠습니다. 이 데이터는 누적데이터로 해당 날짜까지의 총 확진자수를 의미합니다.

confirmed[confirmed['Country/Region']=='Korea, South']
Province/State Country/Region Lat Long 1/22/20 1/23/20 1/24/20 1/25/20 1/26/20 1/27/20 1/28/20 1/29/20 1/30/20 1/31/20 2/1/20 2/2/20 2/3/20 2/4/20 2/5/20 2/6/20 2/7/20 2/8/20 2/9/20 2/10/20 2/11/20 2/12/20 2/13/20 2/14/20 2/15/20 2/16/20 2/17/20 2/18/20 2/19/20 2/20/20 2/21/20 2/22/20 2/23/20 2/24/20 2/25/20 2/26/20 ... 11/9/20 11/10/20 11/11/20 11/12/20 11/13/20 11/14/20 11/15/20 11/16/20 11/17/20 11/18/20 11/19/20 11/20/20 11/21/20 11/22/20 11/23/20 11/24/20 11/25/20 11/26/20 11/27/20 11/28/20 11/29/20 11/30/20 12/1/20 12/2/20 12/3/20 12/4/20 12/5/20 12/6/20 12/7/20 12/8/20 12/9/20 12/10/20 12/11/20 12/12/20 12/13/20 12/14/20 12/15/20 12/16/20 12/17/20 12/18/20
157 NaN Korea, South 35.907757 127.766922 1 1 2 2 3 4 4 4 4 11 12 15 15 16 19 23 24 24 25 27 28 28 28 28 28 29 30 31 31 104 204 433 602 833 977 1261 ... 27653 27799 27942 28133 28338 28546 28769 28998 29311 29654 30017 30403 30733 31004 31353 31735 32318 32887 33375 33824 34201 34652 35163 35703 36332 36915 37546 38161 38755 39432 40098 40786 41736 42766 43484 44364 45442 46453 47515 48570

1 rows × 336 columns

여기서 지역명, 위경도를 제외한 확진자수에 대한 정보만 남기도록 하겠습니다. 그리고 이후 편의성을 위해 행과 열을 바꾸고(.T), 인덱스인 날짜를 str 형식에서 datetime 형식으로 바꿔주었습니다(to_datetime).

korea = confirmed[confirmed['Country/Region']=='Korea, South'].iloc[:,4:].T
korea.index = pd.to_datetime(korea.index)
korea
157
2020-01-22 1
2020-01-23 1
2020-01-24 2
2020-01-25 2
2020-01-26 3
... ...
2020-12-14 44364
2020-12-15 45442
2020-12-16 46453
2020-12-17 47515
2020-12-18 48570

332 rows × 1 columns

가장 대표적인 시각화 패키지인 matplotlib.pyplotseaborn을 이용하여 시각화해보도록 하겠습니다. 이 때, %matplotlib inline은 해당 셀에서 바로 그래프를 보이게 할 수 있습니다. 그리고 pylabrcParams['figure.figsize']은 그래프 크기를 조정할 수 있으며, sns.set은 격자의 색깔과 글짜 크기를 조정할 수 있습니다.

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
from pylab import rcParams
rcParams['figure.figsize'] = 12, 8
sns.set(style='whitegrid', palette='muted', font_scale=1.2)

plt.plot(korea)
plt.show()
../../_images/Ch2-EDA_35_01.png

이번에는 누적데이터가 아닌 일일 단위로 확진자 수를 알아보겠습니다. diff를 이용하면 이전 행과 차이를 구할 수 있어 누적데이터를 쉽게 일별데이터로 바꿀 수 있습니다. 하지만 첫번째 행에는 결측치가 생겨 이를 누적데이터의 첫번째 값으로 채워주어야 합니다. 그리고 데이터 형식은 int(정수)로 바꿔줍니다.

daily_cases = korea.diff().fillna(korea.iloc[0]).astype('int')
daily_cases
157
2020-01-22 1
2020-01-23 0
2020-01-24 1
2020-01-25 0
2020-01-26 1
... ...
2020-12-14 880
2020-12-15 1078
2020-12-16 1011
2020-12-17 1062
2020-12-18 1055

332 rows × 1 columns

마찬가지로 일별 확진자수 데이터를 그래프로 나타내면 다음과 같습니다. 위에서 그래프 형식에 대한 셋팅을 미리 해두면 이후에는 똑같이 적용됩니다.

plt.plot(daily_cases)
plt.show()
../../_images/Ch2-EDA_39_0.png

3월초와 8월말에 급증하는 시기가 있고, 지속적으로 확진자가 발생하고 있는 것을 볼 수 있습니다. 그리고 연말이 되면서 다시 증가 추세를 보이고 있습니다.

이렇게 이번장에서 전세계와 대한민국의 코로나 확진자 수 데이터에 대해 알아보았습니다. 다음장부터는 대한민국 일별 코로나 확진자 수에 대해서 전처리하고 모델링하는 과정에 대해 알아보도록 하겠습니다.