데이터 분석/실습

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