top of page
Gambar penulisCornellius Yudha Wijaya

Eksplorasi Data: Belajar dari Nutrisi Makanan

Eksplorasi Data: Belajar dari Nutrisi Makanan
Photo by Brooke Lark on Unsplash

Saya suka mengeksplorasi data dan menemukan pola-pola tak terduga dari data. Menurut saya, sebagai seorang data scientist kita perlu memiliki sifat curious (rasa ingin tahu) agar bisa sukses di bidang ini. Cara mengeksplorasi data tidak hanya terbatas pada teknik dasar seperti memvisualisasikan data dan mendapatkan angka-angka statistik; salah satu cara lain adalah dengan menerapkan machine learning.


Machine learning adalah teknik untuk mengeksplorasi data, bukan hanya untuk tujuan prediksi seperti yang sering dikatakan orang. Inilah mengapa saya sering fokus pada pemahaman konsep model untuk mengetahui bagaimana data saya diproses; untuk lebih memahami apa yang terjadi pada data kita.


Pada artikel ini, saya ingin memperkenalkan informasi apa yang bisa kita dapatkan dari angka-angka statistik dan teknik data mining melalui unsupervised learning untuk mengeksplorasi data. Di sini, karena salah satu hobi saya adalah memasak, saya akan menggunakan dataset dari Kaggle tentang nilai nutrisi dari makanan. Saya ingin mengeksplorasi data ini baik untuk belajar maupun memenuhi rasa penasaran saya sendiri. Artinya, tujuan saya di sini hanyalah untuk mengetahui apa yang terjadi pada data dan jenis informasi apa yang bisa saya dapatkan tanpa tujuan spesifik. Mari kita mulai.


Eksplorasi Data

Data Cleaning


Pertama, kita perlu membaca data dan memahami bagaimana data kita. Ini adalah langkah pertama yang sangat penting.

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
data = pd.read_csv('nutrition.csv')

data.head()
Eksplorasi Data: Belajar dari Nutrisi Makanan
data.info()
Eksplorasi Data: Belajar dari Nutrisi Makanan

Kita memiliki 76 kolom yang tidak saya tampilkan semua di sini (daftarnya akan sangat panjang) dengan contoh data yang ditunjukkan pada tabel di atas.


Sebagian besar data kita terdiri dari nilai nutrisi (kalori, lemak, gula, karbohidrat, dll.) dengan nama makanannya. Kolom nilai nutrisi memiliki ukuran yang berbeda seperti g (gram), mg (miligram), dan mcg (mikrogram). Dalam hal ini, kita juga bisa mengabaikan fitur serving_size karena tidak memberikan informasi tambahan selain semua data didasarkan pada 100 gram makanan. Beberapa kolom juga mengandung nilai NaN, yang saya percaya nilai Null ini berarti sama dengan 0. Sekarang, mari kita lakukan beberapa data cleaning.

data.drop('serving_size', axis = 1, inplace = True)

data.fillna(0, inplace = True)

Dalam hal ini, saya ingin semua fitur kecuali fitur nama menjadi kolom numerik. Artinya, kita perlu menghapus semua teks non-numerik dalam data. Saya juga ingin mengubah semua data numerik kecuali kalori agar memiliki ukuran yang sama (gram). Mari kita mulai.


import re
for col in data.drop('name',axis = 1).select_dtypes(exclude = 'number').columns:
    for i in data[col]:
        if i == '0' or i == 0:
            pass
        else:
            point = re.findall('[a-zA-Z]+',i)[0]
            replace = []
            if point == 'mg':
                for j in data[col]:
                    if j == '0' or j == 0:
                        replace.append(float(j))
                    else:
                        replace.append(float(re.sub('[a-zA-Z]','',j))/1000)
            elif point == 'mcg':
                for j in data[col]:
                    if j == '0' or j == 0:
                        replace.append(float(j))
                    else:
                        replace.append(float(re.sub('[a-zA-Z]','',j))/1000000)  
            else:
                 for j in data[col]:
                    if j == '0' or j == 0:
                        replace.append(float(j))
                    else:       
                        replace.append(float(re.sub('[a-zA-Z]','',j)))
                        
            data[col] = replace    
            data.rename({col:col+'(g)'}, axis =1, inplace = True)
            break

Berikut adalah hasil akhir dari data yang akan saya eksplorasi lebih lanjut. Perlu dicatat bahwa saya tahu semua data sekarang dalam ukuran gram kecuali kalori, tetapi hanya untuk tujuan pembelajaran, saya menambahkannya dalam nama kolom saya agar kita tidak lupa tentang itu.

Eksplorasi Data: Belajar dari Nutrisi Makanan

Saya juga membuat satu fitur lagi yang disebut food_categories karena ketika memeriksa dengan cermat fitur nama, kata pertama sebelum koma adalah nama makanan.

data['food_categories'] = data['name'].apply(lambda x: x.split(',')[0])

Numerical Statistic

Jika kita mencoba memvisualisasikan kolom satu per satu, itu akan sangat banyak dan agak berulang karena tidak akan memberi kita banyak informasi. Kamu bisa mencobanya jika kamu mau. Saya bisa memberikan kodenya di bawah ini.

for i in data.select_dtypes('number').columns:
    sns.distplot(data[i])
    plt.title(i)
    plt.show()

Terkadang dalam kasus seperti ini, jika kita benar-benar hanya ingin mengeksplorasi data, akan lebih intuitif melihat dengan angka daripada memvisualisasikannya (saya lebih suka angka karena saya percaya terkadang visualisasi bisa bias).

pd.set_option('display.max_columns', None)
data.agg(['mean', 'median', 'std', 'skew', 'kurtosis'])
Eksplorasi Data: Belajar dari Nutrisi Makanan

Di sini saya menggunakan metode .agg dari Dataframe untuk mendapatkan informasi tentang mean, median, std, skewness, dan kurtosis dari setiap kolom. Di sinilah angka berbicara lebih dari sekedar visualisasi.


Seperti yang kita tahu, mean adalah rata-rata dari data. Beberapa fitur bisa memiliki mean yang sama, tetapi berbeda dalam cara penyebarannya di sekitar mean yang ditunjukkan oleh standar deviasi (std). Ada aturan yang disebut aturan empiris di mana kita bisa mendapatkan probabilitas penyebaran data melalui standar deviasi. Aturan empiris menyatakan bahwa:

  • 68% dari data kita berada di bawah mean ± 1*std

  • 95% dari data kita berada di bawah mean ± 2*std

  • 99,7% dari data kita berada di bawah mean ± 3*std


Aturan empiris atau beberapa juga menyebutnya aturan 68–95–99,7 sering digunakan untuk menganalisis data outlier. Masalah utama dengan statistik ini adalah mereka dipengaruhi oleh outlier atau nilai ekstrem dan sering menyebabkan data menjadi skewed. Saya tunjukkan dengan gambar apa itu data yang skewed.

Eksplorasi Data: Belajar dari Nutrisi Makanan

Di atas adalah plot dari fitur total_fat(g). Itu skewed ke kanan karena ekornya ada di kanan. Tapi, seberapa skewed skewnessnya? Itu adalah tujuan dari statistik skewness. Beberapa aturan yang bisa kita ingat tentang skewness adalah:


  • Jika skewness antara -0,5 dan 0,5, data cukup simetris

  • Jika skewness antara -1 dan -0,5 atau antara 0,5 dan 1, data sedikit skewed

  • Jika skewness kurang dari -1 atau lebih dari 1, data sangat skewed

Jadi kita tahu bahwa data kita sangat skewed, yang sebenarnya sebagian besar data yang akan kamu temui akan seperti ini. Sekarang, bagaimana dengan kurtosis? Apa yang statistik ini beritahukan kepada kita?


Kurtosis adalah ukuran apakah data memiliki heavy-tailed atau light-tailed relatif terhadap distribusi normal. Analisisnya bisa dirangkum seperti di bawah ini:

  • Jika kurtosis mendekati 0, maka diasumsikan sebagai distribusi normal. Ini disebut mesokurtic distributions.

  • Jika kurtosis kurang dari 0, maka distribusi memiliki light tails dan disebut platykurtic distribution.

  • Jika kurtosis lebih dari 0, maka distribusi memiliki heavier tails dan disebut leptokurtic distribution.

Jika kita memvisualisasikannya, itu akan terlihat seperti gambar di bawah ini.

Eksplorasi Data: Belajar dari Nutrisi Makanan
Excess Kurtosis diambil dari booglehead.com

Lebih tepatnya disebut Excess Kurtosis, di mana distribusi normal diukur dalam kurtosis sebagai 0. Jika kita hanya berbicara tentang Kurtosis, distribusi normal akan sama dengan 3 sehingga dalam Excess Kurtosis kita mengurangkan kurtosis dengan 3.


Ternyata sebagian besar data kita skewed. Data yang skewed sebenarnya sangat menarik karena kamu bisa mencoba mengeksplorasinya. Misalnya, makanan apa yang dianggap sebagai outlier berdasarkan kalori.


Karena data kita cukup skewed, saya tidak akan mengandalkan mean untuk menemukan outlier; sebagai gantinya, saya akan menerapkan metode IQR yang didasarkan pada median.

IQR atau Interquartile Range didasarkan pada posisi data. Misalnya, jika kita menggambarkan fitur ‘kalori’ kita akan mendapatkan deskripsi di bawah ini.

data['calories'].describe()
Eksplorasi Data: Belajar dari Nutrisi Makanan

IQR didasarkan pada posisi 25% atau Q1 dan posisi 75% atau Q3. Kita mendapatkan nilai IQR dengan mengurangi Q3 dengan Q1 (Q3-Q1). Dengan metode IQR, kita bisa menentukan data mana yang dianggap outlier berdasarkan batas atas (Upper Limit) atau batas bawah (Lower Limit).


Lower Limit= Q1–1.5 * IQR

Upper Limit= Q3 + 1.5 * IQR


Setiap data di atas atau di bawah batas ini dianggap sebagai outlier. Mari kita coba menerapkan metode ini dan lihat jenis makanan apa yang dianggap outlier berdasarkan kalori.


cal_Q1 = data.describe()['calories']['25%']
cal_Q3 = data.describe()['calories']['75%']
cal_IQR = cal_Q3 - cal_Q1

data[(data['calories'] < 1.5 * (cal_Q1 - cal_IQR)) | (data['calories'] > 1.5 * (cal_Q3 + cal_IQR)) ]['food_categories'].value_counts()
Eksplorasi Data: Belajar dari Nutrisi Makanan

Ternyata, sebagian besar kategori makanan dengan kalori tinggi adalah minyak, tentu tidak mengejutkan.


Unsupervised Learning

Saya telah menunjukkan cara mengeksplorasi data secara numerik, sekarang saya ingin menunjukkan contoh bagaimana machine learning bisa membantu kita mengeksplorasi data.

Unsupervised learning adalah kasus machine learning di mana kita tidak memiliki target spesifik untuk dipelajari. Salah satu contohnya adalah Clustering Analysis, di mana kita memberi model data dan output-nya adalah cluster data di mana data terdekat dianggap sebagai satu cluster.


Yang saya suka lakukan jika kita tidak memiliki target spesifik untuk mengeksplorasi data, kita bisa membiarkan machine learning belajar untuk kita. Menggunakan unsupervised learning, kita bisa mendapatkan perspektif baru yang sebelumnya tidak kita sadari. Mari kita lakukan dengan contoh menggunakan algoritma clustering favorit saya.


Algoritma clustering favorit saya adalah Agglomerative Clustering Analysis yang bisa kamu baca lebih detail di sini. Pada dasarnya, analisis ini menetapkan setiap titik data sebagai satu cluster dan melanjutkan dengan menggabungkan setiap cluster sehingga kita hanya memiliki satu cluster.


Sekarang, sebelum kita melanjutkan analisis, kita perlu menyiapkan data. Clustering analysis bergantung pada jarak antara data. Jarak data dipengaruhi oleh skala mereka, itulah mengapa kita juga perlu mengubah semua fitur agar memiliki skala yang sama. Jika kamu ingat, kita sudah memiliki setiap kolom dalam ukuran gram, tetapi ada kolom ‘Kalori’ yang tidak pada skala yang sama. Inilah mengapa kita masih perlu mengubah data kita. Sering kali kita mengubah data mengikuti distribusi standar dan itulah yang akan kita lakukan.

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
training = pd.DataFrame(scaler.fit_transform(data.drop('name', axis =1)), columns = data.drop('name', axis =1).columns)
Eksplorasi Data: Belajar dari Nutrisi Makanan

Ini adalah hasil akhir kita, dataset dengan skala yang sama untuk setiap fitur. Sekarang, mari kita coba clustering data menggunakan Agglomerative Clustering. Pertama, kita visualisasikan hasil clustering.

from scipy.cluster.hierarchy import linkage, dendrogram

Z = linkage(training,method = 'ward')
dendrogram(Z, truncate_mode = 'lastp')
plt.xticks(rotation = 90, fontsize = 10)
plt.ylabel('Distance')
plt.xlabel('Cluster')
plt.title('Agglomerative Clustering')
Eksplorasi Data: Belajar dari Nutrisi Makanan

Gambar di atas adalah bagan yang dihasilkan oleh Agglomerative Clustering. Data ini hanya menampilkan sekitar 30 penggabungan karena akan terlalu padat jika kita menunjukkan semuanya di sini. Seperti yang kita lihat, tampaknya data bisa dibagi menjadi 2 cluster; tentu saja, jika kamu ingin lebih konservatif, itu bisa dibagi menjadi 3 cluster karena ada bukti dalam visualisasi di atas bahwa itu bisa terjadi. Meskipun demikian, saya akan tetap dengan 2 cluster untuk saat ini.


Mari kita kembali ke data sebelumnya dan masukkan hasil Agglomerative Clustering ke dalam data kita.

from sklearn.cluster import AgglomerativeClustering

ach = AgglomerativeClustering(n_clusters = 2)
ach.fit(training)

data['label'] = ach.labels_

Sekarang, melalui unsupervised learning, kita sebenarnya bisa mencoba memvisualisasikan data multidimensi menjadi dua sumbu. Ada beberapa cara untuk melakukannya, tetapi saya akan menunjukkan teknik yang disebut t-SNE.

from sklearn.manifold import TSNE

tsne = TSNE(random_state=0)
tsne_results = tsne.fit_transform(training) 
tsne_results=pd.DataFrame(tsne_results, columns=['tsne1', 'tsne2'])

tsne_results['label'] = data['label']
sns.scatterplot(data = tsne_results, x = 'tsne1', y = 'tsne2', hue='label')
plt.show()
Eksplorasi Data: Belajar dari Nutrisi Makanan

Sekarang data multidimensi kita telah divisualisasikan dan jelas bahwa metode agglomerative clustering memisahkan data kita dengan garis yang jelas. Nah, apa yang membuat mereka terpisah? Itu yang perlu kita analisis. Tidak ada cara mudah kecuali kita mendalami angka lagi. Tentu saja, visualisasi akan membantu di sini. Saya akan memberikan kode untuk distribusi setiap kolom di bawah ini.

for i in data.select_dtypes('number').columns:
    sns.distplot(data[data['label'] == 0][i], label = 'label 0')
    sns.distplot(data[data['label'] == 1][i], label = 'label 1')
    plt.title(i)
    plt.legend()
    plt.show()
Eksplorasi Data: Belajar dari Nutrisi Makanan

Di atas adalah plot distribusi untuk setiap kolom, tetapi jika kamu lebih suka menggunakan angka seperti saya; kita bisa menggunakan metode groupby dari objek DataFrame.

data.groupby('label').agg(['mean', 'median', 'std'])
Eksplorasi Data: Belajar dari Nutrisi Makanan

Hasilnya akan terlihat seperti di atas. Saya telah melakukan beberapa analisis yang membuat mereka terpisah. Berikut adalah ringkasan saya:

  • Label 0: Makanan dengan protein lebih rendah, gula dan karbohidrat lebih tinggi, serat lebih banyak, lemak dan kolesterol lebih rendah, dan kalori tersebar kecuali sekitar 200 kalori.

  • Label 1: Makanan dengan protein lebih tinggi, gula dan karbohidrat lebih rendah, serat lebih sedikit, lemak dan kolesterol lebih tinggi, dan kalori hanya terpaut sekitar 200 kalori.

Kita juga bisa melihat jenis makanan apa yang kita miliki dari label di atas.

data[data['label'] == 0]['food_categories'].value_counts()
Eksplorasi Data: Belajar dari Nutrisi Makanan

Lima makanan teratas dari makanan dengan label 0 adalah minuman, sereal, makanan bayi, sup, dan makanan ringan yang diharapkan untuk makanan yang tidak mengandung banyak protein dan lemak.

data[data['label'] == 1]['food_categories'].value_counts()
Eksplorasi Data: Belajar dari Nutrisi Makanan

Pada label 1, lima makanan teratas semuanya adalah daging. Ini tidak mengejutkan, mengingat label ini untuk makanan yang mengandung lebih banyak lemak dan protein dibandingkan dengan label 0.

Kesimpulan

Di sini saya hanya mencoba bermain-main dengan data dan mencoba mendapatkan pola apa yang bisa saya dapatkan dari data tersebut. Saya tidak memiliki tujuan spesifik kecuali untuk mendapatkan wawasan tentang apa yang data saya dapat berikan.


Kita bisa melihat bahwa terkadang angka bisa memberikan lebih banyak informasi dibandingkan dengan visualisasi dan machine learning tidak selalu digunakan untuk prediksi tetapi juga bisa digunakan untuk analisis.

28 tampilan0 komentar

Postingan Terkait

Lihat Semua

コメント


bottom of page