MA1420 · DATA SAINS · SESI 06

Tipe Data I:
Klasifikasi & Karakteristik

Sebelum menganalisis data, kita harus tahu apa jenis datanya. Menggunakan rata-rata untuk data nominal, atau membuat boxplot untuk data ordinal, adalah kesalahan dasar yang sering terjadi. Sesi ini membangun fondasi pemahaman tipe data yang benar.

1. Mengapa Memahami Tipe Data Itu Krusial?

Setiap analisis statistik dan machine learning mengasumsikan tipe data tertentu. Salah tipe data = metode yang salah = kesimpulan yang menyesatkan.

💡 ILUSTRASI — ALAT MASAK YANG TEPAT

Bayangkan Anda ingin membuat mie goreng tapi menggunakan blender — hasilnya bukan mie goreng, melainkan bubur aneh. Alat yang salah menghasilkan output yang salah, meski bahan bakunya sama.

Begitu pula dengan analisis data: menghitung rata-rata kode pos (nominal) tidak ada maknanya, walau secara teknis bisa dihitung. Atau membuat histogram warna favorit (nominal) menghasilkan informasi yang keliru. Kenali tipe datamu sebelum memilih alat analisisnya.

⚠️ CONTOH KESALAHAN NYATA

• Menghitung rata-rata "nomor rumah sakit" (nominal) → angkanya ada, tapi tidak bermakna

• Melakukan uji-t pada data "peringkat kepuasan 1–5" (ordinal) → asumsi skala jarak tidak terpenuhi

• Memperlakukan "jumlah anak: 0, 1, 2, 3" sebagai kontinu → 2.4 anak tidak ada artinya

• Mengkodekan "jenis kelamin: L=1, P=2" lalu menghitung rata-ratanya → "1.5 jenis kelamin" tidak bermakna

2. Peta Klasifikasi Tipe Data

DATA
Kualitatif
(Kategorikal)
Nominal
Ordinal
Kuantitatif
(Numerik)
Diskrit
Kontinu
💡 ILUSTRASI — FORMULIR MAHASISWA BARU

Bayangkan formulir pendaftaran mahasiswa. Di dalamnya ada berbagai jenis pertanyaan:

Nama → Kualitatif Nominal  |  Peringkat SMA → Kualitatif Ordinal  |  Jumlah Saudara → Kuantitatif Diskrit  |  Tinggi Badan → Kuantitatif Kontinu

Empat pertanyaan, empat tipe data yang berbeda — masing-masing memerlukan pendekatan analisis yang berbeda pula.

3. Data Kualitatif (Kategorikal)

Data kualitatif mewakili kategori atau label — bukan angka dalam arti matematis. Meski bisa dikodekan dengan angka (1, 2, 3), angka tersebut hanya label, bukan nilai numerik sejati.

🏷️
Nominal
Kategorikan tanpa urutan

Kategori yang tidak memiliki urutan yang bermakna. Satu kategori tidak "lebih besar" dari yang lain.

Jenis kelamin: L / P
Warna favorit: merah / biru / hijau
Golongan darah: A / B / AB / O
Kode pos: 12830, 10110
Status: menikah / lajang
✓ Boleh: modus, frekuensi, persentase, bar chart, pie chart
✗ Jangan: mean, median, standar deviasi, histogram
🏆
Ordinal
Kategorikan dengan urutan

Kategori yang memiliki urutan bermakna, tapi jarak antar kategori tidak harus sama.

Tingkat pendidikan: SD < SMP < SMA < S1
Kepuasan: tidak puas < netral < puas
Ukuran baju: S < M < L < XL
Peringkat lomba: Juara 1, 2, 3
Skala Likert: 1=sangat tidak setuju ... 5=sangat setuju
✓ Boleh: median, modus, frekuensi, bar chart, uji Spearman
✗ Hati-hati: mean (jarak tidak sama!), uji-t (kecuali asumsi terpenuhi)
💡 ILUSTRASI — NOMINAL vs ORDINAL: LOMBA LARI

Nama peserta (Budi, Andi, Citra) = Nominal — tidak ada yang "lebih besar".

Peringkat finish (Juara 1, 2, 3) = Ordinal — ada urutan, tapi jarak waktu antara Juara 1 dan 2 bisa saja berbeda jauh dengan jarak antara Juara 2 dan 3. Kita tahu urutannya, tapi tidak tahu seberapa besar perbedaannya dari peringkat saja.

4. Data Kuantitatif (Numerik)

Data kuantitatif adalah angka sejati yang merepresentasikan jumlah atau ukuran — operasi aritmatika seperti penjumlahan dan pengurangan memiliki makna.

🔢
Diskrit
Bilangan bulat terhitung

Nilai yang dapat dihitung satu per satu dan biasanya berupa bilangan bulat. Ada "celah" antar nilai — tidak ada nilai di antara dua nilai berurutan.

Jumlah mahasiswa: 0, 1, 2, ... 45
Jumlah kendaraan: 0, 1, 2, 3...
Jumlah gol dalam pertandingan
Jumlah klik iklan
Skor kuis (0, 10, 20, 30...)
✓ Boleh: semua ukuran numerik, histogram, boxplot, bar chart
✗ Perhatikan: nilai pecahan mungkin tidak bermakna (2.3 anak)
📏
Kontinu
Nilai tak terbatas dalam rentang

Nilai yang dapat mengambil semua nilai dalam suatu rentang — termasuk pecahan. Hanya dibatasi oleh presisi alat ukur.

Tinggi badan: 170.5 cm, 170.51 cm...
Suhu: 36.7°C, 36.75°C...
Berat badan: 65.3 kg
Nilai IPK: 3.75
Waktu berlari: 9.58 detik
✓ Boleh: semua operasi numerik, mean, std, histogram, scatter plot
✗ Perhatikan: distribusi penting (normal? skewed?)
💡 ILUSTRASI — DISKRIT vs KONTINU: MEMOTRET vs MEREKAM VIDEO

Data Diskrit = Foto snapshot. Kita hanya bisa punya foto ke-1, ke-2, ke-3 — tidak ada foto ke-1.7. Nilai "loncat" dari satu ke yang berikutnya.

Data Kontinu = Video. Setiap momen bisa ditangkap — 1 detik, 1.5 detik, 1.51 detik. Ada nilai di antara setiap dua nilai yang ada. Hanya kualitas kamera (presisi alat ukur) yang membatasi detail yang bisa direkam.

5. Empat Skala Pengukuran (Stevens, 1946)

Klasifikasi yang lebih detail dikembangkan oleh Stanley Smith Stevens. Setiap skala "mewarisi" semua kemampuan skala di bawahnya, plus kemampuan tambahan.

NOMINAL

Skala Nominal — Hanya Label

Angka hanya digunakan sebagai label atau kode. Tidak ada makna matematis sama sekali.

Contoh: Nomor jersey pemain (Ronaldo #7 tidak "lebih besar" dari Messi #10)

✓ Kategori berbeda ✗ Urutan ✗ Jarak sama ✗ Nol absolut
ORDINAL

Skala Ordinal — Ada Urutan, Jarak Tidak Pasti

Kategori memiliki urutan bermakna, tetapi selisih antar peringkat tidak harus setara.

Contoh: Peringkat kelas (Juara 1 lebih baik dari Juara 2, tapi tidak tahu seberapa lebih baik)

✓ Kategori berbeda ✓ Urutan ✗ Jarak sama ✗ Nol absolut
INTERVAL

Skala Interval — Jarak Sama, Nol Relatif

Ada urutan DAN jarak antar nilai setara. Namun nol tidak berarti "tidak ada" — hanya titik referensi.

Contoh: Suhu Celsius: 0°C bukan "tidak ada suhu", dan 20°C tidak berarti "dua kali lebih panas" dari 10°C

✓ Kategori berbeda ✓ Urutan ✓ Jarak sama ✗ Nol absolut
RASIO

Skala Rasio — Lengkap, Nol Absolut

Skala paling lengkap. Ada urutan, jarak sama, DAN nol berarti "tidak ada". Perbandingan rasio bermakna.

Contoh: Tinggi badan: 0 cm = tidak ada tinggi; 180 cm benar-benar dua kali 90 cm.

✓ Kategori berbeda ✓ Urutan ✓ Jarak sama ✓ Nol absolut
💡 PERBEDAAN KUNCI INTERVAL vs RASIO

Suhu Celsius (Interval): 20°C tidak "dua kali lebih panas" dari 10°C — karena 0°C bukan "tidak ada panas", hanya titik beku air.

Suhu Kelvin (Rasio): 200K memang dua kali lebih panas dari 100K — karena 0K = nol absolut (tidak ada gerakan molekul sama sekali).

Berat badan (Rasio): 80 kg memang dua kali 40 kg — 0 kg benar-benar tidak ada berat.

6. Operasi Statistik yang Diizinkan per Skala

Operasi
Nominal
Ordinal
Interval
Rasio
= (sama/beda)
Urutan (< >)
Modus
Median
Mean (Rata-rata)
Std Deviasi
Rasio (A = 2×B)

7. Representasi Tipe Data di Pandas Python

Pandas memetakan konsep statistik tipe data ke dalam dtype (data type) teknis. Memilih dtype yang tepat menghemat memori dan mengaktifkan operasi yang benar.

int64 / int32
Bilangan bulat. Cocok untuk data diskrit seperti jumlah, umur (tahun), skor.
jumlah_mahasiswa: 30, 28, 35
float64 / float32
Bilangan desimal. Untuk data kontinu seperti tinggi, berat, IPK, suhu.
ipk: 3.75, 3.50, 2.89
object
Teks/string. Default untuk data nominal. Boros memori jika banyak kategori.
nama: "Budi", "Andi"
kota: "Jakarta"
category
Kategori dengan nilai terbatas. Lebih efisien dari object, mendukung urutan (ordinal).
grade: "A", "B", "C"
ukuran: "S", "M", "L", "XL"
bool
Nilai benar/salah. Cocok untuk flag, status biner, atau hasil perbandingan.
lulus: True, False
aktif: True
datetime64
Tanggal dan waktu. Memungkinkan ekstraksi hari, bulan, tahun, dan operasi temporal.
tgl_lahir: 2002-05-15
waktu: 2024-01-01 08:30
⚡ TIPS PENTING: category vs object

Jika kolom teks memiliki kardinality rendah (sedikit nilai unik, seperti jenis kelamin, grade, status), gunakan dtype category bukan object.

Manfaatnya: hemat memori hingga 5–10×, mendukung pengurutan ordinal, dan operasi groupby menjadi lebih cepat.

8. Kesalahan Umum Penanganan Tipe Data

⚠️
Angka sebagai Kategori — Tidak Dikonversi
Data kategorikal yang dikodekan angka (1=L, 2=P) dibiarkan bertipe int64. Model ML akan memperlakukan ini sebagai numerik dan menghitung rata-rata, dsb.
✓ Solusi: konversi ke dtype 'category' atau gunakan One-Hot Encoding untuk ML
⚠️
Ordinal Diperlakukan sebagai Nominal
Kolom "tingkat_pendidikan" disimpan sebagai object tanpa urutan. Saat diurutkan, "SMA" bisa muncul sebelum "S1" secara alfabetis, bukan secara logis.
✓ Solusi: gunakan pd.CategoricalDtype(categories=[...], ordered=True) untuk menetapkan urutan
⚠️
Tanggal Disimpan sebagai String
Kolom "tanggal_lahir" bertipe object. Tidak bisa dihitung umur, tidak bisa difilter berdasarkan tahun, tidak bisa diplot sebagai time series dengan benar.
✓ Solusi: pd.to_datetime() untuk konversi ke datetime64, aktifkan operasi temporal
⚠️
Menggunakan Mean pada Data Ordinal
Menghitung rata-rata skala Likert (1–5) dianggap valid padahal jarak antar nilai tidak harus setara (jarak antara "tidak puas" dan "netral" bisa berbeda dari "netral" ke "puas").
✓ Solusi: gunakan median atau modus untuk data ordinal; mean hanya jika diasumsikan interval

9. Praktik: Identifikasi & Konversi Tipe Data di Pandas

9.1 Dataset dengan Berbagai Tipe Data

PYTHON · MEMBUAT DATASET CONTOH
import pandas as pd
import numpy as np

# Dataset mahasiswa dengan berbagai tipe data
data = {
    'nim':           ['2021001', '2021002', '2021003', '2021004', '2021005'],
    'nama':          ['Andi', 'Budi', 'Citra', 'Dewi', 'Eko'],
    'jenis_kelamin': ['L', 'L', 'P', 'P', 'L'],          # nominal
    'grade':         ['B', 'A', 'A', 'C', 'B'],             # ordinal
    'jumlah_mk':     [6, 7, 6, 5, 7],                      # diskrit
    'ipk':           [3.45, 3.78, 3.92, 2.85, 3.60],       # kontinu (rasio)
    'tgl_masuk':     ['2021-09-01']*5,                       # tanggal (string → datetime)
    'aktif':         [True, True, True, False, True]         # boolean
}

df = pd.DataFrame(data)
print("=== INFO AWAL (DTYPE DEFAULT) ===")
print(df.dtypes)
print(f"\nMemori digunakan: {df.memory_usage(deep=True).sum():,} bytes")
📤 OUTPUT AWAL
=== INFO AWAL (DTYPE DEFAULT) ===
nim               object    ← harusnya tetap string
nama              object    ← sudah benar
jenis_kelamin     object    ← sebaiknya category (nominal)
grade             object    ← sebaiknya category ordered (ordinal)
jumlah_mk          int64    ← sudah benar (diskrit)
ipk              float64    ← sudah benar (kontinu)
tgl_masuk         object    ← harusnya datetime64!
aktif               bool    ← sudah benar
dtype: object

Memori digunakan: 2,728 bytes

9.2 Konversi Tipe Data yang Tepat

PYTHON · KONVERSI & OPTIMASI TIPE DATA
# ── 1. Nominal → category ────────────────────────────
df['jenis_kelamin'] = df['jenis_kelamin'].astype('category')

# ── 2. Ordinal → category dengan urutan ─────────────
grade_order = pd.CategoricalDtype(
    categories=['D', 'C', 'B', 'A'],
    ordered=True   # D < C < B < A
)
df['grade'] = df['grade'].astype(grade_order)

# ── 3. String → datetime64 ──────────────────────────
df['tgl_masuk'] = pd.to_datetime(df['tgl_masuk'])

# ── 4. Cek hasil konversi ───────────────────────────
print("=== SETELAH KONVERSI ===")
print(df.dtypes)
print(f"\nMemori setelah: {df.memory_usage(deep=True).sum():,} bytes")

# ── 5. Manfaat urutan ordinal ───────────────────────
print("\n=== MANFAAT ORDINAL TERURUT ===")
print("Apakah grade 'A' > 'B'? :", df['grade'][1] > df['grade'][0])
print("Mahasiswa dengan grade ≥ B:")
print(df[df['grade'] >= 'B'][['nama', 'grade', 'ipk']])
📤 OUTPUT
=== SETELAH KONVERSI ===
nim                      object
nama                     object
jenis_kelamin          category    ✓ nominal
grade          category (ordered)  ✓ ordinal terurut  D < C < B < A
jumlah_mk               int64
ipk                    float64
tgl_masuk        datetime64[ns]    ✓ bisa ekstrak tahun/bulan
aktif                    bool

Memori setelah: 1,856 bytes  ← lebih hemat!

=== MANFAAT ORDINAL TERURUT ===
Apakah grade 'A' > 'B'? : True
Mahasiswa dengan grade ≥ B:
   nama grade   ipk
0  Andi     B  3.45
1  Budi     A  3.78
2  Citra    A  3.92
4  Eko      B  3.60

9.3 Eksplorasi dan Analisis Sesuai Tipe Data

PYTHON · ANALISIS SESUAI TIPE DATA
import matplotlib.pyplot as plt

# Dataset lebih besar untuk visualisasi
np.random.seed(42)
n = 100
df_besar = pd.DataFrame({
    'jk'   : np.random.choice(['L','P'], n),
    'grade': np.random.choice(['A','B','C','D'], n, p=[.25,.40,.25,.10]),
    'mk'   : np.random.randint(4, 9, n),
    'ipk'  : np.random.normal(3.2, 0.4, n).clip(0, 4)
})

fig, axes = plt.subplots(1, 3, figsize=(14, 4))

# ① Nominal → Bar chart (frekuensi)
df_besar['jk'].value_counts().plot(kind='bar', ax=axes[0],
    color=['#3B82F6','#C084FC'], edgecolor='white')
axes[0].set_title('Jenis Kelamin (Nominal)\n→ Bar Chart Frekuensi')

# ② Ordinal → Bar chart terurut
grade_counts = df_besar['grade'].value_counts().reindex(['A','B','C','D'])
grade_counts.plot(kind='bar', ax=axes[1],
    color=['#22D3EE','#3B82F6','#F59E0B','#F87171'], edgecolor='white')
axes[1].set_title('Grade (Ordinal)\n→ Bar Chart Berurutan A→D')

# ③ Kontinu → Histogram
axes[2].hist(df_besar['ipk'], bins=15, color='#4ADE80',
             edgecolor='white', alpha=0.85)
axes[2].set_title('IPK (Kontinu/Rasio)\n→ Histogram Distribusi')
axes[2].axvline(df_besar['ipk'].mean(), color='red',
               linestyle='--', label=f"Mean={df_besar['ipk'].mean():.2f}")
axes[2].legend()

plt.tight_layout()
plt.show()

Latihan Identifikasi Tipe Data

Klik tipe data yang paling tepat untuk setiap variabel berikut:

🎯 IDENTIFIKASI TIPE DATA — KLIK JAWABAN YANG TEPAT
🌡️ Suhu udara dalam derajat Celsius
📚 Tingkat pendidikan (SD / SMP / SMA / S1)
⚖️ Berat badan dalam kilogram
🩸 Golongan darah (A / B / AB / O)
🚗 Jumlah kendaraan yang dimiliki keluarga
📅 Tahun kelahiran (1995, 2000, 2003)

Uji Pemahaman Sesi 6

🧩 PERTANYAAN 1 — SKALA PENGUKURAN
Seorang peneliti mencatat "nomor kursi peserta" (A1, A2, B1, B2...) dan "skor ujian (0–100)". Masing-masing termasuk skala pengukuran apa?
Benar! Nomor kursi (A1, A2...) adalah Nominal — hanya label, tidak ada makna urutan atau jarak. Skor ujian (0–100) adalah Rasio — ada nol absolut (skor 0 = tidak ada jawaban benar), jarak sama, dan 80 memang dua kali lebih besar dari 40.
🧩 PERTANYAAN 2 — OPERASI YANG TEPAT
Peneliti mengumpulkan data "kepuasan pelanggan" dengan skala: 1=Sangat Tidak Puas, 2=Tidak Puas, 3=Netral, 4=Puas, 5=Sangat Puas. Analisis mana yang PALING TEPAT?
Benar! Data kepuasan 1–5 adalah Ordinal — ada urutan (5 > 4 > 3...) tapi jarak antar nilai tidak harus sama. Median dan modus adalah ukuran yang tepat. Rata-rata dan std deviasi secara teknis bisa dihitung tapi tidak sepenuhnya bermakna karena asumsi jarak sama tidak terpenuhi.
🧩 PERTANYAAN 3 — PANDAS DTYPE
Kolom "status_pernikahan" dalam DataFrame berisi nilai "menikah", "lajang", "cerai" dan memiliki 500.000 baris. Dtype Pandas mana yang PALING EFISIEN?
Benar! Dengan 500.000 baris tapi hanya 3 nilai unik, dtype category jauh lebih efisien dari object. Pandas hanya menyimpan integer internal (0, 1, 2) plus kamus kecil untuk mapping, bukan menyimpan string "menikah" sebanyak 500.000 kali. Penghematan memori bisa 5-10× lipat!
📋 Ringkasan Sesi 6