Data Quality with Python
Apa itu Data Profiling?
Pada bagian sebelumnya, aku sudah mempelajari mengenai exploratory data analysis, dimana Exploratory Data Analysis (EDA) adalah menggunakan pendekatan statistik yang bertujuan untuk menemukan dan meringkas sebuah dataset, mengetahui struktur dan hubungan antar variabel dalam dataset. EDA merupakan proses pre-analysis baik untuk descriptive analysis maupun predictive analysis.
Dalam bab ini, aku akan fokus pada satu aspek EDA, yaitu: Data Profiling!
Data profiling adalah kegiatan merangkum dataset menggunakan statistik deskriptif. Tujuan dari pembuatan data profiling adalah untuk memiliki pemahaman yang kuat tentang data sehingga dapat mulai menyusun framework analisis dan memvisualisasikan data.
Importing Data
Sebagai langkah pertama yang harus dilakukan adalah inisialisasi Library dan mengimport dataset tersebut ke dalam Python menggunakan library Pandas dan diassign sebagai retail_raw.
Library yang perlu diimport adalah: (1) pandas, (2) numpy, (3) io, dan (4) pandas_profiling. Untuk dua libray yang pertama importlah sebagai aliasnya.
Datasetnya tersedia di: 'https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/retail_raw_reduced_data_quality.csv'.
Inspeksi tipe data dengan library Pandas, dapat menjalankan fungsi .dtypes untuk melihat data untuk setiap kolom termasuk tipe datanya
import pandas as pd
import numpy as np
import io
import pandas_profiling
retail_raw = pd.read_csv("https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/retail_raw_reduced_data_quality.csv")
print(retail_raw.dtypes)
""" Output
order_id int64
order_date object
customer_id int64
city object
province object
product_id object
brand object
quantity float64
item_price float64
dtype: object
"""
Descriptive Statistics - Part 1
Di bagian ini, aku akan mempelajari berbagai statistik deskriptif yang dapat digunakan untuk lebih memahami struktur data.
Length
Fungsi len menghitung jumlah pengamatan dalam suatu series / column. Fungsi len akan menghitung semua pengamatan, terlepas dari apakah ada null-value atau tidak (include missing value).
Memulai analisis dengan menginspeksi length dari kolom product_id dari dataframe retail_raw! Aku akan membuat syntaks Python untuk mencapai hal tersebut di code editor. Berikut cara yang akan kulakukan:
# Kolom city
length_city = len(retail_raw['city'])
print('Length kolom city:', length_city)
# Tugas Praktek: Kolom product_id
length_product_id = len(retail_raw['product_id'])
print('Length kolom product_id:', length_product_id)
""" Output
Length kolom city: 5000
Length kolom product_id: 5000
"""
Aku melanjutkan mempelajari ke fungsi berikutnya, yaitu Count.
Count
Fungsi count menghitung jumlah pengamatan non-NA / non-null dalam suatu series / column. Fungsi len akan hanya menghitung elemen dari kolom yang mempunyai nilai (exclude missing value).
Setelah yang tadi cukup lancar, aku berniat mengetahui jumlah non-null value dari kolom product_id dari dataframe retail_raw agar hasil analisisnya lebih lengkap.
# Count kolom city
count_city = retail_raw['city'].count()
print('Count kolom count_city:', count_city)
# Tugas praktek: count kolom product_id
count_product_id = retail_raw['product_id'].count()
print('Count kolom product_id:', count_product_id)
""" Output
Count kolom count_city: 4984
Count kolom product_id: 4989
"""
Missing Value
Dengan Length dan Count, sekarang dapat menghitung jumlah missing-value. Jumlah nilai yang hilang adalah perbedaan antara Length dan Count. Sekarang aku perlu mengetahui jumlah missing-value dari kolom tersebut. Ini artiya aku perlu membuat syntaks untuk menghitung persentase missing-value dari product_id.
# Missing value pada kolom city
number_of_missing_values_city = length_city - count_city
float_of_missing_values_city = float(number_of_missing_values_city/length_city)
pct_of_missing_values_city = '{0:.1f}'.format(float_of_missing_values_city * 100)
print('Persentase missing value kolom city:', pct_of_missing_values_city)
# Tugas praktek: Missing value pada kolom product_id
number_of_missing_values_product_id = length_product_id - count_product_id
float_of_missing_values_product_id = float(number_of_missing_values_product_id/length_product_id)
pct_of_missing_values_product_id = '{0:.1f}%'.format(float_of_missing_values_product_id * 100)
print('Persentase missing value kolom product_id:', pct_of_missing_values_product_id)
""" Output
Persentase missing value kolom city: 0.3
Persentase missing value kolom product_id: 0.2%
"""
Maximum dan Minimum
Fungsi max dan min digunakan untuk mengetahui element terbesar dan terkecil dari suatu kolom di dataframe.
Mean, Medium, Modus dan Standard Deviasi
Fungsi mean, medium, modus dan standard deviasi digunakan untuk mengetahui pemusatan data dan persebarannya.
# Deskriptif statistics kolom quantity
print('Kolom quantity')
print('Minimum value: ', retail_raw['quantity'].min())
print('Maximum value: ', retail_raw['quantity'].max())
print('Mean value: ', retail_raw['quantity'].mean())
print('Mode value: ', retail_raw['quantity'].mode())
print('Median value: ', retail_raw['quantity'].median())
print('Standard Deviation value: ', retail_raw['quantity'].std())
# Tugas praktek: Deskriptif statistics kolom item_price
print('')
print('Kolom item_price')
print('Minimum value: ', retail_raw['item_price'].min())
print('Maximum value: ', retail_raw['item_price'].max())
print('Mean value: ', retail_raw['item_price'].mean())
print('Median value: ', retail_raw['item_price'].median())
print('Standard Deviation value: ', retail_raw['item_price'].std())
""" Output
Kolom quantity
Minimum value: 1.0
Maximum value: 720.0
Mean value: 11.423987164059366
Mode value: 0 1.0
dtype: float64
Median value: 5.0
Standard Deviation value: 29.44202501081146
Kolom item_price
Minimum value: 26000.0
Maximum value: 29762000.0
Mean value: 933742.7311008623
Median value: 604000.0
Standard Deviation value: 1030829.8104242847
"""
Quantile Statistics
Quantiles adalah titik potong yang membagi distribusi dalam ukuran yang sama. Jika akan membagi distribusi menjadi empat grup yang sama, kuantil yang dibuat dinamai quartile. Jika dibagi kedalam 10 sepuluh group yang sama dinamakan percentile. Dalam kasus di bawah ini, ingin membagi distribusi menjadi empat grup atau quartile.
# Quantile statistics kolom quantity
print('Kolom quantity:')
print(retail_raw['quantity'].quantile([0.25, 0.5, 0.75]))
# Tugas praktek: Quantile statistics kolom item_price
print('')
print('Kolom item_price:')
print(retail_raw['item_price'].quantile([0.25, 0.5, 0.75]))
""" Output
Kolom quantity:
0.25 2.0
0.50 5.0
0.75 12.0
Name: quantity, dtype: float64
Kolom item_price:
0.25 450000.0
0.50 604000.0
0.75 1045000.0
Name: item_price, dtype: float64
"""
Correlation
Korelasi adalah cara yang tepat untuk menemukan hubungan antara variabel numerik. Koefisien korelasi berkisar antara -1 hingga 1. Korelasi 1 adalah korelasi positif total, korelasi -1 adalah korelasi negatif total dan korelasi 0 adalah korelasi non-linear.
print('Korelasi quantity dengan item_price')
print(retail_raw[['quantity', 'item_price']].corr())
""" Output
Korelasi quantity dengan item_price
quantity item_price
quantity 1.000000 -0.133936
item_price -0.133936 1.000000
"""
Penggunaan Profiling Libraries
Seperti yang terlihat di atas, mengumpulkan statistik deskriptif dapat menjadi proses yang panjang. Pandas Profiling library memiliki function yang dapat membuat profiling data secara otomatis.
Untuk dapat menggunakannya, cukup dengan memanggil library:
import pandas_profiling
Syntax:
pandas_profiling.ProfileReport(retail_raw)
Mengingat output yang ditampilkan kaya akan penggunaan javascript, maka silakan klik tautan berikut ini untuk dibuka di tab baru browser kamu:
__link__ProfileReport_retail_raw___.html
untuk melihat profiling report dari data frame retail_raw yang telah DQLab buatkan.
Akan dapat memahami proses profiling data yang menerapkan EDA (exploratory data analysis) dari report yang di-generate menggunakan library pandas_profiling melalui method ProfileReport.
Apa itu Data Cleansing?
Data Cleansing berarti proses mengidentifikasi bagian data yang salah, tidak lengkap, tidak akurat, tidak relevan atau hilang dan kemudian memodifikasi, mengganti atau menghapusnya sesuai dengan kebutuhan. Data Cleansing dianggap sebagai elemen dasar dari Data Science.
Missing Data
Dataset yang ditemui di real-world biasanya akan memiliki banyak missing value. Kemampuan untuk treatment missing value sangat penting karena jika membiarkan missing value itu dapat memengaruhi analisis dan machine learning model. Sehingga jika menemukan nilai yang hilang dalam dataset, harus melakukan treatment sedemikian rupa. Cara check kolom yang mempunyai missing value:
nama_dataframe.isnull().any()
Cara treatment terhadap missing-value antara lain:
- Leave as it is (dibiarkan)
- Filling the missing value (imputasi)
- Drop them (hapus row yang mengandung missing value)
Imputasi merupakan suatu metode treatment terhadap missing value dengan mengisinya menggunakan teknik tertentu. Bisa menggunakan mean, modus ataupun menggunakan predictive modelling. Pada modul ini akan membahas mengenai pemanfaatan function fillna dari Pandas untuk imputasi ini, yaitu
nama_dataframe['nama_kolom'].fillna(nama_dataframe.nama_kolom.function())
.function() yang dimaksud pada syntax di atas adalah penggunaa fungsi .mean() atau .mode(). Penggunaan fungsi .mean() atau .mode() ini bergantung pada kondisi yang mengharuskan menggunakan nilai rata - rata atau modus dari kolom yang akan diimputasi, seperti
nama_dataframe['nama_kolom'].fillna(nama_dataframe.nama_kolom.mean())
atau
nama_dataframe['nama_kolom'].fillna(nama_dataframe.nama_kolom.modus())
Drop row yang mengandung missing value. Dapat menggunakan function dropna dari Pandas.
nama_dataframe['nama_kolom'].dropna()
Untuk menangani missing data pada retail_raw,
- Ceklah jika terdapat missing value pada variabel dataframe, dan kemudian cetak ke console
- Imputasi missing value pada kolom quantity dengan menggunaan nilai rataan (mean), dan kemudian cetak ke console
- Drop-lah missing value pada kolom quantity, dan kemudian cetak ke console
# Check kolom yang memiliki missing data
print('Check kolom yang memiliki missing data:')
print(retail_raw.isnull().any())
# Filling the missing value (imputasi)
print('\nFilling the missing value (imputasi):')
print(retail_raw['quantity'].fillna(retail_raw['quantity'].mean()))
# Drop missing value
print('\nDrop missing value:')
print(retail_raw['quantity'].dropna())
""" Output
Check kolom yang memiliki missing data:
order_id False
order_date False
customer_id False
city True
province True
product_id True
brand False
quantity True
item_price True
dtype: bool
Filling the missing value (imputasi):
0 10.0
1 2.0
2 8.0
3 4.0
4 2.0
Name: quantity, dtype: float64
Drop missing value:
0 10.0
1 2.0
2 8.0
3 4.0
4 2.0
Name: quantity, dtype: float64
"""
melengkapi missing value tersebut dengan mean dari item_price. Berikut caraya:
print(retail_raw['item_price'].fillna(retail_raw['item_price'].mean()))
""" Output
0 7.400000e+05
1 6.040000e+05
2 1.045000e+06
3 2.050000e+05
4 9.337427e+05
5 5.200000e+05
...
4995 4.500000e+05
4996 1.465000e+06
4997 7.470000e+05
4998 6.950000e+05
4999 1.045000e+06
Name: item_price, Length: 5000, dtype: float64
"""
Outliers
Outliers merupakan data observasi yang muncul dengan nilai-nilai ekstrim. Yang dimaksud dengan nilai-nilai ekstrim dalam observasi adalah nilai yang jauh atau beda sama sekali dengan sebagian besar nilai lain dalam kelompoknya.
Cara treatment terhadap outliers antara lain:
- Remove the outliers (dibuang)
- Filling the missing value (imputasi)
- Capping
- Prediction
Pada umumnya, outliers dapat ditentukan dengan metric IQR (interquartile range).
Rumus dasar dari IQR: Q3 - Q1, dan data suatu observasi dapat dikatakan outliers jika memenuhi kedua syarat dibawah ini:
- < Q1 - 1.5 * IQR
- > Q3 + 1.5 * IQR
Syntax di Python:
Q1 = nama_dataframe.quantile(0.25)
Q3 = nama_dataframe.quantile(0.75)
IQR = Q3 - Q1
Kemudian untuk membuang outliersnya:
nama_dataframe = nama_dataframe[~(((nama_dataframe < (Q1 - 1.5*IQR)) | nama_dataframe > (Q2 - 1.5*IQR)))]
# Q1, Q3, dan IQR
Q1 = retail_raw['quantity'].quantile(0.25)
Q3 = retail_raw['quantity'].quantile(0.75)
IQR = Q3 - Q1
# Check ukuran (baris dan kolom) sebelum data yang outliers dibuang
print('Shape awal: ', retail_raw.shape)
# Removing outliers
retail_raw = retail_raw[~((retail_raw['quantity'] < (Q1 - 1.5 * IQR)) | (Q1 - 1.5 * retail_raw['quantity'] > (Q3 - 1.5 * IQR)))]
# Check ukuran (baris dan kolom) setelah data yang outliers dibuang
print('Shape akhir: ', retail_raw.shape)
Deduplikasi Data
Duplikasi data merupakan data dengan kondisi pada row-row tertentu memiliki kesamaan data di seluruh kolomnya. Tentunya ada data yang duplikat dalam dataset yang dimiliki. Kondisi duplikasi harus diatasi dengan jalan mengeliminir baris yang mengalami duplikasi, sehingga proses ini dikenal dengan deduplikasi.
Untuk mencek duplikasi data:
nama_dataframe.duplicated(subset=None)
Syntax untuk membuang duplikasi:
nama_dataframe.drop_duplicates()
# Check ukuran (baris dan kolom) sebelum data duplikasi dibuang
print('Shape awal: ', retail_raw.shape)
# Buang data yang terduplikasi
retail_raw.drop_duplicates(inplace=True)
# Check ukuran (baris dan kolom) setelah data duplikasi dibuang
print('Shape akhir: ', retail_raw.shape)