📘 Pertemuan 4 - Eksplorasi Data (EDA - Exploratory Data Analysis)

🎯 Tujuan Pembelajaran

  1. Memahami tujuan dan langkah dalam eksplorasi data
  2. Menggunakan fungsi Pandas untuk analisis statistik deskriptif
  3. Mengidentifikasi missing value dan outlier
  4. Menginterpretasikan pola dasar dari dataset
  5. Memahami distribusi data dan hubungan antar variabel

🧩 1. Apa itu EDA?

Exploratory Data Analysis (EDA) adalah proses investigasi data untuk memahami karakteristik utama sebelum melakukan analisis lebih lanjut atau pemodelan.

Tujuan EDA:

  • Memahami struktur dan bentuk data
  • Mengidentifikasi pola, tren, dan anomali
  • Mendeteksi outlier dan missing values
  • Menemukan hubungan antar variabel
  • Memvalidasi asumsi untuk analisis lanjutan
  • Menentukan feature engineering yang diperlukan

Tahapan EDA:

  1. Memahami konteks dan tujuan analisis
  2. Mengecek struktur data (tipe, dimensi)
  3. Analisis statistik deskriptif
  4. Visualisasi distribusi data
  5. Deteksi missing values dan outliers
  6. Analisis korelasi antar variabel

📦 2. Dataset yang Digunakan - Iris Dataset

Iris Dataset adalah salah satu dataset paling terkenal dalam machine learning. Dataset ini berisi pengukuran bunga iris dari 3 spesies berbeda.

Informasi Dataset:

  • Jumlah sampel: 150 bunga iris
  • Jumlah fitur: 4 fitur numerik
  • Target: 3 spesies (setosa, versicolor, virginica)
  • Fitur:
    • sepal_length: panjang sepal (cm)
    • sepal_width: lebar sepal (cm)
    • petal_length: panjang petal (cm)
    • petal_width: lebar petal (cm)
# Import library
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# Setting untuk visualisasi
plt.style.use('seaborn-v0_8')
sns.set_palette("husl")

# Membaca dataset Iris dari URL
url = "https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv"
df = pd.read_csv(url)

# Menampilkan 5 data teratas
print("=" * 60)
print("IRIS DATASET - SAMPLE DATA")
print("=" * 60)
print(df.head(10))
print(f"
Jumlah data: {len(df)} baris, {len(df.columns)} kolom")

🔍 3. Eksplorasi Struktur Data

Informasi Dasar Dataset

# Informasi struktur data
print("
" + "=" * 60)
print("INFORMASI DATASET")
print("=" * 60)
print(df.info())

# Cek tipe data
print("
" + "=" * 60)
print("TIPE DATA SETIAP KOLOM")
print("=" * 60)
print(df.dtypes)

# Bentuk data
print(f"
Bentuk data: {df.shape}")
print(f"Jumlah baris: {df.shape[0]}")
print(f"Jumlah kolom: {df.shape[1]}")

# Nama kolom
print(f"
Nama kolom: {list(df.columns)}")

Statistik Deskriptif

# Statistik deskriptif lengkap
print("
" + "=" * 60)
print("STATISTIK DESKRIPTIF")
print("=" * 60)
print(df.describe())

# Statistik untuk semua kolom termasuk kategorikal
print("
" + "=" * 60)
print("STATISTIK LENGKAP (TERMASUK KATEGORIKAL)")
print("=" * 60)
print(df.describe(include='all'))

# Statistik per spesies
print("
" + "=" * 60)
print("JUMLAH SAMPEL PER SPESIES")
print("=" * 60)
print(df['species'].value_counts())
print("
Persentase:")
print(df['species'].value_counts(normalize=True) * 100)

🚨 4. Menangani Missing Value dan Outlier

Deteksi Missing Values

# Mengecek missing value
print("
" + "=" * 60)
print("CEK MISSING VALUES")
print("=" * 60)
print("Jumlah missing value per kolom:")
print(df.isnull().sum())
print(f"
Total missing values: {df.isnull().sum().sum()}")
print(f"Persentase missing: {(df.isnull().sum().sum() / (df.shape[0] * df.shape[1]) * 100):.2f}%")

# Visualisasi missing values (jika ada)
if df.isnull().sum().sum() > 0:
    plt.figure(figsize=(10, 6))
    sns.heatmap(df.isnull(), cbar=False, yticklabels=False, cmap='viridis')
    plt.title("Visualisasi Missing Values")
    plt.show()
else:
    print("
✓ Tidak ada missing values dalam dataset!")

# Menangani missing values (contoh)
# df_clean = df.dropna()  # Hapus baris dengan missing value
# df['column'] = df['column'].fillna(df['column'].mean())  # Isi dengan mean

Deteksi Outlier dengan IQR Method

Interquartile Range (IQR) adalah metode untuk mendeteksi outlier.

  • Q1 (Kuartil 1) = Persentil ke-25
  • Q3 (Kuartil 3) = Persentil ke-75
  • IQR = Q3 - Q1
  • Outlier: nilai < (Q1 - 1.5 × IQR) atau > (Q3 + 1.5 × IQR)
# Fungsi untuk deteksi outlier
def detect_outliers_iqr(data, column):
    """Deteksi outlier menggunakan metode IQR"""
    Q1 = data[column].quantile(0.25)
    Q3 = data[column].quantile(0.75)
    IQR = Q3 - Q1
    
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR
    
    outliers = data[(data[column] < lower_bound) | (data[column] > upper_bound)]
    
    return outliers, lower_bound, upper_bound

# Deteksi outlier untuk setiap kolom numerik
print("
" + "=" * 60)
print("DETEKSI OUTLIER")
print("=" * 60)

numeric_columns = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']

for col in numeric_columns:
    outliers, lower, upper = detect_outliers_iqr(df, col)
    print(f"
{col.upper()}")
    print(f"  Batas bawah: {lower:.2f}")
    print(f"  Batas atas: {upper:.2f}")
    print(f"  Jumlah outlier: {len(outliers)}")
    if len(outliers) > 0:
        print(f"  Outlier indices: {outliers.index.tolist()}")

📊 5. Visualisasi Sederhana

Histogram - Distribusi Data

# Histogram untuk semua fitur numerik
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle('Distribusi Fitur Iris Dataset', fontsize=16, fontweight='bold')

columns = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']
colors = ['#c31432', '#e74c3c', '#3498db', '#2ecc71']

for idx, (col, color) in enumerate(zip(columns, colors)):
    row = idx // 2
    col_idx = idx % 2
    
    axes[row, col_idx].hist(df[col], bins=20, color=color, edgecolor='black', alpha=0.7)
    axes[row, col_idx].axvline(df[col].mean(), color='red', linestyle='--', 
                                linewidth=2, label=f'Mean: {df[col].mean():.2f}')
    axes[row, col_idx].axvline(df[col].median(), color='blue', linestyle='--', 
                                linewidth=2, label=f'Median: {df[col].median():.2f}')
    axes[row, col_idx].set_title(col.replace('_', ' ').title(), fontweight='bold')
    axes[row, col_idx].set_xlabel('Value (cm)')
    axes[row, col_idx].set_ylabel('Frequency')
    axes[row, col_idx].legend()
    axes[row, col_idx].grid(alpha=0.3)

plt.tight_layout()
plt.show()

Boxplot - Deteksi Outlier Visual

# Boxplot untuk deteksi outlier
fig, axes = plt.subplots(1, 4, figsize=(16, 5))
fig.suptitle('Boxplot Fitur Iris Dataset', fontsize=16, fontweight='bold')

for idx, col in enumerate(columns):
    sns.boxplot(y=df[col], ax=axes[idx], color=colors[idx])
    axes[idx].set_title(col.replace('_', ' ').title(), fontweight='bold')
    axes[idx].set_ylabel('Value (cm)')
    axes[idx].grid(axis='y', alpha=0.3)

plt.tight_layout()
plt.show()

Scatter Plot - Hubungan Antar Variabel

# Scatter plot dengan pewarnaan berdasarkan spesies
fig, axes = plt.subplots(1, 2, figsize=(16, 6))
fig.suptitle('Hubungan Antar Variabel', fontsize=16, fontweight='bold')

# Plot 1: Sepal Length vs Petal Length
sns.scatterplot(data=df, x='sepal_length', y='petal_length', 
                hue='species', s=100, alpha=0.7, ax=axes[0])
axes[0].set_title('Sepal Length vs Petal Length', fontweight='bold')
axes[0].set_xlabel('Sepal Length (cm)')
axes[0].set_ylabel('Petal Length (cm)')
axes[0].grid(alpha=0.3)
axes[0].legend(title='Species')

# Plot 2: Sepal Width vs Petal Width
sns.scatterplot(data=df, x='sepal_width', y='petal_width', 
                hue='species', s=100, alpha=0.7, ax=axes[1])
axes[1].set_title('Sepal Width vs Petal Width', fontweight='bold')
axes[1].set_xlabel('Sepal Width (cm)')
axes[1].set_ylabel('Petal Width (cm)')
axes[1].grid(alpha=0.3)
axes[1].legend(title='Species')

plt.tight_layout()
plt.show()

Pairplot - Visualisasi Semua Kombinasi

# Pairplot untuk melihat semua kombinasi variabel
sns.pairplot(df, hue='species', height=2.5, 
             diag_kind='kde', plot_kws={'alpha': 0.6})
plt.suptitle('Pairplot Iris Dataset', y=1.02, fontsize=16, fontweight='bold')
plt.show()

📈 6. Analisis Statistik Per Spesies

# Statistik per spesies
print("
" + "=" * 60)
print("STATISTIK PER SPESIES")
print("=" * 60)

for species in df['species'].unique():
    print(f"
{'='*60}")
    print(f"SPESIES: {species.upper()}")
    print('='*60)
    species_data = df[df['species'] == species][numeric_columns]
    print(species_data.describe())

# Rata-rata per spesies
print("
" + "=" * 60)
print("RATA-RATA FITUR PER SPESIES")
print("=" * 60)
species_mean = df.groupby('species')[numeric_columns].mean()
print(species_mean)

# Visualisasi rata-rata per spesies
species_mean.plot(kind='bar', figsize=(12, 6), rot=0)
plt.title('Rata-rata Fitur per Spesies', fontsize=16, fontweight='bold')
plt.xlabel('Species')
plt.ylabel('Value (cm)')
plt.legend(title='Features', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.grid(axis='y', alpha=0.3)
plt.tight_layout()
plt.show()

🔗 7. Analisis Korelasi

Korelasi mengukur kekuatan hubungan linear antara dua variabel numerik.

  • Korelasi = +1: Hubungan positif sempurna
  • Korelasi = 0: Tidak ada hubungan linear
  • Korelasi = -1: Hubungan negatif sempurna
# Hitung korelasi
correlation_matrix = df[numeric_columns].corr()

print("
" + "=" * 60)
print("MATRIX KORELASI")
print("=" * 60)
print(correlation_matrix)

# Visualisasi heatmap korelasi
plt.figure(figsize=(10, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='RdYlGn', center=0,
            square=True, linewidths=2, cbar_kws={"shrink": 0.8},
            fmt='.2f', vmin=-1, vmax=1)
plt.title('Heatmap Korelasi Fitur Iris Dataset', fontsize=16, fontweight='bold')
plt.tight_layout()
plt.show()

# Interpretasi
print("
" + "=" * 60)
print("INTERPRETASI KORELASI")
print("=" * 60)
for i in range(len(correlation_matrix.columns)):
    for j in range(i+1, len(correlation_matrix.columns)):
        col1 = correlation_matrix.columns[i]
        col2 = correlation_matrix.columns[j]
        corr_value = correlation_matrix.iloc[i, j]
        
        if abs(corr_value) > 0.8:
            strength = "sangat kuat"
        elif abs(corr_value) > 0.6:
            strength = "kuat"
        elif abs(corr_value) > 0.4:
            strength = "sedang"
        else:
            strength = "lemah"
        
        direction = "positif" if corr_value > 0 else "negatif"
        print(f"{col1} vs {col2}: {corr_value:.3f} ({strength} {direction})")

🧠 8. Studi Kasus Mini - Analisis Iris Dataset

📊 Tugas Analisis Lengkap

Lakukan analisis eksplorasi lengkap pada Iris Dataset:

  1. Tampilkan statistik deskriptif tiap kolom
  2. Hitung rata-rata petal_length per jenis species
  3. Visualisasikan hasilnya dengan grafik batang
  4. Identifikasi species mana yang memiliki petal terpanjang
  5. Analisis hubungan antara petal_length dan petal_width
# Solusi lengkap
print("
" + "="*70)
print("ANALISIS KOMPREHENSIF IRIS DATASET")
print("="*70)

# 1. Statistik deskriptif
print("
1. STATISTIK DESKRIPTIF")
print("-"*70)
print(df[numeric_columns].describe())

# 2. Rata-rata petal_length per species
print("
2. RATA-RATA PETAL LENGTH PER SPESIES")
print("-"*70)
mean_petal = df.groupby('species')['petal_length'].agg(['mean', 'min', 'max', 'std'])
print(mean_petal)

# 3. Visualisasi
fig, axes = plt.subplots(1, 2, figsize=(15, 5))

# Bar chart rata-rata petal_length
mean_petal['mean'].plot(kind='bar', color=['#c31432', '#e74c3c', '#f39c12'], 
                        ax=axes[0], edgecolor='black')
axes[0].set_title('Rata-rata Petal Length per Spesies', fontweight='bold', fontsize=14)
axes[0].set_xlabel('Species')
axes[0].set_ylabel('Petal Length (cm)')
axes[0].set_xticklabels(axes[0].get_xticklabels(), rotation=45)
axes[0].grid(axis='y', alpha=0.3)

# Tambahkan nilai di atas bar
for i, v in enumerate(mean_petal['mean']):
    axes[0].text(i, v + 0.1, f'{v:.2f}', ha='center', fontweight='bold')

# Box plot petal_length per species
sns.boxplot(data=df, x='species', y='petal_length', 
            palette=['#c31432', '#e74c3c', '#f39c12'], ax=axes[1])
axes[1].set_title('Distribusi Petal Length per Spesies', fontweight='bold', fontsize=14)
axes[1].set_xlabel('Species')
axes[1].set_ylabel('Petal Length (cm)')
axes[1].grid(axis='y', alpha=0.3)

plt.tight_layout()
plt.show()

# 4. Identifikasi species dengan petal terpanjang
longest_petal_species = mean_petal['mean'].idxmax()
longest_petal_value = mean_petal['mean'].max()

print(f"
3. SPESIES DENGAN PETAL TERPANJANG")
print("-"*70)
print(f"Spesies: {longest_petal_species}")
print(f"Rata-rata petal length: {longest_petal_value:.2f} cm")

# 5. Analisis korelasi petal_length vs petal_width
print(f"
4. ANALISIS HUBUNGAN PETAL LENGTH VS PETAL WIDTH")
print("-"*70)
corr_petal = df['petal_length'].corr(df['petal_width'])
print(f"Korelasi: {corr_petal:.3f}")

if corr_petal > 0.7:
    print("Interpretasi: Hubungan positif yang sangat kuat")
    print("Semakin panjang petal, semakin lebar petal cenderung lebih besar")
elif corr_petal > 0.4:
    print("Interpretasi: Hubungan positif yang kuat")
else:
    print("Interpretasi: Hubungan positif yang sedang")

# Visualisasi scatter plot dengan trendline
plt.figure(figsize=(10, 6))
sns.regplot(data=df, x='petal_length', y='petal_width', 
            scatter_kws={'s': 100, 'alpha': 0.6}, color='#c31432')
plt.title('Hubungan Petal Length vs Petal Width
' + 
          f'(Korelasi: {corr_petal:.3f})', fontweight='bold', fontsize=14)
plt.xlabel('Petal Length (cm)', fontsize=12)
plt.ylabel('Petal Width (cm)', fontsize=12)
plt.grid(alpha=0.3)
plt.tight_layout()
plt.show()

print("
" + "="*70)
print("KESIMPULAN")
print("="*70)
print(f"1. Dataset Iris memiliki 3 spesies dengan karakteristik berbeda")
print(f"2. Spesies {longest_petal_species} memiliki petal terpanjang ({longest_petal_value:.2f} cm)")
print(f"3. Petal length dan petal width memiliki korelasi {corr_petal:.3f} (sangat kuat)")
print(f"4. Tidak ditemukan missing values dalam dataset")
print(f"5. Terdapat beberapa outlier pada beberapa fitur yang perlu diperhatikan")
print("="*70)

💡 Tips EDA yang Efektif:

  • Selalu mulai dengan memahami konteks dan tujuan analisis
  • Gunakan visualisasi untuk membantu interpretasi
  • Dokumentasikan setiap temuan penting
  • Jangan langsung menghapus outlier - pahami dulu penyebabnya
  • Perhatikan distribusi data untuk menentukan metode analisis selanjutnya
  • Cari pola yang tidak biasa atau menarik dalam data

🧩 9. Latihan Mandiri

Latihan 1: Analisis Dataset Lain

  1. Download dataset Titanic dari: https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv
  2. Lakukan eksplorasi awal (shape, info, describe)
  3. Identifikasi missing values dan outliers
  4. Buat visualisasi distribusi umur penumpang
  5. Analisis survival rate berdasarkan kelas dan jenis kelamin

Latihan 2: Analisis Korelasi

  1. Gunakan dataset Iris
  2. Hitung korelasi antara semua fitur numerik
  3. Buat heatmap korelasi
  4. Identifikasi pasangan fitur dengan korelasi tertinggi
  5. Buat scatter plot untuk pasangan tersebut

Latihan 3: Analisis Per Kategori

  1. Pilih dataset dengan variabel kategorikal
  2. Hitung statistik deskriptif per kategori
  3. Buat visualisasi perbandingan antar kategori
  4. Identifikasi perbedaan signifikan antar kategori
  5. Tuliskan kesimpulan dari analisis

✍️ Kesimpulan

Pada pertemuan ini, mahasiswa telah mempelajari:

  • ✅ Konsep dan tujuan Exploratory Data Analysis (EDA)
  • ✅ Cara mengeksplorasi struktur dan karakteristik data
  • ✅ Metode deteksi missing values dan outliers
  • ✅ Teknik visualisasi data untuk EDA (histogram, boxplot, scatter plot)
  • ✅ Analisis statistik deskriptif dan korelasi
  • ✅ Interpretasi hasil analisis eksplorasi

Pertemuan selanjutnya: Visualisasi Data dengan Matplotlib dan Seaborn untuk membuat grafik yang lebih informatif dan menarik.