Basic Exploratory Data Analysis dengan Studi Kasus: Pandemic Covid-19 Case di Dunia dan Indonesia

Hai, sekarang ini pandemic covid-19 di dunia semakin masif. Kasus baru terkonfirmasi semakin bertambah, begitu pula kasus kematian baru. Dalam hal ini, saya mencoba membuat data analisis terkait pandemic covid-19 di dunia dan membandingkannya dengan negara Indonesia, karena saya berasal dari Indonesia. Data analisis ini merupakan sarana pembelajaran bagi saya untuk mengasah kemampuan saya di bidang data science. Adapun perbedaan data, itu dimungkinkan ada data dari sumber yang belum update terbaru. Namun tidak mengurangi isi secara teknis yaitu metode analisis data tersebut. Saya melakukan analisis data dengan Python di aplikasi web Jupyter Notebook (Google Colaboratory), library yang digunakan; Pandas, Numpy, Matplotlib & Seaborn.

Oke, mari kita mulai.

Dataset

Sumber dataset diambil dari link source: https://github.com/CSSEGISandData/COVID-19/tree/master/csse_covid_19_data/csse_covid_19_time_series

Dataset tersebut terdiri dari time series dari confirmed & death case di global dan US. Untuk eksplorasi data ini, saya hanya mengambil data yang terjadi secara global saja. Lalu dari dataset global tersebut, saya spesifikan lagi ke negara Indonesia.

Libraries

Library yang saya pakai adalah: Pandas & Numpy untuk manipulasi data dan Matplotlib & Seaborn untuk data visualisasi.

import warnings
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np


warnings.simplefilter(action='ignore', category=FutureWarning)
pd.plotting.register_matplotlib_converters()

Import dataset:

# Import Source
covid_confirmed = pd.read_csv('https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv')
covid_deaths = pd.read_csv('https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_deaths_global.csv')

Untuk lebih mudah memanipulasi data, saya sudah menganalisis data apa saja yang dibutuhkan, lalu menghapus data yang tidak diperlukan, serta melakukan set index & transpose. Tujuan transpose ini agar memudahkan dalam visulisasi data nantinya.

# Drop, set index, transpose
confirmed = covid_confirmed.drop(columns=['Province/State', 'Lat', 'Long']) \
                           .set_index('Country/Region') \
                           .T
confirmed.columns.name = None

deaths = covid_deaths.drop(columns=['Province/State', 'Lat', 'Long']) \
                     .set_index('Country/Region') \
                     .T
deaths.columns.name = None

Global Data Wrangle

# World confirmed & deaths: reset index, rename columns, add column Total, change datatype Date

world_confirmed = confirmed.reset_index() \
                           .rename(columns={'index': 'Date'})
world_confirmed['Confirmed_Cases'] = world_confirmed.sum(axis=1)
world_confirmed['Date'] = pd.to_datetime(world_confirmed['Date'])

world_deaths = deaths.reset_index() \
                     .rename(columns={'index': 'Date'})
world_deaths['Deaths_Cases'] = world_deaths.sum(axis=1)
world_deaths['Date'] = pd.to_datetime(world_deaths['Date'])

Pada kode di bawah ini, saya melakukan penggabungan/merge 2 kolom dari 2 dataframe yang berbeda. Dari dataframe hasil merge tersebut saya buat kolom baru yaiut tingkat kematian yang merupakan hasil bagi dari total kasus terconfirmasi dan total kematian. Lalu saya mendefinisikan nilai variable untuk divisualisasikan nanti.

# Show Date & Total only
world_confirmed_total = world_confirmed[['Date', 'Confirmed_Cases']]
world_deaths_total = world_deaths[['Date', 'Deaths_Cases']]

# Merge confirmed & deaths, add new column Death_Rate
global_covid = pd.merge(world_confirmed_total, world_deaths_total, on='Date')

global_covid['Death_Rate'] = global_covid['Deaths_Cases'] / global_covid['Confirmed_Cases']
# global_covid

# Last row values for visualization
Global_Date_Val = global_covid.tail(1)['Date'].dt.strftime('%d %b %Y').values[0]
Global_Confirmed_Cases_Val = global_covid.tail(1)['Confirmed_Cases'].values[0]
Global_Deaths_Cases_Val = int(global_covid.tail(1)['Deaths_Cases'].values[0])
Global_Death_Rate_Val = float(global_covid.tail(1)['Death_Rate'].values[0]) * 100

# Summary dataframe for visualization
global_sum_df = pd.DataFrame({'Cases':['Confirmed Cases', 'Deaths Cases'], 'Total':[Global_Confirmed_Cases_Val, Global_Deaths_Cases_Val]})
# global_sum_df

Indonesia Data Wrangle

Untuk data kasus di Indonesia, saya hanya mengambil data colom Indonesia dari dataset dan lakukan hal yang sama seperi code untuk kasus Global.

# Select column Indonesia, reset index, rename columns
indo_confirmed = confirmed[['Indonesia']]
indo_confirmed = indo_confirmed.reset_index() \
                               .rename(columns={'index': 'Date', 'Indonesia': 'Confirmed_Cases'})

indo_deaths = deaths[['Indonesia']]
indo_deaths = indo_deaths.reset_index() \
                         .rename(columns={'index': 'Date', 'Indonesia': 'Deaths_Cases'})

Berbeda dari code Global, untuk time series, saya filter data dari tanggal akhir februari 2020, karena di Indonesia, baru terjadi kasus covid di minggu pertama bulan maret 2020.

# Filter by date
indo_confirmed['Date'] = pd.to_datetime(indo_confirmed['Date'])
indo_confirmed = indo_confirmed[indo_confirmed['Date'] > '2020-02-28']

indo_deaths['Date'] = pd.to_datetime(indo_deaths['Date'])
indo_deaths = indo_deaths[indo_deaths['Date'] > '2020-02-29']

# Merge confirmed & deaths
indo_covid = pd.merge(indo_confirmed,
                     indo_deaths[['Date', 'Deaths_Cases']],
                     on='Date')
indo_covid['Death_Rate'] = indo_covid['Deaths_Cases'] / indo_covid['Confirmed_Cases']
#indo_covid

# Last row values
Date_Val = indo_covid.tail(1)['Date'].dt.strftime('%d %b %Y').values[0]
Confirmed_Cases_Val = indo_covid.tail(1)['Confirmed_Cases'].values[0]
Deaths_Cases_Val = int(indo_covid.tail(1)['Deaths_Cases'].values[0])
Death_Rate_Val = float(indo_covid.tail(1)['Death_Rate'].values[0]) * 100

# Summary dataframe
sum_df = pd.DataFrame({'Cases':['Confirmed Cases', 'Deaths Cases'], 'Total':[Confirmed_Cases_Val, Deaths_Cases_Val]})
#sum_df

Eksplorasi data & memvisualisasikannya

Pada tahap ini, kita mulai melakukan eksplorasi data dan memvisualisasikannya.

Bar Plot

# Total cases visualization - Global
plt.figure(figsize=(16, 8))
viz = sns.barplot(data=global_sum_df, x='Cases', y='Total', label="Extra label on the legend")
plt.xlabel('Type', fontsize=15)
plt.ylabel('Total Cases (in Millions)', fontsize=15)
plt.title('Total Confirmed & Deaths Cases of Covid-19 in Global', fontsize=20)
plt.grid(color='#95a5a6', linestyle='--', linewidth=1, axis='y', alpha=0.5)

@ticker.FuncFormatter
def million_formatter(x, pos):
    return "%.2f M" % (x/1000000)
ax = viz
ax.yaxis.set_major_formatter(million_formatter)


# Annotate axis = seaborn axis
space = Global_Confirmed_Cases_Val + 1000000
for p in viz.patches:
             viz.annotate("%.f" % p.get_height(), (p.get_x() + p.get_width() / 2., p.get_height()),
                 ha='center', va='center', fontsize=20, color='black', xytext=(0, 25),
                 textcoords='offset points')
_ = viz.set_ylim(0,space) # To make space for the annotations

# Text
textstr = 'Death Rate: %.2f%%\nDate: %s'%(Global_Death_Rate_Val, Global_Date_Val)
plt.gcf().text(0.73, 0.77, textstr, fontsize=14)
plt.show()

Code di atas menghasilkan visualisasi di bawah ini:

# Total cases visualization - Indonesia
plt.figure(figsize=(16,8))
viz = sns.barplot(data=sum_df, x='Cases', y='Total', label="Extra label on the legend")
plt.xlabel('Type', fontsize=15)
plt.ylabel('Total Cases', fontsize=15)
plt.title('Total Confirmed & Deaths Cases of Covid-19 in Indonesia', fontsize=20)
plt.grid(color='#95a5a6', linestyle='--', linewidth=1, axis='y', alpha=0.4)

# Annotate axis = seaborn axis
space = Confirmed_Cases_Val + 1000
for p in viz.patches:
             viz.annotate("%.f" % p.get_height(), (p.get_x() + p.get_width() / 2., p.get_height()),
                 ha='center', va='center', fontsize=20, color='black', xytext=(0, 25),
                 textcoords='offset points')
_ = viz.set_ylim(0,space) # To make space for the annotations

# Text
textstr = 'Death Rate: %.2f%%\nDate: %s'%(Death_Rate_Val,Date_Val)
plt.gcf().text(0.73, 0.77, textstr, fontsize=14)
plt.show()

Code di atas menghasilkan visualisasi di bawah ini:

Line Plot

# Time series of cases visualization - Global
plt.figure(figsize=(15,8))
plt.plot('Date', 'Confirmed_Cases', data=global_covid, marker='o', markerfacecolor='blue', markersize=5, color='skyblue', linewidth=3, label="Confirmed Cases")
plt.plot('Date', 'Deaths_Cases', data=global_covid, marker='o', markerfacecolor='red', markersize=5, color='orange', linewidth=3, label="Deaths Case")
plt.xlabel('Date', fontsize=15)
plt.ylabel('Total Cases', fontsize=15)
plt.title('Time series of Confirmed & Deaths Cases of Covid-19 in Global', fontsize=20)
plt.grid(color='#95a5a6', linestyle='--', linewidth=2, axis='y', alpha=0.7)
plt.legend(borderpad=1,fontsize=14)


@ticker.FuncFormatter
def million_formatter(x, pos):
    return "%.2f M" % (x/1000000)

plt.gca().yaxis.set_major_formatter(million_formatter)

plt.show()

Code di atas menghasilkan visualisasi di bawah ini:

# Time series of cases visualization - Indonesia
plt.figure(figsize=(15,8))
plt.plot('Date', 'Confirmed_Cases', data=indo_covid, marker='o', markerfacecolor='blue', markersize=5, color='skyblue', linewidth=3, label="Confirmed Cases")
plt.plot('Date', 'Deaths_Cases', data=indo_covid, marker='o', markerfacecolor='red', markersize=5, color='orange', linewidth=3, label="Deaths Case")
plt.xlabel('Date', fontsize=15)
plt.ylabel('Total Cases', fontsize=15)
plt.title('Time series of Confirmed & Deaths Cases of Covid-19 in Indonesia', fontsize=20)
plt.grid(color='#95a5a6', linestyle='--', linewidth=2, axis='y', alpha=0.7)
plt.legend(borderpad=1,fontsize=14)
plt.show()

Code di atas menghasilkan visualisasi di bawah ini:

Kesimpulan

Analisis Data Covid-19 di Indonesia dan Global

Per 17 April 2020:
1. Tingkat kematian di Indonesia (8.78%) lebih tinggi daripada Global (6.87%).
2. Berdasarkan Line Plot, garis pada grafik belum mencapai titik puncak atau grafik melandai, itu artinya upaya Social Distancing di Indonesia khususnya terus berlanjut sampai berhenti penyebaran virusnya dan angka kasus baru hilang.

Menurut pakar kesehatan mengatakan, dari titik puncak sampai berhentinya penyebaran yaitu 3 bulan, CMIIW, belum termasuk recovery secara ekonomi ya. Semoga pandemi Covid-19 di dunia khususnya di Indonesia cepat tertangani dengan baik dan terselesaikan.

Akhir kata, dengan data analisis ini dapat bermanfaat bagi Anda sebagai referensi pembelajaran Data Science Dasar. Berikut saya sertakan juga source code saya di github : https://gist.github.com/syamdev/d5a45fe3cfd6a9f1073094b1ee8a6e53.

Silakan kunjungi juga Artikel saya di Medium: (coming soon). Bila ada pertanyaan atau masukan, silakan comment di kolom komentar. Terima Kasih

Dataset source:
https://github.com/CSSEGISandData/COVID-19/tree/master/csse_covid_19_data/csse_covid_19_time_series

Tinggalkan Komentar

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *