Memprediksi Cuaca dengan Machine Learning: Regresi Linier & Regresi Logistik
Dari 96.000+ data cuaca Hungaria hingga 145.000+ hari hujan Australia — sebuah perjalanan lengkap memahami dua fondasi algoritma Machine…
Memprediksi Cuaca dengan Machine Learning: Regresi Linier & Regresi Logistik

Dari 96.000+ data cuaca Hungaria hingga 145.000+ hari hujan Australia — sebuah perjalanan lengkap memahami dua fondasi algoritma Machine Learning.
🌤️ Pendahuluan: Mengapa Cuaca?
Cuaca adalah salah satu domain data paling kaya di dunia. Setiap jam, ribuan stasiun cuaca di seluruh dunia merekam suhu, kelembapan, tekanan udara, hingga kecepatan angin. Data ini bukan sekadar angka — ia adalah cerita tentang atmosfer yang bisa kita “baca” menggunakan Machine Learning.
Pada artikel ini, saya akan memandu kamu melalui dua proyek analisis cuaca yang berbeda namun saling melengkapi:
- **Regresi Linier — Berapa derajat suhu udara besok ? *Menggunakan dataset Szeged Weather* dari Hungaria (96.453 baris data, 2006–2016) untuk memprediksi suhu udara dalam satuan °C berdasarkan kelembapan, kecepatan angin, visibilitas, dan tekanan udara.
- **Regresi Logistik — Apakah besok akan hujan ? *Menggunakan dataset Rain in Australia* (145.460 baris data) untuk memprediksi apakah besok akan terjadi hujan atau tidak — sebuah masalah klasifikasi biner Yes/No.
“Regresi Linier menjawab berapa banyak, Regresi Logistik menjawab ya atau tidak.”
📦 Bagian 0— Import Library
import kagglehub
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, LogisticRegression
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.metrics import (
mean_squared_error, mean_absolute_error, r2_score,
accuracy_score, precision_score, recall_score,
f1_score, confusion_matrix, classification_report
)
print('✅ Semua library berhasil diimport!')
Pada kode tersebut adalah library atau module yang akan saya gunakan untuk membuat model regresi linier dan juga regresi logistik.
🌤️ Bagian 1 — Regresi Linier: Prediksi Suhu Udara
1.1 — Download & Load Dataset
# Download dataset Szeged Weather
path_weather = kagglehub.dataset_download("budincsevity/szeged-weather")
print("Path dataset:", path_weather)
# Load CSV
df_linear = pd.read_csv(f"{path_weather}/weatherHistory.csv")
print(f"\n✅ Dataset berhasil dimuat!")
print(f"Jumlah baris: {len(df_linear):,}") # Jumlah baris: 96,453
print(f"Jumlah kolom: {df_linear.shape[1]}") # Jumlah kolom: 12
Untuk kode ini saya melakukan download dataset yang berasal dari kaggle yang nantinya file dataset tersebut tersimpan didalam folder penyimpanan Goggle Colab nya itu sendiri yang tersimpan secara temporary.
Untuk kode selanjutnya itu, saya melakukan load data untuk memparsing data dari format teks mentah dalam file .csv menjadi objek DataFrame di dalam memori komputer, setelah DataFrame telah dibuat selanjutnya saya melakukan pengechekan terkait Jumlah Baris dan Kolom yang tersedia pada data tersebut.
1.2 — Eksplorasi Data (EDA)
# Tampilkan 5 baris pertama
print("=== 5 Baris Pertama Dataset ===")
df_linear.head()
Pada kode ini tujuannya untuk melihat data secara keseluruhan namun hanya mencetak 5 baris pertamanya saja, karena by default .head() hanya menampilkan 5 baris data saja.

DataFrame
# Info tipe data dan jumlah non-null
print("=== Info Dataset ===")
df_linear.info()
Untuk kode ini agar kita bisa melihat metadata secara cepat dari sebuah DataFrame, mencakup jumlah baris, nama kolom, tipe data dan juga jumlah non-null (tidak kosong) disetiap kolom.

Metadata Dataset
# Statistik deskriptif
print("=== Statistik Deskriptif ===")
df_linear.describe().round(2)
Terkait kode ini saya melakukan untuk mendapatkan perhitungan ringkasan statistik matematik dari seluruh kolom angka (numerik) yang ada didalam dataset secara instan.

Statistik Deskriptif
# Cek missing values
print("=== Missing Values ===")
missing = df_linear.isnull().sum()
# missing[missing > 0]
print(missing[missing > 0] if missing.sum() > 0 else "Tidak ada missing values!")
Pada kode ini saya melakukan pengechekan dan menghitung secara pasti berapa banyak data yang kosong didalam dataset tersebut, jika kalian bingung terhadap perkondisian nya pada kode tersebut saya menggunakan tenary condition.

Informasi jumlah data kosong
# Distribusi variabel target: Temperature (C)
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
sns.histplot(df_linear['Temperature (C)'], bins=50, color='steelblue', kde=True)
plt.title('Distribusi Suhu Udara (°C)')
plt.xlabel('Suhu (°C)')
plt.ylabel('Frekuensi')
plt.subplot(1, 2, 2)
sns.boxplot(y=df_linear['Temperature (C)'], color='lightblue')
plt.title('Boxplot Suhu Udara (°C)')
plt.ylabel('Suhu (°C)')
plt.tight_layout()
plt.show()
Lalu pada kode ini saya mencoba untuk melihat data secara menyeluruh dengan visualisasi dan juga memahami pola yang dihasilkan sekaligus mengidentifikasi pola outlier yang ada pada distribusi variable target

Distribusi variabel target
# Scatter plot: Humidity vs Temperature
plt.figure(figsize=(12, 4))
df_linear['Humidity']
plt.subplot(1, 3, 1)
plt.scatter(df_linear['Humidity'], df_linear['Temperature (C)'],
alpha=0.3, color='tomato', s=5)
plt.xlabel('Humidity')
plt.ylabel('Temperature (°C)')
plt.title('Humidity vs Suhu')
plt.subplot(1, 3, 2)
plt.scatter(df_linear['Wind Speed (km/h)'], df_linear['Temperature (C)'],
alpha=0.3, color='steelblue', s=5)
plt.xlabel('Wind Speed (km/h)')
plt.ylabel('Temperature (°C)')
plt.title('Kecepatan Angin vs Suhu')
plt.subplot(1, 3, 3)
plt.scatter(df_linear['Visibility (km)'], df_linear['Temperature (C)'],
alpha=0.3, color='green', s=5)
plt.xlabel('Visibility (km)')
plt.ylabel('Temperature (°C)')
plt.title('Visibilitas vs Suhu')
plt.tight_layout()
plt.show()
Kode ini bertujuan untuk melihat hubungan (korelasi) antara variabel independen (fitur) dengan variable dependen (target yang ingin di prediksi, yaitu Suhu/Temperature)

Temperature Korelasi
1.3 — Preprocessing Data
# Pilih fitur (X) dan target (y)
features_linear = ['Humidity', 'Wind Speed (km/h)', 'Visibility (km)',
'Pressure (millibars)', 'Wind Bearing (degrees)']
target_linear = 'Temperature (C)'
# Drop baris dengan nilai kosong pada kolom yang dipakai
df_lin = df_linear[features_linear + [target_linear]].dropna()
X = df_lin[features_linear]
y = df_lin[target_linear]
print(f"Fitur yang digunakan: {features_linear}")
print(f"Target: {target_linear}")
print(f"Jumlah data setelah bersih: {len(df_lin):,}")
Pada kode ini saya melakukan 3 langkah yang pertama menentukan X (fitur) dan y (target) setelah itu saya menghapus nilai kosong pada kolom yang ingin di gunakan, lalu selanjutnya saya memisahkan matriks X dan vektor y

Jumlah data setelah di bersihkan
# Split data: 80% training, 20% testing
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
print(f"Data Training: {X_train.shape[0]:,} baris")
print(f"Data Testing : {X_test.shape[0]:,} baris")
Untuk kode ini saya membagi menjadi 2 bagian secara terpisah untuk variabel X_train dan y_train digunakan untuk melakukan training model nantinya dan untuk X_test dan y_test dilakukan untuk pengetesan.

Jumlah data setelah di bagi menjadi 2 bagian
1.4 — Training Model Regresi Linier
# Buat dan latih model
model_linear = LinearRegression()
model_linear.fit(X_train, y_train)
print("✅ Model Regresi Linier berhasil dilatih!")
print(f"\nIntercept (b0): {model_linear.intercept_:.4f}")
print("\nKoefisien setiap fitur:")
for feat, coef in zip(features_linear, model_linear.coef_):
print(f" {feat}: {coef:.4f}")
Pada kode ini saya membuat sekaligus melatih model lalu mencetak nilai intercept dan nilai koefisien untuk setiap fitur nya.

Hasil model
1.5 — Evaluasi Model
# Prediksi
y_pred_linear = model_linear.predict(X_test)
# Hitung metrik evaluasi
mae = mean_absolute_error(y_test, y_pred_linear)
mse = mean_squared_error(y_test, y_pred_linear)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred_linear)
print("=== Hasil Evaluasi Regresi Linier ===")
print(f"MAE (Mean Absolute Error) : {mae:.4f} °C")
print(f"MSE (Mean Squared Error) : {mse:.4f}")
print(f"RMSE (Root MSE) : {rmse:.4f} °C")
print(f"R² (R-Squared) : {r2:.4f}")
print(f"\n💡 Model menjelaskan {r2*100:.2f}% variasi suhu udara.")
Pada kode ini saya menguji model menggunakan data testing — data yang memang tidak dipakai saat training. Tujuannya sederhana: melihat seberapa dekat prediksi model dengan suhu aktual, lalu menghitung metrik evaluasinya (MAE, RMSE, R²) sebagai ukuran seberapa baik model bekerja.
🌧️ BAGIAN 2 — REGRESI LOGISTIK
1.1 — Eksplorasi Data (EDA)
# Distribusi kelas target: RainTomorrow
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
counts = df_logistic['RainTomorrow'].value_counts()
plt.pie(counts, labels=counts.index, autopct='%1.1f%%',
colors=['skyblue', 'tomato'], startangle=90)
plt.title('Proporsi RainTomorrow (Hujan Besok?)')
plt.subplot(1, 2, 2)
sns.countplot(data=df_logistic, x='RainTomorrow',
palette={'No': 'skyblue', 'Yes': 'tomato'})
plt.title('Jumlah Data: Hujan vs Tidak Hujan Besok')
plt.xlabel('RainTomorrow')
plt.ylabel('Jumlah')
for p in plt.gca().patches:
plt.gca().annotate(f'{int(p.get_height()):,}',
(p.get_x() + p.get_width()/2, p.get_height()),
ha='center', va='bottom', fontweight='bold')
plt.tight_layout()
plt.show()
Saya cek distribusi target RainTomorrow pakai pie chart (proporsi) dan countplot (jumlah asli). Tujuannya satu — pastikan data tidak terlalu timpang antar kelas, karena kalau 90% "Tidak Hujan", model bisa dapat akurasi tinggi hanya dengan nebak satu kelas terus.

# Distribusi suhu berdasarkan RainTomorrow
plt.figure(figsize=(12, 4))
plt.subplot(1, 3, 1)
sns.boxplot(data=df_logistic, x='RainTomorrow', y='MaxTemp',
palette={'No': 'skyblue', 'Yes': 'tomato'})
plt.title('Suhu Maks vs Hujan Besok')
plt.subplot(1, 3, 2)
sns.boxplot(data=df_logistic, x='RainTomorrow', y='Humidity3pm',
palette={'No': 'skyblue', 'Yes': 'tomato'})
plt.title('Kelembapan 3pm vs Hujan Besok')
plt.subplot(1, 3, 3)
sns.boxplot(data=df_logistic, x='RainTomorrow', y='Rainfall',
palette={'No': 'skyblue', 'Yes': 'tomato'})
plt.title('Curah Hujan vs Hujan Besok')
plt.tight_layout()
plt.show()
Tiga boxplot ini untuk melihat apakah MaxTemp, Humidity3pm, dan Rainfall punya pola berbeda antara hari hujan dan tidak. Kalau boxplot-nya tumpang tindih penuh, fitur itu tidak banyak membantu model.

1.2 — Preprocessing Data
# Pilih fitur numerik yang relevan
features_log = ['MinTemp', 'MaxTemp', 'Rainfall', 'Humidity9am',
'Humidity3pm', 'Pressure9am', 'Pressure3pm',
'Temp9am', 'Temp3pm', 'WindGustSpeed']
target_log = 'RainTomorrow'
# Ambil subset kolom
df_log = df_logistic[features_log + [target_log]].copy()
# Drop baris dengan nilai kosong
df_log.dropna(inplace=True)
print(f"Jumlah data setelah dropna: {len(df_log):,}")
print(f"Distribusi kelas target:")
print(df_log[target_log].value_counts())
Saya pilih 10 fitur numerik, hapus baris kosong dengan dropna

# Encode target: Yes → 1, No → 0
le = LabelEncoder()
df_log[target_log] = le.fit_transform(df_log[target_log])
print("Mapping label:")
for cls, enc in zip(le.classes_, le.transform(le.classes_)):
print(f" '{cls}' → {enc}")
print(f"\nDistribusi setelah encoding:")
print(df_log[target_log].value_counts())
Setelah itu target di-encode dari teks ('Yes'/'No') ke angka (1/0) menggunakan LabelEncoder, karena model tidak bisa memproses teks mentah.

# Pisahkan X dan y
X2 = df_log[features_log]
y2 = df_log[target_log]
# Split 80% training, 20% testing
X2_train, X2_test, y2_train, y2_test = train_test_split(
X2, y2, test_size=0.2, random_state=42
)
# Normalisasi fitur (penting untuk Logistic Regression)
scaler = StandardScaler()
X2_train_scaled = scaler.fit_transform(X2_train)
X2_test_scaled = scaler.transform(X2_test)
print(f"Data Training: {X2_train.shape[0]:,} baris")
print(f"Data Testing : {X2_test.shape[0]:,} baris")
Setelah split 80:20, ada satu langkah ekstra dibanding Regresi Linier sebelumnya — normalisasi dengan StandardScaler. Ini wajib karena Regresi Logistik sensitif terhadap perbedaan skala antar fitur. fit_transform hanya di data training, data testing cukup transform — supaya tidak ada kebocoran informasi.

1.3 — Training Model Regresi Linier
# Buat dan latih model
model_logistic = LogisticRegression(max_iter=1000, random_state=42)
model_logistic.fit(X2_train_scaled, y2_train)
print("✅ Model Regresi Logistik berhasil dilatih!")
print(f"\nIntercept (b0): {model_logistic.intercept_[0]:.4f}")
print("\nKoefisien setiap fitur:")
for feat, coef in zip(features_log, model_logistic.coef_[0]):
print(f" {feat}: {coef:.4f}")
max_iter=1000 dinaikkan dari default supaya model punya cukup iterasi untuk konvergen. Koefisien hasil training dibaca sederhana: positif = menaikkan peluang hujan, negatif = sebaliknya.

1.4 — Evaluasi Model
# Prediksi
y2_pred = model_logistic.predict(X2_test_scaled)
y2_prob = model_logistic.predict_proba(X2_test_scaled)[:, 1] # probabilitas hujan
# Hitung metrik
acc = accuracy_score(y2_test, y2_pred)
prec = precision_score(y2_test, y2_pred)
rec = recall_score(y2_test, y2_pred)
f1 = f1_score(y2_test, y2_pred)
print("=== Hasil Evaluasi Regresi Logistik ===")
print(f"Accuracy : {acc:.4f} ({acc*100:.2f}%)")
print(f"Precision : {prec:.4f}")
print(f"Recall : {rec:.4f}")
print(f"F1-Score : {f1:.4f}")
print("\n=== Classification Report ===")
print(classification_report(y2_test, y2_pred, target_names=['Tidak Hujan (0)', 'Hujan (1)']))
Saya ambil dua output — prediksi kelas dan probabilitasnya. Untuk metrik, akurasi saja tidak cukup karena bisa menipu di data tidak seimbang. Makanya saya tambah Precision (seberapa tepat prediksi hujan), Recall (seberapa banyak hujan yang berhasil terdeteksi), dan F1-Score (keseimbangan keduanya). classification_report merangkum semua ini per kelas sekaligus.

🎯 Kesimpulan
Pelajaran Utama dari Dua Model Ini
📚 Referensi & Tools
- Dataset 1: Szeged Weather — kaggle.com/datasets/budincsevity/szeged-weather
- Dataset 2: Rain in Australia — kaggle.com/datasets/jsphyg/weather-dataset-rattle-package
- Library: scikit-learn, pandas, numpy, matplotlib, seaborn
- Platform: Google Colab
- Referensi Artikel: Modul 4 Logistic Regression — Hernandyvincent
- Referensi Video: Exploratory Data Analysis (EDA)
- Referensi Visualisasi: Visualisasi
메타데이터
- post_id
- 2011ebeb34c7
- slug
- memprediksi-cuaca-dengan-machine-learning-regresi-linier-regresi-logistik-2011ebeb34c7
- url
- https://medium.com/@ghifariezraramadhan/memprediksi-cuaca-dengan-machine-learning-regresi-linier-regresi-logistik-2011ebeb34c7
- canonical_url
- https://medium.com/@ghifariezraramadhan/memprediksi-cuaca-dengan-machine-learning-regresi-linier-regresi-logistik-2011ebeb34c7
- author_url
- https://medium.com/@ghifariezraramadhan
- status
- ok
- fetched_at
- 2026-06-23 03:48:11