# Data Handling & Preprocessing (Part 2): Data Transformation, Versioning, dan Best Practices

> *Bagian 2 dari 2: lanjutan dari* [*Part 1*](#) *yang membahas Data Cleaning. Di sini kita masuk ke Data Transformation, cara menyimpan dataset bersih, Data Versioning ala MLOps, Best Practices, sampai gambaran besar Data Pipeline Flow.*

Sekilas recap: di Part 1 kita sudah tahu kenapa preprocessing itu penting (formula 80/20), bagaimana data dikumpulkan & disimpan, dasar-dasar Pandas, dan cara membersihkan data — mulai dari missing values, duplikat, outlier, sampai adversarial data. Sekarang saatnya mengubah data yang sudah bersih itu menjadi format yang benar-benar bisa "dimakan" oleh algoritma Machine Learning.

## Daftar Isi

*   [1\. Data Transformation](#1-data-transformation)
    
*   [2\. Menyimpan Dataset Bersih](#2-menyimpan-dataset-bersih)
    
*   [3\. Data Versioning & Management Strategies](#3-data-versioning--management-strategies)
    
*   [4\. Best Practices, Kesalahan Umum & Error Handling](#4-best-practices-kesalahan-umum--error-handling)
    
*   [5\. Before vs After & Data Pipeline Flow](#5-before-vs-after--data-pipeline-flow)
    
*   [6\. Quiz Check — Part 2](#6-quiz-check--part-2)
    
*   [7\. Cheat Sheet Checklist Preprocessing](#7-cheat-sheet-checklist-preprocessing)
    

* * *

## 1\. Data Transformation

Sebagian besar algoritma ML **hanya menerima data numerik**, sehingga data non-numerik perlu diubah menjadi representasi angka (*vectorization / encoding*). Ini inti dari data transformation.

### 1.1 Sorting & Filtering

*   **Sorting** — prinsip **"Order before logic"**: data yang terurut lebih mudah dianalisis dan diproses oleh model AI.
    
*   **Filtering** — memungkinkan kita fokus pada subset data tertentu, misalnya hanya transaksi dari Asia, atau hanya produk dengan harga di atas Rp 100.000.
    

```python
# Sorting
df_sorted = df.sort_values('price')                    # ascending
df_sorted = df.sort_values('price', ascending=False)    # descending

# Filtering
df_asia = df[df['region'] == 'Asia']
df_filtered = df[(df['region'] == 'Asia') & (df['price'] > 50000)]              # AND
df_filtered = df[(df['region'] == 'Asia') | (df['region'] == 'Europe')]         # OR
df_filtered = df[df['region'].isin(['Asia', 'Europe', 'Africa'])]               # isin()
```

### 1.2 Encoding Data Kategorikal

> 🤔 **Coba Tebak Dulu:** Ukuran baju (S, M, L) dan warna rambut, dua-duanya kategori. Menurutmu, apa keduanya harus di-encode dengan cara yang sama?
> 
> Lihat Jawaban
> 
> **Tidak.** Ukuran baju punya urutan tingkatan (S < M < L) sehingga termasuk **ordinal** — bisa langsung dikonversi ke angka. Warna rambut tidak punya urutan sehingga termasuk **nominal** — sebaiknya pakai One-Hot Encoding.

*   **Nominal**: kategori tanpa urutan/tingkatan. Contoh: warna rambut, ras, jenis kendaraan, jenis kelamin → sebaiknya pakai **One-Hot Encoding** agar model tidak menganggap ada urutan.
    
*   **Ordinal**: kategori dengan urutan/tingkatan yang bermakna. Contoh: ukuran baju (S, M, L), tingkat pendidikan, tingkat kepuasan → bisa dikonversi langsung ke nilai numerik.
    

### 1.3 Dimensionality Reduction (Mengubah Dimensi Data)

**Tujuan:** mengurangi jumlah fitur tanpa menghilangkan informasi penting, untuk mengatasi *Curse of Dimensionality* (fitur terlalu banyak → training lambat, kompleks, performa turun).

> *Number of Dimensionality* = banyaknya fitur/variabel dalam dataset.

**i. Teknik Transformasi Data**

*   **PCA (Principal Component Analysis)** — mencari arah dengan variasi data terbesar (*principal components*); banyak dipakai pada data numerik untuk mengompresi fitur yang saling berkorelasi.
    
*   **t-SNE** — mempertahankan kedekatan antar data (*local structure*); baik untuk visualisasi klaster pada data berdimensi tinggi.
    
*   **UMAP** — tujuan mirip t-SNE tapi lebih cepat & skalabel untuk dataset besar; juga bisa dipakai untuk feature engineering.
    

**ii. Menghapus Fitur yang Kurang Relevan**

*   `.corr()` **(Pandas)** — mengukur korelasi linear antar fitur maupun fitur dengan target.
    
*   **Predictive Power Score (PPS / ppscore)** — mengukur kemampuan fitur memprediksi target; mampu mendeteksi hubungan non-linear (berbeda dari korelasi biasa).
    

**iii. Feature Engineering (Membuat Fitur Baru)**

*   Menggabungkan dua atau lebih fitur menjadi satu fitur baru.
    
*   Membuat rasio, selisih, atau transformasi tertentu dari fitur yang ada.
    
*   Mengekstraksi informasi baru dari data waktu (tanggal, jam, hari, bulan, dst).
    

**iv. Kernelization (Membesarkan Dimensi)**

*   **Konsep**: memetakan data ke ruang berdimensi lebih tinggi agar data yang awalnya tidak terpisah secara linear menjadi dapat dipisahkan. Tidak bisa dilakukan dengan metode linear, melainkan pakai *kernel function*.
    
*   **Kernel function**: Linear Kernel, Polynomial Kernel, Radial Basis Function (RBF) Kernel, Sigmoid Kernel.
    
*   **Tujuan**: membuat data *linearly separable* agar algoritma klasifikasi (Logistic Regression, SVM) bisa membangun *decision boundary* yang lebih baik.
    

**Kernelization vs TF-IDF — sering ketuker, ini bedanya**

Kernelization dipakai di ML (misalnya SVM) untuk memetakan dimensi lebih tinggi, sedangkan TF-IDF dipakai untuk merepresentasikan **teks** menjadi vektor berbobot. Dua teknik yang beda tujuan meskipun sama-sama "mengubah representasi data".

### 1.4 Normalisasi / Scaling

**Definisi:** proses mengubah skala data ke *range* tertentu (biasanya 0–1 atau -1 sampai 1) supaya semua fitur punya kontribusi yang seimbang ke model.

**Kenapa perlu:**

*   Model AI sensitif terhadap skala data.
    
*   Fitur dengan nilai besar bisa mendominasi.
    
*   Mempercepat *convergence* saat training.
    
*   Meningkatkan akurasi model.
    

| Jenis | Rumus | Kapan Dipakai |
| --- | --- | --- |
| Min-Max Scaling | `(x - min) / (max - min)` → skala ke 0–1 | Data tidak punya outlier ekstrem |
| Standardization (Z-Score) | `(x - mean) / std` → mean = 0, std = 1 | Data punya outlier atau distribusi normal |
| Robust Scaling | Memakai median dan IQR, tahan outlier | Data dengan banyak outlier |

```python
from sklearn.preprocessing import MinMaxScaler, StandardScaler

scaler = MinMaxScaler()
df['price_scaled'] = scaler.fit_transform(df[['price']])

scaler = StandardScaler()
df['price_std'] = scaler.fit_transform(df[['price']])
```

*   **Kapan perlu normalisasi**: terutama untuk algoritma yang sensitif terhadap skala, seperti *K-Nearest Neighbors* (KNN), *Neural Networks*, dan algoritma berbasis jarak.
    
*   **Manfaat untuk AI**: kecepatan training (model *converge* lebih cepat), performa model (Neural Networks/KNN/SVM sangat sensitif skala), dan interpretasi yang adil (semua fitur berkontribusi seimbang tanpa didominasi satu fitur).
    

> ⚠️ **Jangan sampai salah urutan** — lihat bagian [Best Practices](#4-best-practices-kesalahan-umum--error-handling) di bawah: normalisasi harus dilakukan **setelah** train-test split, bukan sebelumnya!

### 1.5 Text Vectorization untuk NLP

Komputer tidak dapat langsung memahami kata/kalimat, sehingga teks perlu diubah menjadi representasi numerik (vektor). Sebelum divektorisasi, teks biasanya dibersihkan dulu dengan menghapus link/URL, tag (mention/hashtag), dan stopwords (*the, a, an, or, for*, dll) — lihat [Part 1 bagian Data Cleaning Khusus NLP](#) — karena elemen-elemen ini tidak memberi informasi penting dan hanya memperberat komputasi.

**a) One-Hot Encoding**

*   **Cara kerja**: setiap kata diubah menjadi vektor biner; setiap kata punya posisi (indeks) sendiri, hanya satu nilai bernilai 1, sisanya 0.
    
*   **Kelebihan**: sederhana, mudah diimplementasikan, cocok untuk vocabulary kecil.
    
*   **Kekurangan**: dimensi vektor sangat besar jika jumlah kata banyak; tidak menangkap hubungan/makna antar kata.
    

> **Korpus** = kumpulan data teks yang jadi dasar pembentukan vocabulary. Dalam NLP modern, kata sering disebut **token**.

Contoh korpus (5 kata): *aku, makan, nasi, pakai, tempe*

| Kata | Representasi Vektor |
| --- | --- |
| aku | \[1, 0, 0, 0, 0\] |
| makan | \[0, 1, 0, 0, 0\] |
| nasi | \[0, 0, 1, 0, 0\] |
| pakai | \[0, 0, 0, 1, 0\] |
| tempe | \[0, 0, 0, 0, 1\] |

Kalimat "aku makan nasi" → gabungan vektor *aku* + *makan* + *nasi*. Setiap kata dianggap berdiri sendiri, tidak memperhatikan hubungan makna antar kata.

**b) Bag of Words (BoW)**

Merepresentasikan dokumen berdasarkan jumlah kemunculan tiap kata sesuai korpus yang terbentuk dari seluruh dokumen.

Contoh — D1: *rumah ini bagus* | D2: *rumah saya makan nasi* | D3: *saya makan nasi*

| Dokumen | rumah | ini | bagus | saya | makan | nasi |
| --- | --- | --- | --- | --- | --- | --- |
| D1 | 1 | 1 | 1 | 0 | 0 | 0 |
| D2 | 1 | 0 | 0 | 1 | 1 | 1 |
| D3 | 0 | 0 | 0 | 1 | 1 | 1 |

Yang diperhatikan hanya jumlah kemunculan kata; urutan kata dalam kalimat diabaikan. Sederhana, tetapi belum memahami konteks/makna kalimat.

**c) TF-IDF (Term Frequency – Inverse Document Frequency)**

*   **Rumus**: `TF-IDF = TF × IDF`
    
*   **TF (Term Frequency)**: mengukur seberapa sering sebuah kata muncul dalam satu dokumen — makin sering muncul, makin tinggi nilai TF-nya.
    
*   **IDF (Inverse Document Frequency)**: mengukur seberapa unik/jarang suatu kata muncul di seluruh dokumen korpus. Kata umum (dan, yang, di) → IDF rendah karena kurang informatif; kata jarang muncul → IDF tinggi karena lebih membedakan isi dokumen.
    

> 🤔 **Coba Tebak Dulu:** Kalau tidak pakai IDF sama sekali (cuma pakai TF), apa yang terjadi pada kata umum seperti "yang" atau "di" yang sering muncul di HAMPIR SEMUA dokumen?
> 
> Lihat Jawaban
> 
> Tanpa IDF, kata yang sering muncul di banyak dokumen akan **selalu berbobot tinggi** meski tidak informatif, sehingga model jadi sulit membedakan isi antar dokumen. Inilah alasan IDF dibutuhkan — untuk "menghukum" kata yang terlalu umum.

*   **Proses perhitungan**: harus memakai seluruh dokumen dalam dataset (nilai IDF bergantung pada seluruh korpus), lalu TF dan IDF dikalikan untuk tiap kata di tiap dokumen.
    
*   **Hasil akhir**: matriks TF-IDF berukuran (Jumlah Dokumen × Jumlah Kata dalam Korpus). Contoh: 3 dokumen × 6 kata unik → matriks 3×6.
    
*   **Kegunaan**: klasifikasi dokumen, *information retrieval*, *search engine*, *text mining*.
    

**d) Word2Vec**

*   **Konsep**: representasi kata menggunakan *dense vector* (embedding) yang dipelajari oleh neural network; mampu menangkap hubungan semantik antar kata (kata bermakna mirip → vektor berdekatan).
    

> 🤔 **Coba Tebak Dulu:** Lengkapi rumus vektor kata terkenal ini: `King − Man + Woman ≈ ?`
> 
> Lihat Jawaban
> 
> **Queen.** Ini contoh klasik yang menunjukkan Word2Vec menangkap hubungan semantik antar kata — bukan cuma kemunculan kata seperti BoW/TF-IDF.

*   **Cara kerja**: model dilatih memprediksi kata yang hilang (*masked word*) atau kata di sekitarnya berdasarkan konteks — bukan generatif, melainkan klasifikasi kata berdasarkan konteks sebelum & sesudah.
    
*   **Hidden Dimension**: ruang representasi (*embedding space*) penyimpan fitur tiap kata. Contoh: Hidden Dimension = 512 → tiap kata direpresentasikan sebagai vektor 512 fitur.
    
*   **Visualisasi**: hasil embedding bisa divisualisasikan dengan PCA, t-SNE, atau UMAP — kata bermakna serupa akan membentuk cluster (contoh: "Raja" dan "Ratu" saling berdekatan).
    

### 1.6 Image sebagai Data Numerik

Pada data gambar, komputer pada dasarnya sudah menerima data dalam bentuk numerik.

**a) Representasi Gambar sebagai Matriks**

*   Gambar disimpan sebagai data biner, lalu direpresentasikan sebagai matriks piksel.
    
*   **Grayscale**: satu nilai intensitas (0–255).
    
*   **RGB**: tiga nilai — Red, Green, Blue.
    

**b) CNN sebagai Feature Extractor**

*   **Cara kerja**: *Convolutional Neural Network* (CNN) secara otomatis mempelajari karakteristik penting gambar: tepi (*edges*), garis, tekstur, bentuk objek, pola, dan bagian-bagian objek.
    
*   **Semakin dalam layer CNN**: semakin kompleks fitur yang dipelajari — layer awal mengenali garis/tepi, layer dalam mengenali objek kompleks (wajah, kendaraan, hewan).
    
*   **Tugas Computer Vision**: Image Classification, Object Detection, Image Segmentation, Face Recognition, Image Retrieval.
    

* * *

## 2\. Menyimpan Dataset Bersih

Setelah semua tahap cleaning dan transformation selesai, saatnya menyimpan dataset bersih — ibarat "bahan masakan" yang siap diberikan ke AI.

```python
df_clean.to_csv('retail_data_clean.csv', index=False)
df_clean.to_excel('retail_data_clean.xlsx', index=False)
df_clean.to_pickle('retail_data_clean.pkl')  # format Python
```

> Catatan: selalu simpan dataset asli dan dataset yang sudah dibersihkan dengan **nama file berbeda** — jangan *overwrite* data original.

* * *

## 3\. Data Versioning & Management Strategies

### A. Data Versioning

*   **Konsep**: salah satu konsep penting dalam MLOps.
    
*   **Tujuan**: membantu *development lifecycle* dengan menyediakan checkpoint di tiap tahap, sehingga setiap perubahan dapat dilacak.
    
*   **Manfaat rollback**: jika terjadi error atau hasil eksperimen tidak sesuai harapan, developer bisa rollback ke versi sebelumnya tanpa mengulang seluruh proses dari awal.
    
*   **Hasil akhir**: proses pengembangan menjadi lebih terstruktur, terdokumentasi, dan mudah ditelusuri.
    

**Syarat Sistem Versioning:**

*   Bisa memberi label pada setiap versi.
    
*   Bisa membuat *checkpoint* / *freeze progress* pada setiap tahap pengembangan.
    
*   Memungkinkan pengembang rollback ke versi tertentu kapan saja.
    

### B. Skema Penomoran Versi

*   **vX.X.X** (contoh: v1.0.0): terdiri dari **Major Version** (perubahan fundamental/total), **Minor Version** (perubahan besar tapi tidak mengubah keseluruhan sistem), dan **Patch/Revision** atau *Micro Changing* (perubahan kecil yang tidak memengaruhi struktur utama).
    
*   **vX.X.X.X**: menambahkan satu komponen Patch lagi, khusus untuk *bug fixing* atau perbaikan kecil.
    

### C. Kategori Perubahan Versi

| Kategori | Kapan Digunakan | Contoh |
| --- | --- | --- |
| Major Version | Perubahan sangat signifikan | Mengubah task ML (Image Classification → Object Detection); perubahan arsitektur sistem secara menyeluruh |
| Minor Version | Perubahan cukup besar, tidak mengubah keseluruhan sistem | Penambahan kelas baru; perubahan dataset dalam jumlah besar; penambahan fitur utama yang berdampak pada performa |
| Micro Changing | Perubahan kecil | Penambahan data dalam jumlah sedikit; jumlah kelas tetap; perubahan kecil pada preprocessing/konfigurasi |
| Patch (Bug Fix) | Memperbaiki kesalahan tanpa mengubah perilaku utama | Memperbaiki bug; menambahkan 1–10 data yang sebelumnya salah; memperbaiki kesalahan labeling/konfigurasi |

> 🤔 **Coba Tebak Dulu:** Kamu baru saja memperbaiki 5 data yang salah label di dataset. Itu masuk kategori versi apa — Major, Minor, Micro, atau Patch?
> 
> Lihat Jawaban
> 
> **Patch (Bug Fix)** — memperbaiki kesalahan labeling termasuk contoh Patch, karena tidak mengubah perilaku utama sistem, hanya membenarkan kesalahan kecil.

### D. GitLab sebagai Data Versioning

| Kelebihan | Kekurangan |
| --- | --- |
| Gratis untuk penggunaan dasar | Versi gratis memiliki keterbatasan |
| Mudah digunakan | Perlu konfigurasi tambahan agar versioning dataset berjalan baik |
| Keamanan yang baik | Belum ada fitur lanjutan khusus DataOps/MLOps |
| Mendukung struktur subfolder | Kurang optimal untuk dataset yang sangat besar |
| Bersifat open source |  |

### E. Tools untuk DataOps dan MLOps

| Kategori | Tools |
| --- | --- |
| Annotation Tools (sudah punya fitur dataset versioning) | CVAT (open source), Roboflow (khusus computer vision), SuperAnnotate, V7 Labs, Scale AI |
| Dataset Versioning & Preprocessing | DVC – Data Version Control (open source), FiftyOne (open source) |
| ML Pipelining & Experiment Tracking | Neptune.ai, Weights & Biases (W&B), MLflow (open source) |

* * *

## 4\. Best Practices, Kesalahan Umum & Error Handling

### A. Do & Don't

| ❌ Jangan Lakukan Ini | ✅ Lakukan Ini |
| --- | --- |
| Normalize sebelum train-test split | Split data dulu, baru normalize |
| Drop semua rows dengan missing values tanpa analisis | Analisis pattern missing values sebelum mengambil tindakan |
| Lupa reset index setelah drop rows | Selalu `reset_index(drop=True)` setelah cleaning |
| Normalize target variable (y) untuk regression | Keep target variable dalam skala original |
| Menggunakan test data saat fit scaler | Fit scaler hanya pada training data |
| Tidak cek data quality setelah transformasi | Validate hasil dengan visualisasi dan statistik |

### B. Trust But Verify

| Kesalahan Umum | Solusi |
| --- | --- |
| Tidak cek tipe data sebelum operasi numerik | Selalu verifikasi dengan `df.dtypes` sebelum menghitung mean atau sum |
| Lupa handling null values sebelum konversi tipe | Handle dulu dengan `dropna()` atau `fillna()` sebelum mengubah tipe data |
| Overwrite dataset original | Selalu simpan dataset asli, buat copy untuk cleaning: `df_clean = df.copy()` |
| Tidak verifikasi hasil cleaning | Setelah cleaning, jalankan `df.info()` dan `df.head()` untuk memastikan hasilnya benar |
| Normalisasi tanpa perlu | Tidak semua model butuh normalisasi — pahami konteks dan algoritma yang dipakai |

> Prinsip: **"Trust but verify"** — selalu double-check hasil setiap langkah cleaning.

### C. Error Handling

| Error | Penyebab | Solusi |
| --- | --- | --- |
| `KeyError` | Nama kolom salah atau tidak ada | Cek nama kolom dengan `df.columns` |
| `ValueError` | Konversi tipe data gagal | Gunakan parameter `errors='coerce'` pada `pd.to_numeric()` |
| `FileNotFoundError` | File path salah atau file tidak ada | Pastikan file sudah di-*upload* ke environment kerja (mis. Google Colab) |
| `AttributeError` | Method tidak tersedia untuk tipe data tertentu | Cek tipe data dengan `type()` atau `df.dtypes` |

> Catatan: error adalah momen belajar, bukan kegagalan.

* * *

## 5\. Before vs After & Data Pipeline Flow

### A. Before vs After: From Chaos to Clarity

| Dataset Mentah (Raw) | Dataset Bersih (Clean) |
| --- | --- |
| Missing values di berbagai kolom | Tidak ada missing values |
| Data duplikat yang menipu | Setiap baris unik |
| Tipe data tidak konsisten | Tipe data sesuai konteks |
| Nama kolom ambiguous | Nama kolom jelas dan konsisten |
| Nilai outlier ekstrem | Nilai dalam rentang wajar |
| Format tidak standar | Format terstandarisasi |

*   **Dampak dataset mentah**: AI akan bingung, error saat training, dan prediksi tidak akurat.
    
*   **Dampak dataset bersih**: AI bisa belajar dengan baik, training lancar, dan prediksi akurat.
    

### B. Data Pipeline Flow (End-to-End)

1.  **Data Collection** — mengumpulkan data dari berbagai sumber (database, API, file).
    
2.  **Data Loading** — membaca data ke dalam environment Python.
    
3.  **Data Exploration** — memahami struktur, distribusi, dan masalah dalam data.
    
4.  **Data Cleaning** — menangani missing values, duplikat, dan error.
    
5.  **Data Transformation** — sorting, filtering, normalisasi, feature engineering.
    
6.  **Data Storage** — menyimpan dataset bersih untuk tahap selanjutnya (training model).
    

* * *

## 6\. Quiz Check — Part 2

**Q1. Kamu punya dataset dengan outlier ekstrem di kolom gaji. Metode scaling mana yang paling tahan terhadap outlier: Min-Max, Standardization, atau Robust Scaling?**

**Jawaban: Robust Scaling.** Metode ini memakai median dan IQR (bukan mean/min/max), sehingga jauh lebih tahan terhadap outlier dibanding Min-Max Scaling maupun Standardization.

**Q2. Kenapa normalisasi HARUS dilakukan setelah train-test split, bukan sebelumnya?**

**Jawaban:** Karena scaler (misalnya `MinMaxScaler`) harus di-*fit* hanya pada training data. Kalau di-fit sebelum split (pada seluruh data termasuk test set), informasi dari test set "bocor" ke proses training — ini disebut *data leakage* dan membuat evaluasi model jadi tidak jujur.

**Q3. Kode kamu error dengan pesan \`KeyError\` saat mencoba akses \`df\['harga'\]\`. Apa penyebab paling mungkin dan solusinya?**

**Jawaban:** Penyebab paling mungkin adalah **nama kolom salah atau tidak ada** — mungkin sebenarnya nama kolomnya `price` atau `Harga` (kapital berbeda). Solusi: cek nama kolom persis dengan `df.columns`.

**Q4. Kamu baru saja menambahkan satu kelas objek baru ke dataset object detection, plus menambah ribuan gambar baru. Ini termasuk perubahan versi apa?**

**Jawaban: Minor Version.** Penambahan kelas baru dan perubahan dataset dalam jumlah besar termasuk kategori Minor Version — perubahan cukup besar tapi belum mengubah keseluruhan sistem/task ML-nya.

* * *

## 7\. Cheat Sheet Checklist Preprocessing

Simpan checklist ini sebagai referensi cepat sebelum data kamu masuk ke tahap training:

**Eksplorasi**

*   \[ \] Sudah jalankan `df.head()`, `df.info()`, `df.describe()`, `df.shape`?
    
*   \[ \] Sudah tahu tipe data tiap kolom (`df.dtypes`)?
    

**Cleaning**

*   \[ \] Missing values sudah dicek (`df.isnull().sum()`) dan ditangani sesuai persentasenya?
    
*   \[ \] Duplikat sudah dicek (`df.duplicated().sum()`) dan dihapus?
    
*   \[ \] Outlier sudah dideteksi (Boxplot/IQR/Z-Score) dan diputuskan: hapus atau treatment?
    
*   \[ \] Tipe data sudah dikonversi dengan benar (`astype`, `to_numeric`, `to_datetime`)?
    
*   \[ \] Teks sudah dirapikan (strip, lowercase, replace) dan konsisten formatnya?
    
*   \[ \] Nama kolom sudah `snake_case` dan konsisten?
    
*   \[ \] Index sudah di-reset setelah drop rows (`reset_index(drop=True)`)?
    

**Transformation**

*   \[ \] Data kategorikal sudah di-encode sesuai jenisnya (nominal → One-Hot, ordinal → numerik langsung)?
    
*   \[ \] Dimensionality reduction dipertimbangkan jika fitur terlalu banyak?
    
*   \[ \] Scaler di-*fit* hanya pada training data, **setelah** train-test split?
    
*   \[ \] Target variable (y) **tidak** dinormalisasi untuk kasus regression?
    

**Penyimpanan & Versioning**

*   \[ \] Dataset asli disimpan terpisah dari dataset bersih (nama file berbeda)?
    
*   \[ \] Dataset bersih sudah diberi versi (Major/Minor/Micro/Patch) sesuai jenis perubahan?
    
*   \[ \] Dataset sudah disimpan di tempat yang mendukung versioning (S3/GCS/DVC/dll)?
    

* * *

*Lihat* [*Part 1*](https://shaka-ai.hashnode.dev/data-handling-preprocessing-part-1) *untuk pembahasan lengkap tentang Data Collection, Storage, dan Data Cleaning.*
