데이터 분석/실습
COVID-19 data from John Hopkins University
eunki
2022. 1. 6. 06:02
728x90
https://www.kaggle.com/antgoldbloom/covid19-data-from-john-hopkins-university
COVID-19 data from John Hopkins University
Updated daily at 6am UTC in both raw and convenient form
www.kaggle.com
데이터 정보
- Country/Region: 국가
- Province/State: 지방/주
- Lat: 지역의 위도
- Long: 지역의 경도
- 날짜: 각 날짜의 확진자/사망자 수
데이터셋 준비
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
df_case = pd.read_csv('../input/covid19-data-from-john-hopkins-university/RAW_global_confirmed_cases.csv')
df_death = pd.read_csv('../input/covid19-data-from-john-hopkins-university/RAW_global_deaths.csv')
df_case.head()

df_death.head()

데이터 구조 변경 및 시각화
# 데이터 프레임 구조를 Date를 Index로, 지역을 Column으로 변경
def fix_dataframe(df):
df = df.drop(['Lat', 'Long'], axis=1).groupby('Country/Region').sum()
df = df.transpose() # 행 열 전환
df.index.name = 'Date'
df.reset_index(inplace=True)
df['Date'] = df['Date'].apply(lambda s: pd.to_datetime(str(s)))
df.set_index('Date', inplace=True)
return df
df_case = fix_dataframe(df_case)
df_case

df_death = fix_dataframe(df_death)
df_death
# 나라별 확진자 수 및 사망자 수 시각화 (최신일자, 가장 많이 확진된 10국가)
top_ten_cases = df_case.loc[df_case.index[-1]].sort_values(ascending=False)[:10]
sns.barplot(x=top_ten_cases.index, y=top_ten_cases, color='black')
plt.xticks(rotation=90, size=15)
plt.xlabel('')
plt.ylabel('Total Confirmed Cases', size=15)
plt.title('Total Confirmed Cases (%s)' % top_ten_cases.name.strftime('%Y-%m-%d'), size=15)
# 왼쪽 y축에는 확진자 수, 오른쪽 y축에는 사망자 수 표시
ax = plt.gca()
ax2 = ax.twinx() # 동일한 x축을 공유하면서 서로 다른 y축을 가짐
top_ten_deaths = df_death.loc[df_death.index[-1]][top_ten_cases.index]
ax2.plot(top_ten_deaths.index, top_ten_deaths, 'r--')
ax2.set_ylabel('Total Deaths', color='red', size=15)
plt.show()

# 특정 국가의 확진자 수 및 사망자 수 변화 시각화
def plot_case_with_death(country):
plt.plot(df_case.index, df_case[country], 'b-')
plt.xlabel('Date')
plt.ylabel('Confirmed Cases', color='blue')
plt.title(country + ' Cases & Deaths')
plt.xlim(right=df_case.index[-1])
plt.ylim(0, df_case[country].max() * 1.1)
ax = plt.gca()
ax2 = ax.twinx()
ax2.plot(df_death.index, df_death[country], 'r--')
ax2.set_ylabel('Deaths', color='red')
ax2.set_ylim(0, df_death[country].max() * 1.3)
plt.show()
plot_case_with_death('US')

plot_case_with_death('Germany')

plot_case_with_death('China')

plot_case_with_death('Kenya')

plot_case_with_death('Korea, South')

# 한국의 일일 확진자 수 및 사망자 수 변화 시각화
# 일일 확진자 수는 누적 확진자 수에서 연속된 두 값의 차이 (미분)
country = 'Korea, South'
plt.plot(df_case.index, df_case[country].diff(), 'b-')
plt.xlabel('Date')
plt.ylabel('Confirmed Cases', color='blue')
plt.title(country + ' Cases & Deaths')
plt.xlim(right=df_case.index[-1])
plt.ylim(bottom=0)
ax = plt.gca()
ax2 = ax.twinx()
ax2.plot(df_death.index, df_death[country].diff(), 'r--')
ax2.set_ylabel('Deaths', color='red')
ax2.set_ylim(bottom=0)
plt.show()

데이터 전처리
df_case.reset_index()[['Date', 'Korea, South']].to_numpy()
array([[Timestamp('2020-01-22 00:00:00'), 1],
[Timestamp('2020-01-23 00:00:00'), 1],
[Timestamp('2020-01-24 00:00:00'), 2],
...,
[Timestamp('2022-01-02 00:00:00'), 642207],
[Timestamp('2022-01-03 00:00:00'), 645226],
[Timestamp('2022-01-04 00:00:00'), 649669]], dtype=object)
# 한국의 확진자 수 데이터를 FBProphet에 학습하기 위한 데이터 프레임으로 재구성
df = pd.DataFrame(df_case.reset_index()[['Date', 'Korea, South']].to_numpy(), columns=['ds', 'y'])
df

학습 데이터와 테스트 데이터 분리
from math import floor
# test_size(0 < test_size < 1) 비율에 따라 테스트/학습 데이터 프레임으로 나누어 반환
def train_test_split_df(df, test_size):
div = floor(df.shape[0] * (1 - test_size))
return df.loc[:div], df.loc[div+1:]
train_df, test_df = train_test_split_df(df, 0.1)
train_df.tail()

test_df.head()

Prophet 모델 학습
from fbprophet import Prophet
# Prophet 모델 생성/학습
# changepoint_range=0.8 : 앞의 80% 시간까지만 changepoint 허용 (default)
model = Prophet(changepoint_range=1.0)
model.fit(train_df)
# Prophet 모델 학습 결과 시각화
# 검정선은 실제 과거 데이터 (train), 파란선은 예측 데이터 (predict), 파란면은 신뢰도 95% 구간
# 뒤에 ;를 붙이면 1개만 출력
pred = model.predict(test_df)
model.plot(pred);

model.plot_components(pred);

from fbprophet.plot import add_changepoints_to_plot
# 초록 선은 실제 데이터 (test)
fig = model.plot(pred)
plt.plot(test_df['ds'], test_df['y'], 'g-', label='actual')
changes = add_changepoints_to_plot(fig.gca(), model, pred)
plt.legend()

from sklearn.metrics import r2_score
# r2_score 평가
print('R2 Score: ', r2_score(test_df['y'], pred['yhat']))
R2 Score: 0.28505533869619315
# Prophet 모델로 미래 30일 데이터 예측
model = Prophet(changepoint_range=1.0)
model.fit(df)
future = model.make_future_dataframe(30)
pred = model.predict(future)
model.plot(pred);

IF-CASE 예측
1. 한국 확진자 수 변화의 특별한 이벤트 확인
# 코로나 확산 초기, 한국의 확진자 수가 급증한 시점 찾기
df.loc[24:30]

2. 이벤트가 없었을 경우 한국의 확진자 수 변화 예측
model = Prophet(changepoint_range=1.0)
model.fit(df.loc[:28])
future = model.make_future_dataframe(30)
pred = model.predict(future)
model.plot(pred);
plt.plot(df.loc[:58]['ds'], df.loc[:58]['y'], 'g-')
plt.show()

728x90