Studi Kasus Analisis Data Kesehatan dengan Missing Values

Studi Kasus Analisis Data Kesehatan dengan Missing Values

Latar Belakang Masalah

Sebuah rumah sakit ingin menganalisis data pasien rawat jalan untuk memprediksi risiko diabetes. Dataset mengandung missing values karena:

  • Pasien menolak memberikan informasi tertentu
  • Kesalahan input petugas administrasi
  • Data lab tidak lengkap untuk pasien tertentu

Dataset Contoh (data_pasien.csv):

ID Usia Gender Glukosa Tekanan_Darah BMI Riwayat_Keluarga HbA1c
1 45 L 148 72 33.6 Ya 6.1
2 50 P NaN 90 26.6 Tidak NaN
3 32 L 138 NaN 43.1 Ya 5.7
4 NaN P 96 74 NaN Tidak 5.0
5 61 L NaN 82 28.1 NaN 6.5

Analisis Missing Data

a. Eksplorasi Awal

python
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv('data_pasien.csv')
print("Persentase Missing Values:")
print(df.isnull().mean() * 100)

plt.figure(figsize=(10,4))
plt.title('Distribusi Missing Values')
sns.heatmap(df.isnull(), cbar=False, cmap='Blues')
plt.show()

Output:

Persentase Missing Values:
Usia               20.0
Gender             10.0
Glukosa            40.0
Tekanan_Darah      20.0
BMI                20.0
Riwayat_Keluarga   20.0
HbA1c              40.0
dtype: float64

b. Pola Missing Data

python
import missingno as msno

# Matrix plot untuk identifikasi pola
msno.matrix(df)
plt.show()

# Korelasi missing values antar kolom
msno.heatmap(df)
plt.show()

Solusi Penanganan

a. Penanganan Berdasarkan Jenis Kolom

1. Kolom Numerik (Glukosa, Tekanan Darah, BMI, HbA1c)

python
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer

# Imputasi multivariat
imputer = IterativeImputer(max_iter=10, random_state=42)
numeric_cols = ['Usia', 'Glukosa', 'Tekanan_Darah', 'BMI', 'HbA1c']
df[numeric_cols] = imputer.fit_transform(df[numeric_cols])

2. Kolom Kategorik (Gender, Riwayat_Keluarga)

python
# Imputasi modus + flag missing
df['Gender'].fillna(df['Gender'].mode()[0], inplace=True)
df['Riwayat_Keluarga'].fillna('Tidak Diketahui', inplace=True)

b. Validasi Hasil Imputasi

python
# Bandingkan statistik sebelum-sesudah
original_stats = df.describe()

# Buat data artifisial untuk validasi
df_artificial = df.copy()
for col in numeric_cols:
    df_artificial[col] = np.where(
        np.random.random(len(df)) < 0.2, 
        np.nan, 
        df[col]
    )

# Imputasi data artifisial
df_imputed = df_artificial.copy()
df_imputed[numeric_cols] = imputer.fit_transform(df_imputed[numeric_cols])

# Hitung error
mse = ((df[numeric_cols] - df_imputed[numeric_cols])**2).mean()
print("Mean Squared Error Imputasi:", mse)

Implementasi Lengkap

python
import pandas as pd
import numpy as np
from sklearn.impute import KNNImputer, SimpleImputer
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline

# 1. Baca Data
df = pd.read_csv('data_pasien.csv')

# 2. Pipeline Imputasi
numeric_features = ['Usia', 'Glukosa', 'Tekanan_Darah', 'BMI', 'HbA1c']
categorical_features = ['Gender', 'Riwayat_Keluarga']

numeric_transformer = Pipeline(steps=[
    ('imputer', KNNImputer(n_neighbors=3)),
])

categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='most_frequent')),
])

preprocessor = ColumnTransformer(
    transformers=[
        ('num', numeric_transformer, numeric_features),
        ('cat', categorical_transformer, categorical_features)
    ])

# 3. Eksekusi Imputasi
df_clean = pd.DataFrame(
    preprocessor.fit_transform(df),
    columns=numeric_features + categorical_features
)

# 4. Tambahkan kolom ID kembali
df_clean['ID'] = df['ID']

# 5. Simpan Data Bersih
df_clean.to_csv('data_pasien_clean.csv', index=False)

print("Data setelah cleaning:")
print(df_clean.head())

Visualisasi Hasil

a. Sebelum vs Sesudah Imputasi

python
fig, axes = plt.subplots(2, 2, figsize=(12,8))

# Glukosa
sns.kdeplot(df['Glukosa'], ax=axes[0,0], label='Original', fill=True)
sns.kdeplot(df_clean['Glukosa'], ax=axes[0,0], label='Imputed', fill=True)
axes[0,0].set_title('Distribusi Glukosa')

# BMI
sns.boxplot(data=pd.DataFrame({
    'Original': df['BMI'],
    'Imputed': df_clean['BMI']
}), ax=axes[0,1])
axes[0,1].set_title('Perbandingan BMI')

# HbA1c sebelum-sesudah
df['HbA1c_imputed'] = df_clean['HbA1c']
sns.scatterplot(data=df, x='Usia', y='HbA1c', 
                hue='HbA1c_imputed', ax=axes[1,0])
axes[1,0].set_title('Hubungan Usia-HbA1c')

plt.tight_layout()
plt.show()

Rekomendasi untuk Analisis Lanjutan

  1. Uji Sensitivitas:
    python
    # Bandingkan hasil model dengan berbagai metode imputasi
    from sklearn.linear_model import LogisticRegression
    from sklearn.model_selection import cross_val_score
    
    # Contoh: Prediksi diabetes (asumsi target ada)
    X = df_clean[numeric_features]
    y = df['Diabetes']  # Asumsi kolom target ada
    
    model = LogisticRegression()
    scores = cross_val_score(model, X, y, cv=5)
    print("Akurasi model setelah imputasi:", scores.mean())
  2. Dokumentasi Proses:
    PROTOKOL PENANGANAN MISSING VALUES:
    1. Kolom numerik:
       - Imputasi menggunakan KNN (k=3)
       - Pertimbangkan korelasi antar variabel
    2. Kolom kategorik:
       - Isi dengan modus
       - Tambahkan kategori 'Tidak Diketahui' jika perlu
    3. Validasi:
       - Bandingkan distribusi sebelum-sesudah
       - Hitung MSE pada data artifisial

Lesson Learned

  • Tantangan:
    • HbA1c memiliki 40% missing values (butuh investigasi klinis)
    • Korelasi missing antara Glukosa dan HbA1c (MAR)
  • Solusi Efektif:
    • Imputasi multivariat untuk data laboratorium
    • Penanganan berbeda untuk tipe data (numerik vs kategorik)
  • Hasil:
    • Dataset lengkap tanpa mengurangi sampel
    • Mempertahankan distribusi asli variabel
    • Siap untuk analisis statistik/modeling

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *