# Teknik Binning
Data binning atau bucketing adalah metode pra-pemrosesan data yang digunakan untuk mengurangi dampak kesalahan pengamatan. Nilai data asli dibagi ke dalam interval-interval kecil yang disebut bin, lalu nilai-nilai tersebut digantikan oleh suatu nilai umum yang dihitung untuk setiap bin tersebut. Metode ini memiliki efek menghaluskan (smoothing) pada data masukan dan juga dapat mengurangi risiko overfitting terutama pada kasus dataset yang kecil.
Ada beberapa **metode di data mining (data mining methods)** yang **memerlukan diskritisasi (discretization)** sebelumnya diantaranya adalah
---
### 1 **Naive Bayes Classifier**
- **Mengapa butuh diskritisasi**: Naive Bayes, terutama versi kategorikalnya (Categorical Naive Bayes), bekerja dengan variabel kategoris atau diskrit.
- **Jika tidak didiskritisasi**: Versi Gaussian Naive Bayes bisa digunakan untuk fitur kontinu, tetapi kadang diskritisasi diterapkan untuk menghindari asumsi distribusi normal.
---
### 2. **Decision Tree (seperti ID3, C4.5)**
- **Mengapa butuh diskritisasi**:
- Algoritma seperti ID3 hanya menerima atribut kategoris.
- Diskritisasi diperlukan agar algoritma dapat membangun aturan keputusan berdasarkan nilai-nilai diskrit.
- **Algoritma C4.5** sudah bisa menangani data numerik secara langsung dengan mencari split point, tetapi diskritisasi tetap berguna dalam beberapa kasus.
### Mengapa Binning Penting?
1. **Penghalusan Data (Data Smoothing):**
Binning membantu mengurangi dampak variasi kecil dalam pengamatan, sehingga secara efektif menghaluskan data.
2. **Penanganan Outlier (Outlier Mitigation):**
Dengan mengelompokkan nilai-nilai ke dalam bin, metode ini mengurangi pengaruh outlier pada analisis.
3. **Analisis yang Lebih Baik (Improved Analysis):**
Diskritisasi data kontinu mempermudah analisis data dan memungkinkan visualisasi yang lebih baik.
4. **Feature Engineering:**
Variabel yang dibin dapat menjadi lebih intuitif dan berguna dalam pemodelan prediktif.
### Macama macam Teknik Binning
Binning secara umum dikategorikan menjadi beberapa jenis berdasarkan cara bin ditentukan:
#### 1. **Equal-Width Binning**
Setiap bin memiliki lebar yang sama, yang ditentukan dengan membagi rentang data menjadi *n* interval. Pendekatan diskritisasi Equal-Width Binning adalah membagi rentang dari $X$ menjadi $k$ interval dengan lebar sama (equal-width interval). Cara yang paling sederhana untuk membagi lebar rentang dari $X$ adalah dengan menggunakan rumus berikut:
$$
w = \frac{x_{\max} - x_{\min}}{k}
$$
Kemudian, batas rentang ke-$i$ dinyatakan dengan:
$$
v_i = x_{\min} + iw, \quad \text{untuk } i = 1, \dots, k-1
$$
#### Contoh Manual: Equal-Width Binning
**Diketahui:**
Misalnya kita memiliki data berikut (variabel $X$):
$$
X = [12, 15, 17, 20, 22, 25, 28, 30, 35, 40]
$$
Kita ingin membagi data ini ke dalam **3 bin (k = 3)**.
---
**Langkah 1: Cari Nilai Minimum dan Maksimum**
$$
x_{\min} = 12,\quad x_{\max} = 40
$$
---
**Langkah 2: Hitung Lebar Bin ($w$)**
Gunakan rumus:
$$
w = \frac{x_{\max} - x_{\min}}{k} = \frac{40 - 12}{3} = \frac{28}{3} \approx 9.33
$$
**Langkah 3: Tentukan Batas-Batas Bin**
Kita buat interval berdasarkan lebar $w \approx 9.33$:
- **Bin 1:** 12 – 21.33
- **Bin 2:** 21.33 – 30.66
- **Bin 3:** 30.66 – 40
di bulatkan agar lebih mudah dibaca,:
- Bin 1: 12 – 21
- Bin 2: 21 – 30
- Bin 3: 30 – 40
Untuk implementasi, kita tetap gunakan nilai asli dalam proses pengelompokan.
Langkah 4: Masukkan Data ke dalam Bin
| Data | Bin |
|------|-----|
| 12 | Bin 1 |
| 15 | Bin 1 |
| 17 | Bin 1 |
| 20 | Bin 1 |
| 22 | Bin 2 |
| 25 | Bin 2 |
| 28 | Bin 2 |
| 30 | Bin 2 |
| 35 | Bin 3 |
| 40 | Bin 3 |
Hasil Akhir:
- **Bin 1 (12–21.33):** [12, 15, 17, 20]
- **Bin 2 (21.33–30.66):** [22, 25, 28, 30]
- **Bin 3 (30.66–40):** [35, 40]
Ganti dengan Label kategori seperti yang ditentukan "Rendah", "Sedang", "Tinggi"**
Contoh label:
- Bin 1 → "Rendah"
- Bin 2 → "Sedang"
- Bin 3 → "Tinggi"
Sehingga data menjadi:
```
X = [12, 15, 17, 20, 22, 25, 28, 30, 35, 40]
X = ["Rendah", "Rendah", "Rendah", "Rendah",
"Sedang", "Sedang", "Sedang", "Sedang",
"Tinggi", "Tinggi"]
```
### Pseudocode: Equal-Width Binning
```
function equiwidth(arr1, m):
// arr1 : array data numerik input
// m : jumlah bin yang diinginkan
n = panjang(arr1)
lebar_rentang = maks(arr1) - min(arr1)
w = lebar_rentang / m
min_val = min(arr1)
// Buat batas-batas bin
batas_bin = array kosong dengan ukuran m + 1
batas_bin[0] = min_val
for i from 1 to m:
batas_bin[i] = min_val + w * i
// Inisialisasi list untuk menyimpan hasil binning
bins = array kosong dengan ukuran m
// Masukkan data ke dalam bin
for i from 0 to m - 1:
bin_i = [ semua elemen j dari arr1 dimana batas_bin[i] <= j <= batas_bin[i+1] ]
tambahkan bin_i ke bins
return bins, batas_bin
```
---
### Contoh Eksekusi:
```
arr1 = [12, 15, 17, 20, 22, 25, 28, 30, 35, 40]
m = 3
hasil_bins, batas = equiwidth(arr1, m)
// hasil_bins akan berisi:
// [
// [12, 15, 17, 20], // Bin 1
// [22, 25, 28, 30], // Bin 2
// [35, 40] // Bin 3
// ]
// batas = [12, 21.33, 30.66, 40]
```
**Kelebihan:**
- Mudah untuk diimplementasikan dan dipahami.
**Kekurangan:**
- Dapat menghasilkan bin dengan distribusi data yang sangat tidak merata.
### 2. **Equal-Frequency Binning**
**Algoritma diskritisasi berdasarkan Fungsi Distribusi Kumulatif (CDF)** untuk membagi data numerik menjadi sejumlah interval dengan **frekuensi yang sama** (*Equal-Frequency Discretization*).
### Konsep Dasar:
- **CDF (Cumulative Distribution Function)**: Memberikan probabilitas bahwa suatu variabel acak bernilai kurang dari atau sama dengan nilai tertentu.
- Untuk diskritisasi, kita gunakan **kuantil** dari CDF untuk menentukan batas antar-bins.
- Misalnya, jika ingin 4 bins → kita gunakan kuantil 0.25, 0.50, dan 0.75.
---
### Algoritma Berdasarkan CDF
### Masukan:
- Sebuah array numerik `data` (misalnya `[4.3, 4.6, 4.7, ..., 5.6]`)
- Jumlah bin yang diinginkan `m`
### Keluaran:
- Array of arrays: tiap array berisi elemen-elemen dalam satu bin
- Atau label kelas untuk setiap elemen
---
### Langkah-langkah Algoritma:
1. **Urutkan data secara ascending**
- Contoh: `[4.3, 4.6, 4.7, 4.9, 5.0, 5.1, 5.2, 5.3, 5.4, 5.6]`
2. **Hitung posisi kuantil**
- Untuk `m` bins, kita butuh `m - 1` titik pemisah
- Posisi kuantil:
$$
q_k = \frac{k}{m},\quad k = 1, 2, ..., m-1
$$
3. **Cari nilai kuantil dari data**
- Gunakan interpolasi linier untuk mendapatkan nilai threshold
- Rumus posisi indeks:
$$
\text{index}_k = (n - 1) \cdot q_k
$$
4. **Buat batas interval**
- Tambahkan nilai `-inf` dan `+inf` sebagai batas awal dan akhir
- Contoh untuk 3 bins:
`batas = [-inf, q1, q2, inf]`
5. **Kelompokkan data ke dalam bins**
- Data dimasukkan ke dalam bin berdasarkan rentang nilai threshold
---
### Contoh
### Diberikan:
```python
data = [4.3, 4.6, 4.7, 4.9, 5.0, 5.1, 5.2, 5.3, 5.4, 5.6]
m = 3
```
#### Langkah 1: Urutkan (sudah urut)
#### Langkah 2: Hitung kuantil
Jumlah data: `n = 10`
Jumlah bins: `m = 3`
Kuantil yang dibutuhkan:
- Q1 = 1/3 = 0.333
- Q2 = 2/3 = 0.666
Posisi kuantil:
- Q1: `(10 - 1) * 1/3 = 9 * 0.333 ≈ 3`
- Q2: `(10 - 1) * 2/3 = 9 * 0.666 ≈ 6`
Nilai kuantil:
- Q1 = data[3] = 4.9
- Q2 = data[6] = 5.2
#### Langkah 3: Buat batas interval
```python
batas = [-inf, 4.9, 5.2, inf]
```
#### Langkah 4: Diskritkan data
| Data | Bin |
|------|-----------|
| 4.3 | < 4.9 → Rendah |
| 4.6 | < 4.9 → Rendah |
| 4.7 | < 4.9 → Rendah |
| 4.9 | ≥4.9 & <5.2 → Sedang |
| 5.0 | ≥4.9 & <5.2 → Sedang |
| 5.1 | ≥4.9 & <5.2 → Sedang |
| 5.2 | ≥5.2 → Tinggi |
| 5.3 | ≥5.2 → Tinggi |
| 5.4 | ≥5.2 → Tinggi |
| 5.6 | ≥5.2 → Tinggi |
---
### Implementasi Python
```python
import numpy as np
def discretize_cdf(data, m):
data_sorted = sorted(data)
n = len(data_sorted)
thresholds = [-float('inf')]
# Hitung kuantil sebagai batas
for k in range(1, m):
q = k / m
index = (n - 1) * q
floor = int(index)
ceil = floor + 1
frac = index - floor
if ceil >= n:
val = data_sorted[floor]
else:
val = data_sorted[floor] + (data_sorted[ceil] - data_sorted[floor]) * frac
thresholds.append(val)
thresholds.append(float('inf'))
# Kelompokkan ke dalam bins
bins = [[] for _ in range(m)]
labels = [0] * n
for i, value in enumerate(data):
for b in range(1, len(thresholds)):
if thresholds[b - 1] <= value < thresholds[b]:
bins[b - 1].append(value)
labels[i] = b - 1
break
return bins, labels, thresholds
```
**Kelebihan:**
- Menjamin ukuran bin yang seimbang, sehingga menghindari bin yang jarang (sparse bins).
**Kekurangan:**
- Lebar bin dapat sangat berbeda-beda.
Implementasi [Link](https://github.com/nani757/Binning-Discretization-_-Quantile-Binning-_-KMeans-Binning/blob/main/Binning%20Discretization%20_%20Quantile%20Binning%20_%20KMeans%20Binning.ipynb) dan [sklean methods](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.KBinsDiscretizer.html)