Hotel Booking Demand dengan Analisis Python
Python telah menjadi bahasa pemrograman yang sangat populer dalam analisis data, karena adanya ekosistem yang kaya dengan pustaka dan alat-alat yang mendukung analisis data. Kecanggihan, kemudahan penggunaan, dan kemudahan membuat program adalah alasan mengapa Python menjadi bahasa yang sangat cocok untuk analisis data dan pemodelan.
NumPy adalah salah satu pustaka Python yang paling penting dalam analisis data, digunakan untuk operasi numerik dan manipulasi matriks. Pustaka ini menawarkan berbagai macam fungsi untuk komputasi linear algebra, pengolahan citra, dan analisis data, menjadikannya alat yang penting dalam memproses data secara efisien.
Pandas adalah pustaka Python yang dapat digunakan untuk memproses dan menganalisis data dalam bentuk data frame, yang memungkinkan pengguna untuk mengelola data dengan mudah. Pandas menyediakan berbagai macam fungsi untuk memfilter, mengurutkan, dan memanipulasi data dengan mudah, menjadikannya pilihan yang populer untuk analisis data.
Matplotlib adalah pustaka visualisasi data dalam Python, menyediakan berbagai macam grafik, grafik garis, dan visualisasi yang berbeda untuk membantu pengguna memvisualisasikan data mereka. Pustaka ini memiliki antarmuka pengguna yang mudah digunakan dan menawarkan fleksibilitas untuk membuat berbagai macam tampilan.
Secara keseluruhan, Python adalah bahasa pemrograman yang sangat populer dan berguna dalam analisis data. Keunggulannya dalam memproses dan menganalisis data membuatnya menjadi alat yang sangat bermanfaat untuk para analis data dan ilmuwan data dalam berbagai industri, termasuk keuangan, kesehatan, dan teknologi. Python akan terus menjadi bahasa pemrograman yang penting dalam analisis data dan pemodelan di masa depan.
Setelah kita memahami Python, dalam pembahasan kali ini akan membahas pertanyaan bisnis dari dataset Hotel Booking Demand.
Sebelumnya, langkah pertama yang harus dilakukan untuk menganalisis data menggunakan pyhton dapat dilakukan dengan cara mengimport beberapa library yang akan digunakan. Berikut ini contoh untuk import library yang akan gunakan:
mport pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import re
sns.set()
Library yang dibutuhkan tersebut adalah pandas, numpy, matplotlib, dan seaborn. Kemudian ada library se yang digunakan sebagai regular expression. Lalu terdapat sns.set untuk mengatur default settingan dari visualisasi seaborn.
Setelah itu, hal yang kita perlukan adalah dengan memasukkan dataset yang sudah ada yaitu dengan cara seperti berikut:
df_hotels = pd.read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-02-11/hotels.csv')
df_hotels.head()
Dalam memasukkan data tersebut, kita dapat menggunakan tidytuesday untuk merapikan data tersebut dengan urlnya. File tersebut merupakan file dengan jenis csv. Di mana dataset tersebut tersimpan dalam variabel yaitu df_hotels. Jika kita ingin melihat isi dari dataset tersebut, maka dapat digunakan fungsi info seperti syntax dibawah ini:
Maka kita dapat melihat hasilnya yaitu:
Dari output tersebut, kita dapat mengetahui bahwa pada dataset tersebut terdapat 32 column dengan banyak tipe data. Kita juga dapat lihat bahwa tabel tersebut belum memiliki primary key atau kolom identifier. Sehingga kita akan menganggap bahwa jika setiap row adalah unik dengan memberikan kolom id sebagai unique identifier dengan menggunakan syntax seperti berikut:
df_hotels = df_hotels.reset_index().rename(columns={'index':'id'})
df_hotels
Hasil dari syntax tersebut akan menghasilkan output seperti berikut:
Lalu kita melakukan pengecekan pada column df_hotels seperti berikut:
Kita juga melakukan pengecekan tipe data pada column df hotels seperti berikut:
Selain itu, kita melakukan pengecekan terhadap jumlah Null value seperti berikut:
Di mana:
- sum(axis=0) = filter by row/baris
- sum(axis=1) = filter by columns
Selanjutnya pengecekan jumlah unique value seperti berikut:
Dari langkah-langkah yang kita lakukan, maka selanjutnya kita menyelesaikan beberapa pertanyaan untuk kasus ini seperti berikut:
Nomor 1
Buatlah fungsi dengan :
* 1 argumen berupa dataframe untuk mengecek data type,
* untuk mengecek jumlah null value,
* untuk mengecek percent null value,
* serta jumlah unique value tiap kolom yang ada di sebuah dataframe
Untuk menyelesaikan masalah tersebut digunakan code sebagai berikut.
def check_values(df):
data = []
for col in df.columns:
data.append([col, \
df[col].dtype, \
df[col].isna().sum(), \
round(100*(df[col].isna().sum() / len(df)),2), \
df[col].nunique()
])
return pd.DataFrame(columns=['dataFeatures', 'dataType', 'null', 'nullPct', 'unique'],data=data)
Kode tersebut merupakan sebuah fungsi Python dengan nama check_values yang digunakan untuk memeriksa dan mengembalikan informasi statistik mengenai setiap kolom dalam sebuah dataframe yang diberikan sebagai input.
Berikut adalah penjelasan dari setiap baris kode dalam fungsi check_values:
data = []: Membuat sebuah list kosong dengan nama data yang akan digunakan untuk menyimpan informasi statistik setiap kolom dalam dataframe.
for col in df.columns: Melakukan iterasi untuk setiap kolom dalam dataframe df.
data.append([col, df[col].dtype, df[col].isna().sum(), round(100*(df[col].isna().sum() / len(df)),2), df[col].nunique()]): Menambahkan informasi statistik untuk setiap kolom dalam bentuk list ke dalam list data.
col: Nama dari kolom.
df[col].dtype: Tipe data dari kolom.
df[col].isna().sum(): Jumlah nilai null pada kolom.
round(100*(df[col].isna().sum() / len(df)),2): Presentase jumlah nilai null pada kolom terhadap total baris pada kolom (dalam satuan persen, dibulatkan ke 2 desimal).
df[col].nunique(): Jumlah nilai unik dalam kolom.
return pd.DataFrame(columns=[‘dataFeatures’, ‘dataType’, ‘null’, ‘nullPct’, ‘unique’],data=data): Mengembalikan sebuah dataframe yang berisi informasi statistik untuk setiap kolom dalam dataframe df.
columns=[‘dataFeatures’, ‘dataType’, ‘null’, ‘nullPct’, ‘unique’]: Menentukan nama kolom untuk dataframe yang akan dibuat.
data=data: Menentukan data yang akan dimasukkan ke dalam dataframe yang akan dibuat.
Fungsi check_values ini dapat digunakan untuk melakukan pemeriksaan awal terhadap kualitas data dalam sebuah dataframe. Informasi statistik yang dihasilkan oleh fungsi ini dapat membantu pengguna dalam menentukan tindakan koreksi yang perlu dilakukan terhadap data tersebut.
check_values(df_hotels)
check_values(df_hotels) merupakan pemanggilan fungsi check_values dengan df_hotels sebagai argumen yang merupakan sebuah dataframe. Fungsi check_values akan memeriksa dan mengembalikan informasi statistik mengenai setiap kolom dalam dataframe df_hotels.
Informasi statistik yang dihasilkan meliputi nama kolom (dataFeatures), tipe data (dataType), jumlah nilai null (null), presentase jumlah nilai null terhadap total baris pada kolom (nullPct), dan jumlah nilai unik (unique) dalam kolom.
Pemanggilan check_values(df_hotels) dapat membantu pengguna dalam memeriksa kualitas data pada dataframe df_hotels dan menentukan tindakan koreksi yang perlu dilakukan jika ditemukan nilai null atau data yang tidak sesuai.
Ouput dari sintax tersebut adalah sebagai berikut:
Nomor 2
Ada berapa berapa jumlah pengunjung yang membatalkan reservasi dan yang tidak? Dan dari jumlah tersebut buatlah kesimpulan mengenai proporsi masing-masing!
Berikut code yang digunakan untuk menjawab pertanyan di atas
df_hotels.is_canceled.value_counts()
df_hotels.is_canceled.value_counts() adalah sebuah fungsi pada objek dataframe df_hotels yang digunakan untuk menghitung jumlah kemunculan dari setiap nilai pada kolom is_canceled. Kolom is_canceled merupakan sebuah kolom dalam dataframe df_hotels yang menandakan apakah suatu reservasi hotel telah dibatalkan atau tidak.
Fungsi value_counts() menghitung jumlah kemunculan setiap nilai pada kolom is_canceled dan mengembalikan sebuah objek Series dengan nilai-nilai unik pada kolom sebagai indeks dan jumlah kemunculan setiap nilai sebagai nilai pada indeks tersebut. Objek Series ini secara otomatis diurutkan berdasarkan jumlah kemunculan nilai yang paling banyak.
Pemanggilan df_hotels.is_canceled.value_counts() dapat membantu pengguna dalam memahami distribusi data pada kolom is_canceled dan mengevaluasi proporsi reservasi hotel yang dibatalkan dan tidak dibatalkan dalam dataset.
Berikut hasil yang dikeluarkan
Kemudian untuk membuat kesimpulan mengenai proporsi digunakan code berikut.
df_hotels.is_canceled.value_counts(normalize=True)
df_hotels.is_canceled.value_counts(normalize=True) adalah sebuah fungsi pada objek dataframe df_hotels yang digunakan untuk menghitung proporsi setiap nilai pada kolom is_canceled. Kolom is_canceled merupakan sebuah kolom dalam dataframe df_hotels yang menandakan apakah suatu reservasi hotel telah dibatalkan atau tidak.
Fungsi value_counts() pada kode tersebut dengan argumen normalize=True akan menghitung proporsi setiap nilai pada kolom is_canceled dan mengembalikan sebuah objek Series dengan nilai-nilai unik pada kolom sebagai indeks dan proporsi kemunculan setiap nilai sebagai nilai pada indeks tersebut. Proporsi kemunculan setiap nilai dihitung dengan membagi jumlah kemunculan setiap nilai dengan total jumlah baris pada kolom tersebut.
Berikut ini adalah output yang dihasilkan:
Selanjutnya untuk memvisualisasikan proporsi dari data tersebut gunakan kode berikut.
sns.countplot(data=df_hotels, x='is_canceled')
plt.title('Cancelled')
plt.show()
Kode tersebut menggunakan library Seaborn untuk membuat sebuah grafik countplot. Grafik countplot digunakan untuk memvisualisasikan jumlah kemunculan setiap nilai pada suatu kolom.
Pada kode tersebut, grafik countplot akan menampilkan jumlah kemunculan setiap nilai pada kolom is_canceled dari dataframe df_hotels. Kolom is_canceled merupakan sebuah kolom dalam dataframe df_hotels yang menandakan apakah suatu reservasi hotel telah dibatalkan atau tidak.
Argumen x=’is_canceled’ pada fungsi sns.countplot() menunjukkan bahwa sumbu x dari grafik akan menampilkan nilai pada kolom is_canceled.
Setelah itu, terdapat fungsi plt.title(‘Cancelled’) yang digunakan untuk memberi judul pada grafik, dengan judul “Cancelled”.
Terakhir, plt.show() digunakan untuk menampilkan grafik yang telah dibuat.
Berikut visualisasi yang dihasilkan dengan kode di atas
Dengan memvisualisasikan data dalam bentuk grafik countplot, kita dapat dengan lebih mudah memahami distribusi data pada kolom is_canceled, yaitu dengan melihat jumlah reservasi hotel yang dibatalkan dan tidak dibatalkan dalam dataset.
Nomor 3
A. Untuk “City Hotel”, berapa persen reservasi yang dibatalkan?
Dalam menjawab hal tersebut, hal yang perlu kita lakukan adalah mengkondisikan table df_hotels yang jenis hotelnya adalah ‘City Hotel’. Dari hal tersebut, kita dapat mengetahui seberapa besar reservasi yang dibatalkan untuk jenis hotel yang bernilai ‘City Hotel’. Kita dapat mencari value dari is_canceled untuk jenis hotel “City Hotel” yang bernilai true menggunakan syntax value_counts seperti berikut ini:
df_hotels[df_hotels.hotel=='City Hotel'].is_canceled.value_counts(normalize=True)
Di mana hasilnya akan menampilkan nilai 0 yang berarti untuk nilai False dan 1 untuk bernilai True seperti berikut:
Name: is_canceled, dtype: float64
maka didapatkan hasil dari nilai True untuk value is_canceled adalah 0.41727 dengan tipe data float.
B. Untuk “Resort Hotel”, berapa persen reservasi yang dibatalkan?
Dari visualisasi diatas persentasi booking yang dibatalkan di Resort Hotel sebesar 9.32% dan pembatalan di City Hotel sebesar 27.73%
C. Di hotel jenis apa ditemukan proposi reservasi yang dibatalkan lebih besar?
Pada hasil yang telah kita dapatkan, terbukti bahwa City Hotel memiliki presentase reservasi yang dibatalkan lebih besar yaitu sebesar 27.73%, sedangkan untuk Resort Hotel memiliki presentase reservasi yang dibatalkan lebih kecil yaitu 9.32%.
Nomor 4
Lakukan filter sehingga hanya menampilkan data pengunjung yang tidak membatalkan reservasi. Dan simpan hasilnya dalam variabel df_checkout.
Dalam menyelesaikan pertanyaan tersebut, kita dapat menggunakan cara untuk membuat variable df_checkout dengan isi df_hotels yang telah dikondisikan untuk memfilter sehingga hanya menampilkan data pengunjung yang tidak membatalkan reservasi dengan menggunakan statement seperti ini di bawah ini:
df_hotels[df_hotels.is_canceled==0]
Maka akan menghasilkan output seperti berikut:
Setelah mendapatkan hasil tersebut, maka kita gunakan syntax dalam mengetahui panjang row dan lebar column tersebut seperti berikut ini:
df_checkout = df_hotels[df_hotels.is_canceled==0]
df_checkout.shape
Maka akan menghasilkan seperti berikut:
Di mana pada fungsi shape digunakan untuk mengetahui jumlah baris dan total atau jumlah kolom pada dataframe.
Nomor 5
A. Tampilkan jumlah reservasi tiap bulan kedatangan untuk masing-masing jenis hotel.
B. Lalu di bulan apa terdapat reservasi yang paling banyak di masing-masing jenis hotel? Buatlah kesimpulan apakah trennya sama di kedua jenis hotel?
C. Lakukan seperti point B namun dengan nama bulan yang sudah di-mapping menjadi bulan dalam angka
- (!) Untuk pertanyaan ini dan selanjutnya akan menggunakan dataframe `df_checkout`
- Step awal yang harus dilakukan adalah menggunakan data frame df_checkout
df_checkout.is_canceled.value_counts()
Lalu lanjut dengan dengan mengecek tiap arrival month pada hotel untuk menampilkan tren
df_checkout.groupby(['hotel','arrival_date_month']).size()
Maka hasil yang akan di dapat adalah :
Lalu dengan metode nunique untuk pengecekan
df_checkout.groupby(['hotel','arrival_date_month'])['id'].nunique()
Maka hasil yang didapatkan adalah
Lalu kita diminta mengecek pada bulan-bulan yang memiliki reservasi yang tinggi
Yang harus kita lakukan adalah melakukan mapping nama bulan menjadi bulan dalam angka :
import calendar
month_dict = {month: index for index, month in enumerate(calendar.month_name) if month}
month_dict
Maka hasil yang akan bisa kita dapatkan
Di langkah ini, tiap baris dari kolom arrival_date_month yang berisi nama bulan akan di-mapping ke angka yang sesuai
df_checkout['arrival_date_month_num'] = df_checkout['arrival_date_month'].map(month_dict)
Maka hasil yang didapatkan adalah
Lanjut dengan menggunakan syntax
df_checkout.groupby(['hotel','arrival_date_month_num']).size()
Maka kita akan mendapatkan hasil
Lalu dengan metode countplot kita akan memperoleh visualisasi infografis dari hasil tersebut :
sns.countplot(data=df_checkout, x='arrival_date_month_num')
Maka hasil yang didapatkan adalah
Selanjutnya membandingkan jumlah reservasi antara city hotel dengan resort hotel dengan metode countplot juga
sns.countplot(data=df_checkout, x='arrival_date_month_num',hue='hotel')
plt.xlabel('bulan kedatangan')
plt.ylabel('jumlah reservasi')
plt.show()
Maka infografis perbandingan keduanya adalah
Disini lah kita bisa melihat bahwa reservasi city hotel lebih tinggi daripada resort hotel
Nomor 6
A. Buat sebuah kolom baru bernama arrival_date yang berisi info lengkap tentang tahun, bulan, dan tanggal kedatangan.
B. Ubah kolom menjadi tipe datetime.
Hint: gabungkan tahun, bulan, dan tanggal menjadi format yyyy-mm-dd
A. Langkah 1: mengubah kolom arrival_date_month_num menjadi string,yaitu dengan cara ini
df_checkout.arrival_date_month_num.astype('str')
Maka hasil yang akan kita dapatkan adalah :
Selanjutnya adalah
langkah 1: mengubah kolom arrival_date_month_num menjadi string
# langkah 2: lalu menambahkan zero padding, sehingga ‘1’ menjadi ‘01’ → langkah 2 di-chain dengan langkah 1
df_checkout.arrival_date_month_num.astype('str').str.pad(2,fillchar='0')
Lalu langkah berikutnya adalah
df_checkout['arrival_date_year'].astype('str') + '-' +\
df_checkout.arrival_date_month_num.astype('str').str.pad(2,fillchar='0') + '-' +\
df_checkout.arrival_date_day_of_month.astype('str').str.pad(2,fillchar='0')
Maka hasil yang akan didapakan adalah :
df_checkout['arrival_date'] = \
df_checkout['arrival_date_year'].astype('str') + '-' +\
df_checkout.arrival_date_month_num.astype('str').str.pad(2,fillchar='0') + '-' +\
df_checkout.arrival_date_day_of_month.astype('str').str.pad(2,fillchar='0')
Lalu akan muncul seperti ini :
Lanjut mengecek arrival date :
df_checkout['arrival_date']
Lalu mengujinya dengan
df_checkout.arrival_date.dtype
Dan kita mencoba mengubah kolom menjadi tipe date time,maka langkah yang harus kita lakukan adalah ubah arrival_date dari string menjadi datetime dengan cara :
df_checkout['arrival_date'] = pd.to_datetime(df_checkout.arrival_date)
df_checkout['arrival_date']
Maka dengan syntax diatas maka akan memunculkan hasil seperti ini :
Untuk step terakhir yang perlu dilakukan adalah
df_checkout.arrival_date.dtype
Dan akhirnya seperti ini :
Nomor 7
Mari kita bermain dengan time-series data menggunakan kolom arrival_date. Buat 2 dataframe yang menunjukkan sbb:
- total reservasi harian (df_reservasi_perhari)
- rata-rata reservasi harian di tiap minggu (df_avg_reservasi_harian)
(!) Stop and think!
Apa perbedaan data yang ditunjukkan oleh df_reservasi_perhari dan df_avg_reservasi_harian?
Pada soal ini, kita diminta untuk membuat dua tabel baru bernama df_reservasi_perhari dan df_avg_reservasi_harian. Untuk membuat tabel baru, kita akan mengekstraknya dari tabel df_checkout karena kolom arrival_date ada di tabel tersebut. Untuk menjawab pertanyaan ini, Pertama kita harus mencari kode df_reservasi_perhari.
Kodenya adalah sebagai berikut
df_reservasi_perhari = df_checkout.resample('D',on='arrival_date').size().reset_index().rename(columns={0:'total_reservasi'})
df_reservasi_perhari
inilah hasilnya :
Setelah kita menemukan df_reservasi_perhari, kita harus mencari df_avg_reservasi_harian dan berikut kodenya :
df_avg_reservasi_harian = df_checkout.resample('D',on='arrival_date').size().reset_index().rename(columns={0:'total_reservasi'}).\
resample('W',on='arrival_date')['total_reservasi'].mean().reset_index()
Df_avg_reservasi_harian
Mari kita bahas maksud dari sintaks. fungsi resample() digunakan untuk mengelompokkan data arrival_date berdasarkan D (day) yang berarti hari. Fungsi size() digunakan untuk menghitung setiap kelompok hari. Sedangkan fungsi reset_index() digunakan untuk membuat indeks baru dimana indeks sebelumnya adalah arrival_date dan output arrival_date menjadi kolom baru. fungsi rename() digunakan untuk mengubah nama kolom yang sebelumnya 0 menjadi total_reservation. inilah hasilnya:
Setelah kita selesai mendapatkan hasil dari df_reservasi_perhari dan df_avg_reservasi_harian. Kemudian kita harus menemukan grafik visual. Pada soal nomor 7 ini kita menggunakan grafik lineplot. Jadi inilah kodenya :
plt.figure(figsize=(10,4))
sns.lineplot(data=df_reservasi_perhari, x='arrival_date', y='total_reservasi')
plt.title('Reservasi Harian', fontsize='x-large')
plt.show()
setelah memasukan kode yang harus kita cari untuk lineplot chart inilah hasilnya :
Berikut lineplot dari df_reservasi_perhari. Nah selanjutnya kita cari kode df_avg_reservasi_harian. Jadi inilah kodenya:
plt.figure(figsize=(10,4))
sns.lineplot(data=df_avg_reservasi_harian, x='arrival_date', y='total_reservasi')
plt.title('Rata-Rata Reservasi Harian', fontsize='x-large')
plt.show()
setelah memasukan kode yang harus kita cari untuk lineplot chart inilah hasilnya :
Ini semua jawaban nomor 7 setelah kita cari total reservasi harian (df_reservasi_perhari), rata-rata reservasi harian tiap minggu (df_avg_reservasi_harian), dan selisih antara data yang ditampilkan df_reservasi_perhari dan df_avg_reservasi_harian.
Nomor 8
A. Berapa rata-rata ADR berdasarkan jenis hotel dan jenis customer (customer_type)?
B. Jenis customer mana yang memiliki ADR paling besar di masing-masing jenis hotel?
Untuk menjawab pertanyaan ini, pertama kita cari kode ADR rata-rata berdasarkan tipe hotel dan tipe pelanggan (customer_type). Berikut adalah kodenya :
df_checkout.groupby(['hotel','customer_type'])['adr'].mean()
setelah memasukan kode inilah hasilnya :
“Jenis customer mana yang memiliki ADR paling besar di masing-masing jenis hotel?” kita harus menemukan visual chart. Pada soal nomor 8 ini kita menggunakan boxplot. Berikut adalah kodenya :
plt.figure(figsize=(8,6))
sns.boxplot(data=df_checkout, x='adr', y='hotel',hue='customer_type')
plt.show()
Dari hasil sintaks terlihat bahwa ADR rata-rata tertinggi berasal dari tipe City Hotel dan tipe pelanggan Transient. Sedangkan rata-rata ADR terendah berasal dari tipe Resort Hotel dan tipe pelanggan Transient-Party. setelah memasukan kode inilah hasilnya :
Ini semua jawaban nomor 8 setelah kita rata-rata ADR berdasarkan tipe hotel dan tipe customer (customer_type) dan tipe customer mana yang memiliki ADR terbesar di tiap tipe hotel.
Dalam artikel ini, kita telah membahas 8 pertanyaan seputar kasus Python untuk analisis data, mulai dari cara mengimpor data, memanipulasi data, hingga visualisasi data. Dari pembahasan di atas, kita dapat menyimpulkan bahwa Python merupakan bahasa pemrograman yang sangat berguna dalam melakukan analisis data. Dengan menggunakan Python, kita dapat mengolah data dengan mudah, memvisualisasikan data, dan mengekstrak informasi berharga dari data yang ada. Teruslah belajar dan berlatih, karena kemampuan dalam Python akan sangat berguna dalam dunia kerja maupun bisnis. Semoga artikel ini bermanfaat bagi Anda!