Let’s Code: Descriptive Statistics Program for CSV Data from Scratch!
Apa itu Statistika Deskriptif?
Secara sederhananya, statistika deskriptif adalah proses untuk meringkas, mengorganisir, dan menganalisis sebuah data populasi berdasarkan himpunan data sample. Biasanya proses ini berada di step pertama yaitu eksplorasi data dari siklus hidup data science. Statistika deskriptif menjadi sangat penting karena kita dengan cepat dapat memahami karakteristik dan pola data yang kita punya yang nantinya akan menjadi dasar untuk pengambilan keputusan dan pemilihan model.
Jenis Statistika Deskriptif
Umumnya, statistika deskriptif dibagi menjadi 2 jenis pengukuran, yaitu:
- Measures of Central Tendency
Di pengukuran jenis ini terdapat mean, median, dan mode - Measures of Dispersion
Di pengukuran jenis ini terdapat range, standar deviasi, dan quartiles.
Namun, pada kali ini kita hanya akan membuat code untuk mean, median, quartiles, dan standar deviasi.
Measures of Central Tendency
Terkadang kita akan dihadapi oleh data yang berukuran sangat besar, alih-alih melihat keseluruhan data agar dapat memahami karakteristik data kita, menggunakan satu nilai yang merepresentasikan pusat dari data yang kita punya akan jauh lebih cepat dan mudah. Ini lah kegunaan dari measure of central tendency.
Mean
Mean berguna untuk melihat nilai rata-rata dari sebuah dataset. Namun, yang perlu diperhatikan adalah mean akan sangat berguna jika kita bekerja dengan data yang terdistribusi normal. Data dikatakan terdistribusi normal apabila sebaran data tersebut terlihat simetris, berikut contohnya:
Dapat dilihat pada gambar di atas, apabila data kita terdistribusi normal/simetris maka nilai mean, median, dan mode akan berada tepat di tengah sebaran data. Kembali lagi, mengapa mean hanya akan bekerja dengan sangat baik hanya ketika data berdistribusi normal? Jawabannya, karena mean sangat sensitif terhadap data outlier. Outlier dari sebuah data akan membuat mean bergeser/cenderung mendekat ke arah outlier tersebut. Namun jangan khawatir, kita dapat mengatasi permasalahan ini di penjelasan berikutnya.
Outlier adalah data atau nilai yang berbeda secara signifikan dari nilai-nilai lain dalam suatu kumpulan data atau sampel. Biasanya disebabkan oleh banyak faktor, salah satunya ialah pengamatan yang salah.
Perhitungan mean sebagai berikut:
- xi = Data urutan ke-i
- n = Jumlah data
Setelah kita tahu rumusnya, kita dapat langsung menerapkannya code python.
def mean(data):
n = len(data)
sum_number = 0
for i in range(n):
sum_number += data[i]
mean_number = sum_number/n
return round(mean_number, 4) # rounded to 4 decimal places
Kita memanfaatkan for loop untuk summation, namun opsi lainnya kita juga bisa dengan cepat menggunakan library numpy untuk melakukan summation.
Median
Masih ingat permasalahan mean dengan outlier? Ya, kita bisa mengatasi permasalahan tersebut dengan median. Median dikenal sangat ampuh melawan data outlier dan sebaran data dengan kecenderungan yang cukup parah. Hal ini karena median memanfaatkan sebaran data untuk merepresentasikan nilai tengah, namun median memiliki syarat yaitu data harus dalam kondisi terurut sebelum dilakukan perhitungan.
Meskipun median cukup ampuh mengatasi outlier, namun pada kasus tertentu jika outlier memiliki pengaruh yang signifikan terhadap kumpulan data secara keseluruhan justru akan memengaruhi interpretasi dari median. Oleh sebab itu, kita tidak hanya mengandalkan median, melainkan perlu juga untuk mengatasi data outlier.
Perhitungan median sebagai berikut:
Perlu diingat, kita harus mengurutkan data terlebih dahulu sebelum melakukan perhitungan. Kali ini aku menggunakan algoritma merge sort untuk mengurutkan data. Jika kamu merasa unfamiliar dengan istilah/algoritma tersebut, ini beberapa artikel yang mungkin bisa kamu baca agar dapat memahami algoritma merge sort:
- A Simplified Explanation of Merge Sort | by Karuna Sehgal | Karuna Sehgal | Medium
- Merge Sort Algorithm — GeeksforGeeks
Alasan aku memilih algoritma merge sort dibandingkan algoritma yang lain sederhananya karena merge sort merupakan algoritma yang cukup baik dan cepat ketika mengatasi data yang berukuran besar dengan kecepatan O(n log n). Merge sort akan cocok dengan tujuan program kita yang menghitung statistika deskriptif untuk data csv yang biasanya memiliki jumlah baris dan kolom yang sangat banyak.
Oke, sekarang kita hanya perlu mengimplementasikannya ke python
def merge_sort(data):
if len(data) > 1:
mid = len(data)//2
left = data[:mid]
right = data[mid:]
merge_sort(left)
merge_sort(right)
i = j = k = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
data[k] = left[i]
i += 1
else:
data[k] = right[j]
j += 1
k += 1
while i < len(left):
data[k] = left[i]
i += 1
k += 1
while j < len(right):
data[k] = right[j]
j += 1
k += 1
return data
def minimum(data):
return merge_sort(data)[0] # gets the first item from the sorted list
def maximum(data):
return merge_sort(data)[-1] # gets the last item from the sorted list
def median(data):
data = merge_sort(data)
mid = len(data) // 2
if len(data) % 2 == 0: # if n data is even
return (data[mid-1] + data[mid])/2
else: # if n data is odd
return data[mid]
Selain dapat melakukan perhitungan median, data yang telah terurut dapat memberikan kita informasi terkait nilai minimum dan maksimum dari sebuah kumpulan data.
Measures of Dispersion
Measure of central tendency tidak memberikan informasi tentang seberapa jauh nilai-nilai dari data tersebut tersebar dari nilai rata-rata atau nilai tengah. Sehingga measures of dispersion menjadi sangat penting untuk mengetahui seberapa besar keragaman data dalam kumpulan data. Selain itu, measure of dispersion dapat membantu kita untuk mengidentifikasi outlier dari sebuah data.
Quartiles
Kuartil berguna untuk menjelaskan pembagian dari sekumpulan data menjadi 4 bagian dan membuat 3 titik berdasarkan nilai data yang diberikan. Kuartil sangat mudah ditemukan ketika kita menggunakan box plot.
Berdasarkan gambar di atas, tiga titik yang dimaksud ialah Q1, Q2 (median), dan Q3. Masing-masing titik tersebut membagi data dengan ukuran 25% tiap bagiannya. Kuartil dapat berguna untuk mengetahui letak outlier dari sebuah data dengan menggunakan perhitungan IQR (Interquartile Range).
Rumus dari kuartil dan pengimplementasian code nya sebagai berikut:
def quartile_1(data):
n = len(data)
data = merge_sort(data)
mid = n//2
if n % 2 == 0:
lower_half = data[:mid]
return median(lower_half)
else:
lower_half = data[:mid+1]
return median(lower_half)
def quartile_3(data):
n = len(data)
data = merge_sort(data)
mid = n//2
if n % 2 == 0:
upper_half = data[mid:]
return median(upper_half)
else:
upper_half = data[mid+1:]
return median(upper_half)
Pada dasarnya, Q1 dan Q3 ialah membagi data di sebelah kiri dan kanan. Oleh karena itu, kita dapat memanfaatkan perhitungan median untuk mencari nilai Q1 dan Q3.
Standar Deviasi
Standar deviasi berguna untuk mengukur seberapa jauh nilai-nilai dalam kumpulan data tersebar dari nilai tengah (mean). Penggabungan antara mean dan standar deviasi memberikan informasi yang lebih lengkap terkait sebaran data. Semakin kecil nilai standar deviasi, artinya semakin sedikit data yang tersebar dari nilai tengah dan semakin homogen data yang kita miliki. Sebaliknya, semakin besar nilai standar deviasi, artinya semakin banyak data yang tersebar dari nilai tengah dan semakin heterogen data yang kita miliki.
Informasi tentang apakah data tersebut homogen atau heterogen sangat penting apabila kita ingin melakukan berbagai analisis seperti analisis regresi, pengujian hipotesis, dan pemodelan statistik. Meskipun terdapat uji statistik lainnya untuk mengetahui data tersebut homogen atau heterogen, namun dengan melihat standar deviasi kita akan memiliki gambaran awal yang lebih cepat terkait data tersebut.
Rumus dari standar deviasi sebagai berikut:
Berdasarkan rumus tersebut, perhitungan standar deviasi ternyata memanfaatkan rumus variansi atau dengan kata lain standar deviasi merupakan akar dari variansi.
Berikut pengimplementasiannya di python
def squared_diff(data):
mean_num = mean(data)
return [(x-mean_num)**2 for x in data]
def variance(data):
sum_num = 0
n = len(data)
for i in range(n):
sum_num += squared_diff(data)[i]
return sum_num / (n-1)
def std_dev(data):
return (variance(data))**0.5
Data Summarization
Oke, karena kita sudah membuat fungsi untuk menghitung mean, median, kuartil 1, kuartil 3, dan standar deviasi, langkah terakhir kita akan mengumpulkan semua menjadi satu. Aku ingin hasilnya berbentuk seperti ketika kita menggunakan fungsi desribe() di python. Oleh sebab itu kita perlu menggabungkan semuanya dan menampilkannya ke dalam bentuk dataframe.
# combine all the above functions into a dictionary
def prep_main(data):
numeric_cols = data.select_dtypes(include=['float64', 'int64']).columns.tolist() # selects only columns of type numeric to be processed
data_numeric = data[numeric_cols]
data_dict = {}
for i in data_numeric.columns:
data_dict[i] = data_numeric[i].values.tolist() # make a numeric column into a list
get_value = data_dict.get(i, 0) # takes a value in the form of a list from the i-order dictionary
mean_num = mean(get_value)
minimum_num = minimum(get_value)
maksimum_num = maximum(get_value)
median_num = median(get_value)
q1 = quartile_1(get_value)
q3 = quartile_3(get_value)
std = std_dev(get_value)
data_dict[i] = [mean_num, minimum_num, maksimum_num, q1, median_num, q3, std] # change the value of the i order dictionary
data_dict[''] = ['mean', 'min', 'max', '25%', '50%', '75%', 'std'] # prepare a label for the row index
return data_dict
# convert to dataframe format
def descript_stat(data):
import pandas as pd
new_data = pd.DataFrame.from_dict(prep_main(data))
new_data.set_index('', inplace=True)
return new_data
Fungsi descript_stat() akan mereturn sebuah dataframe.
Evaluation
Tahap ini kita mencoba untuk melakukan uji coba pada sebuah dataset dengan format csv. Data yang aku pakai diambil dari sini.
Sebelum itu kita perlu mengimport data kita ke python menggunakan library pandas seperti berikut
df_test = pd.read_csv("supermarket_sales - Sheet1.csv")
df_test.head()
Data kita memiliki 1000 baris dan 17 kolom, ini sangat cocok untuk menguji apakah fungsi yang telah kita buat dapat mengolah data yang cukup besar atau tidak. Setelah itu, kita perlu menghapus missing value pada data kita agar dapat dilakukan perhitungan menggunakan fungsi yang telah dibuat
df_test.dropna(inplace=True)
df_test.isnull().sum()
dan begini hasilnya
descript_stat(df_test)
Jika kita bandingkan dengan menggunakan fungsi built-in describe() berdasarkan kompleksitas waktunya, hasilnya seperti berikut
import time
# built-in function
start_time1 = time.time()
df_test.describe()
end_time1 = time.time()
elapsed_time1 = end_time1 - start_time1
# user-defined function
start_time2 = time.time()
descript_stat(df_test)
end_time2 = time.time()
elapsed_time2 = end_time2 - start_time2
- Fungsi built-in: 0.0223 detik
- Fungsi user-defined: 2.2062 detik
Meskipun berjalan cukup baik, namun aku melihat beberapa kekurangan dari fungsi yang telah dibuat:
- Fungsi yang telah dibuat tidak dapat melakukan perhitungan apabila dataset yang kita punya terdapat missing values, sehingga perlu dilakukan penanganan terlebih dahulu. Hal ini terlihat tidak efisien seperti fungsi built-in desribe() yang dapat menghiraukan missing value dari sebuah dataset
- Walaupun kompleksitas waktu yang dimiliki sebesar 2 detik, namun itu cukup lama mengingat data yang kita olah hanya 1000 baris. Sangat tidak efektif apabila kita berhadapan dengan data yang memiliki dimensi yang sangat besar. Hal ini bisa kita atasi apabila kita mengurangkan perhitungan yang menggunakan looping pada fungsi-fungsi di atas dan menggantinya dengan menggunakan library numpy atau bisa menggunakan list comprehension.
Sources:
1. Introduction to Descriptive Statistics by Jackie Nicholas
2. statistics | Douglas College Library
3. Central Tendency | Understanding the Mean, Median & Mode (scribbr.com)
4. What is Descriptive Statistics? — Data Science Society
5. Measures of Central Tendency: Definition & Examples — Statology
6. Measures of Dispersion in Statistics (Definition & Types) (byjus.com)
7. Understanding Descriptive Statistics | by Sarang Narkhede | Towards Data Science
8. Intro to Descriptive Statistics. Descriptive Statistical Analysis helps… | by Niklas Donges | Towards Data Science