Semua Tentang Belajar Teknologi Digital Dalam Kehidupan Sehari - Hari

  • IC Timer 555 yang Multifungsi

    IC timer 555 adalah sirkuit terpadu (chip) yang digunakan dalam berbagai pembangkit timer, pulsa dan aplikasi osilator. Komponen ini digunakan secara luas, berkat kemudahan dalam penggunaan, harga rendah dan stabilitas yang baik

  • Data Science

    Mengulik Digitalisasi data statistik dengan bantuan python untuk pemanfaatan di bidang transportasi, kesehatan, keuangan dan masih banyak lagi

  • Artificial Intelligence - Pengenalan Object

    Menghadirkan pemanfaatan AI dengan praktek-praktek yang mudah diikuti - cocok untuk mahasiswa yang mencari ide tugas akhir

  • JAM DIGITAL 6 DIGIT TANPA MICRO FULL CMOS

    Jika anda pencinta IC TTL datau CMOS maka project jam digital ini akan menunjukkan bahwa tidak ada salahnya balik kembali ke dasar elektronika digital , sebab semuanya BISA dibuat dengan teknologi jadul

  • Node Red - Kontrol Industri 4.0

    Teknologi kontrol sudah melampaui ekspektasi semua orang dan dengan kemajuan dunia elektronika, kini semakin leluasa berkreasi melalui Node Red

Jumat, 21 Maret 2025

Mengulik Statistik Transportasi KAI - Regresi Linear Vs ARIMA

 



Pembahasan kali ini akan mengambil data yang telah disediakan oleh Biro Pusat Statistik yang memang diperintahkan oleh negara untuk menyediakan data-data statistik semua kegiatan penduduk Indonesia, salah satunya yang saya ambil adalah data perjalanan kereta api yang tersedia sejak 2006. Jadi jika pembaca ingin belajar lewat contoh-contoh seperti yang saya gunakan, bisa mendaftar API key secara gratis di websitenya BPS. Memang sih tiap data bisa diambil dalam excel atau csv, namun ketersediaanya dalam bentuk tahunan, sehingga gak terlalu keren untuk unjuk gigi kemampuan koding saya (padahal saya juga banyak dibantu QWENAI).

Contoh untuk memanggi API dan mendapatkan JSON nya bisa menggunakan script python seperti ini :


koding:

#Jangan lupa daftar akses API key di BPS
import requests
r = requests.get('https://webapi.bps.go.id/v1/api/list/model/data/lang/ind/domain/0000/var/72/key/Ubah key punya akun anda')

with open('data_KAI.json','w') as fd:
    fd.write(r.text)


Namun ...bukan Indonesia namanya kalau menyediakan data gratisan apapun dengan prinsip "Kalau bisa dipersulit ngapain dipermudah ?" Jadi JSON nya sepertinya hanya dipahami yang bikin database dari BPS, dimana tiap key json saling terhubung dengan kode-kode yang saling terkait. Jadi jika menggunakan layanan Json to Table di internet, maka akan zonk hasilnya. Jadi saya bertanya aja ke QWEN AI dan mendapatkan pencerahan mengenai Json dari API BPS, dan berhasil membuat CSV yang lebih gampang di extract time-series nya.


File JSON ini berisi kumpulan data komprehensif terkait transportasi, khususnya yang berfokus pada jumlah penumpang kereta api di Indonesia. Data tersebut terstruktur dan saling terhubung melalui berbagai kunci dan nilai. Berikut ini adalah analisis struktur dan koneksi dalam JSON:

Struktur Umum

Metadata:
  • status: Menunjukkan status data (misalnya, "OK").
  • data-availability: Menunjukkan apakah data tersedia.
  • last_update: Stempel waktu pembaruan terakhir.
Subjek:
  • subject: Berisi informasi tentang subjek data, dalam hal ini, "Transportasi".
Variabel:
  • var: Menjelaskan variabel yang sedang diukur. Di sini, "Jumlah Penumpang Kereta Api" dengan satuan "Ribu Orang". Ini juga mencakup catatan dan sumber.
Variabel Versi:
  • turvar: Atribut tambahan untuk pembuatan versi (dalam hal ini, menunjukkan 'Tidak'). 
  • labelvervar: Label untuk jenis transportasi ("Kereta Api").
  • vervar: Mencantumkan berbagai jenis layanan kereta api seperti Jabodetabek, Non Jabodetabek, Sumatera, dll.
Tahun:
  • tahun: Mencantumkan tahun dari 2006 hingga 2025.
Periode Waktu:
  • turtahun: Mencantumkan bulan dan entri tahunan.
Konten Data:
  • datacontent: Berisi titik data aktual. Setiap kunci mewakili kombinasi variabel dan periode waktu tertentu, dan nilainya mewakili jumlah penumpang.
Data Terkait:
  • related: Bagian ini kosong di berkas Anda, tetapi dapat digunakan untuk menautkan ke kumpulan data terkait lainnya.

Koneksi dan Hubungan Kunci:

Keterkaitan Subjek dan Variabel:
  • Array subjek terhubung ke array var melalui kolom subj. Misalnya, "Transportasi" terhubung ke "Jumlah Penumpang Kereta Api".
Variabel dan Variabel Versi:
  • Array var dirinci lebih lanjut oleh array vervar yang mengkategorikan data ke dalam berbagai jenis layanan kereta api.
Data Temporal:
  • Array tahun dan turtahun menyediakan konteks temporal. Setiap titik data dalam datacontent sesuai dengan tahun dan bulan tertentu (atau tahunan).
Titik Data:

Kunci dalam datacontent mengikuti pola yang mengodekan jenis layanan, tahun, dan bulan. Misalnya, 17201061 dapat dipecah menjadi:
  • 1: Mengacu pada "Jabodetabek" dari vervar.
  • 72: Mengacu pada "Jumlah Penumpang Kereta Api".
  • 01: Mengacu pada tahun 2006 dari tahun.
  • 06: Mengacu pada Juni dari turtahun.
Contoh Analisis:
Mari kita ambil contoh kunci dari datacontent untuk mengilustrasikan bagaimana data saling terhubung:

Kunci: 17201061
Rincian:
  • 1: "Jabodetabek" (vervar)
  • 72: "Jumlah Penumpang Kereta Api" (var)
  • 01: Tahun 2006 (tahun)
  • 06: Bulan Juni (turtahun)
  • Nilai: 8681 (yang berarti 8.681.000 penumpang)
Ringkasan:

File JSON sangat terstruktur dan saling terhubung, memungkinkan analisis terperinci jumlah penumpang kereta api di berbagai layanan, tahun, dan bulan. Kunci dalam objek datacontent mengodekan dimensi ini, sehingga memungkinkan untuk mengekstrak wawasan yang berarti tentang tren dan pola dalam transportasi kereta api dari waktu ke waktu.

Nah...mumet bukan ? Mari kita lanjutkan ke script python yang sudah saya sesuaikan agar bisa merubah json BPS menjadi CSV data series:

# Import required libraries
import pandas as pd
import json

with open('data_KAI.json', 'r') as file:
    data = json.load(file)


# Extract relevant mappings
vervar_map = {str(v['val']): v['label'] for v in data['vervar']}  # Train services
tahun_map = {str(t['val']): t['label'] for t in data['tahun']}  # Years
turtahun_map = {str(t['val']): t['label'] for t in data['turtahun']}  # Months + Annual

# Prepare a dictionary to store the decoded data
time_series_data = {}

# Decode the datacontent keys
for key, value in data['datacontent'].items():
    # Split the key into components
    service_code = key[0]  # First digit: service type
    year_code = key[4:7]   # Next three digits: year
    month_code = key[7:]   # Remaining digits: month or annual
    #print(year_code)
    # Map codes to labels
    service_label = vervar_map.get(service_code, "Unknown Service")
    year_label = tahun_map.get(year_code, "Unknown Year")  # Use full year_code for lookup
    month_label = turtahun_map.get(month_code, "Unknown Month")

    # Create a unique identifier for the column (YYYY-MM format)
    if month_label != "Tahunan":  # Exclude annual data
        date_key = f"{year_label}-{int(month_code):02d}"  # Format: YYYY-MM
    else:
        date_key = f"{year_label}-Annual"  # For annual totals

    # Add to the time_series_data dictionary
    if service_label not in time_series_data:
        time_series_data[service_label] = {}
    time_series_data[service_label][date_key] = value

# Convert to a DataFrame
all_dates = sorted({date for dates in time_series_data.values() for date in dates})
df = pd.DataFrame(index=time_series_data.keys(), columns=all_dates)

# Populate the DataFrame
for service, values in time_series_data.items():
    for date, count in values.items():
        df.at[service, date] = count

# Reset index to make the services a column
df.reset_index(inplace=True)
df.rename(columns={"index": "Service"}, inplace=True)

# Save the DataFrame to a CSV file
csv_file = "railway_passenger_time_series.csv"
df.to_csv(csv_file, index=False)

print(f"CSV file '{csv_file}' has been created successfully!")

Hasilnya berupa file bernama "railway_passenger_time_series.csv" dan untuk menampilkan data nya dalam visualisasi grafik, kita manfaatkan matplotlib. Seperti contoh dibawah ini mengambarkan data history perjalanan kereta api di daerah jabodetabek periode 2006-2025 (grafik ada di gambar paling atas):

# Import required libraries
import pandas as pd
import matplotlib.pyplot as plt

# Load the previously created CSV file
csv_file = "railway_passenger_time_series.csv"
df = pd.read_csv(csv_file)

# Filter data for "Jabodetabek" service
jabodetabek_data = df[df['Service'] == 'Jabodetabek'].drop(columns=['Service']).T
jabodetabek_data.columns = ['PassengerCount']

# Remove rows corresponding to "Year-Annual" (filter out annual totals)
jabodetabek_data = jabodetabek_data[~jabodetabek_data.index.str.contains('Annual')]

jabodetabek_data.index = pd.to_datetime(jabodetabek_data.index, format='%Y-%m')  # Convert index to datetime
jabodetabek_data = jabodetabek_data.sort_index()  # Ensure chronological order

# Plot the time series data
plt.figure(figsize=(14, 7))
plt.plot(jabodetabek_data.index, jabodetabek_data['PassengerCount'], label='Jabodetabek Passenger Count', color='blue')

# Add title and labels
plt.title('Monthly Passenger Count for Jabodetabek (2006-2025)', fontsize=16)
plt.xlabel('Year', fontsize=12)
plt.ylabel('Passenger Count (in thousands)', fontsize=12)

# Rotate x-axis labels for better readability
plt.xticks(rotation=45)

# Add grid and legend
plt.grid(True, linestyle='--', alpha=0.6)
plt.legend()

# Show the plot
plt.tight_layout()
plt.show()

Ayo jangan lama-lama saya tampilkan regesi linearnya :


# Import required libraries
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt

# Load the previously created CSV file
csv_file = "railway_passenger_time_series.csv"
df = pd.read_csv(csv_file)

# Filter data for "Jabodetabek" service
jabodetabek_data = df[df['Service'] == 'Jabodetabek'].drop(columns=['Service']).T
jabodetabek_data.columns = ['PassengerCount']

# Remove rows corresponding to "Year-Annual" (filter out annual totals)
jabodetabek_data = jabodetabek_data[~jabodetabek_data.index.str.contains('Annual')]

# Convert index to datetime format
jabodetabek_data.index = pd.to_datetime(jabodetabek_data.index, format='%Y-%m')
jabodetabek_data = jabodetabek_data.sort_index()  # Ensure chronological order

# Filter data for the years 2020 to 2024
start_date = '2006-01'
end_date = '2024-12'
filtered_data = jabodetabek_data.loc[start_date:end_date]

# Prepare the data for training
def prepare_data(series):
    """
    Prepare data for supervised learning.
    :param series: Time series data (passenger counts).
    :return: X (features) and y (target).
    """
    X, y = [], []
    for i in range(len(series) - 1):  # Use one-step-ahead prediction
        X.append([i])  # Use time step as the feature
        y.append(series[i + 1])  # Predict the next month
    return np.array(X), np.array(y)

# Extract the passenger count series
series = filtered_data['PassengerCount'].values

# Prepare training datasets
X_train, y_train = prepare_data(series)

# Train the Linear Regression model
model = LinearRegression()
model.fit(X_train, y_train)

# Predict future values for the next 60 months (2029)
future_months = 60
last_time_step = len(series) - 1
future_predictions = []
for i in range(future_months):
    next_month_prediction = model.predict([[last_time_step + i]])[0]
    future_predictions.append(next_month_prediction)

# Create a DataFrame for the predictions
future_dates = pd.date_range(start=filtered_data.index[-1] + pd.offsets.MonthBegin(),
                             periods=future_months, freq='MS')
predictions_df = pd.DataFrame({
    'Date': future_dates,
    'Predicted_PassengerCount': future_predictions
})

# Combine historical data and predictions
combined_data = pd.concat([
    filtered_data.reset_index().rename(columns={'index': 'Date'}),
    predictions_df
])

# Plot the results
plt.figure(figsize=(14, 7))

# Historical data
plt.plot(combined_data['Date'][:-future_months], combined_data['PassengerCount'][:-future_months],
         label='Historical Data (2006-2024)', color='blue')

# Predictions
plt.plot(combined_data['Date'][-future_months:], combined_data['Predicted_PassengerCount'][-future_months:],
         label='Predicted Data (2025)', color='orange', linestyle='--')

# Add title and labels
plt.title('Monthly Passenger Count for Jabodetabek (2006-2029)', fontsize=16)
plt.xlabel('Year', fontsize=12)
plt.ylabel('Passenger Count (in thousands)', fontsize=12)

# Rotate x-axis labels for better readability
plt.xticks(rotation=45)

# Add grid and legend
plt.grid(True, linestyle='--', alpha=0.6)
plt.legend()

# Show the plot
plt.tight_layout()
plt.show()

Hasilnya seperti ini grafiknya :



Bagaimana dengan ARIMA ?


# Create a DataFrame for the predictions
future_dates = pd.date_range(start=filtered_data.index[-1] + pd.offsets.MonthBegin(),
                             periods=future_months, freq='MS')
predictions_df = pd.DataFrame({
    'Date': future_dates,
    'Predicted_PassengerCount': predictions
})

# Combine historical data and predictions
combined_data = pd.concat([
    filtered_data.reset_index().rename(columns={'index': 'Date'}),
    predictions_df
])

# Plot the results
plt.figure(figsize=(14, 7))

# Historical data
plt.plot(combined_data['Date'][:-future_months], combined_data['PassengerCount'][:-future_months],
         label=f'Historical Data ({start_date[0:4]}-{end_date[0:4]})', color='blue')

# Predictions
plt.plot(combined_data['Date'][-future_months:], combined_data['Predicted_PassengerCount'][-future_months:],
         label='Predicted Data (2025)', color='orange', linestyle='--')

# Add title and labels
plt.title(f'Monthly Passenger Count for Jabodetabek ({start_date[0:4]}-{end_date[0:4]})', fontsize=16)
plt.xlabel('Year', fontsize=12)
plt.ylabel('Passenger Count (in thousands)', fontsize=12)

# Rotate x-axis labels for better readability
plt.xticks(rotation=45)

# Add grid and legend
plt.grid(True, linestyle='--', alpha=0.6)
plt.legend()

# Show the plot
plt.tight_layout()
plt.show()

Grafiknya lebih bergejolak dibandingkan regresi linear :



Pada grafik diatas bisa pembaca utak-atik range tahun yang digunakan karena ada pola yang kurang "statisioner" ketika jaman pandemi 2020-2021.

Jika prediksi dari model Anda (misalnya, ARIMA, LSTM, atau model peramalan lainnya) menghasilkan garis 'cenderung' datar, biasanya hal ini menunjukkan bahwa model tersebut gagal menangkap pola, tren, atau kemusiman yang mendasarinya dalam data. Prediksi garis datar menunjukkan bahwa model tersebut memprediksi nilai konstan dari waktu ke waktu, yang sering kali merupakan tanda adanya satu atau beberapa masalah dalam proses pemodelan. Berikut adalah alasan paling umum untuk perilaku ini dan cara mengatasinya:

1. Kurangnya Tren atau Kemusiman dalam Data

Mengapa hal ini terjadi: Jika data historis tidak menunjukkan tren atau kemusiman yang kuat, model tersebut mungkin secara default memprediksi nilai konstan (misalnya, rata-rata data).

Cara memperbaikinya:
  • Visualisasikan data untuk memeriksa tren, kemusiman, atau pola siklus.
  • Gunakan teknik dekomposisi (misalnya, seasonal_decompose dalam Python) untuk menganalisis komponen deret waktu. Jika tren atau kemusiman ada tetapi lemah, pertimbangkan untuk memodelkannya secara eksplisit menggunakan alat seperti:
  • Menambahkan komponen musiman dalam ARIMA (SARIMA).
  • Menggunakan fitur eksternal (misalnya, hari dalam seminggu, hari libur) dalam model pembelajaran mesin.

2. Konfigurasi Model yang Buruk

Mengapa hal ini terjadi: Parameter model mungkin tidak disetel dengan benar, yang menyebabkan underfitting. Misalnya:
  • Dalam ARIMA, parameter (p, d, q) mungkin tidak optimal.
  • Dalam LSTM, arsitektur (misalnya, jumlah lapisan, neuron) atau hiperparameter (misalnya, laju pembelajaran, ukuran batch) mungkin tidak sesuai dengan data.
Cara memperbaikinya:
  • Untuk ARIMA, gunakan alat seperti auto_arima untuk menemukan parameter terbaik secara otomatis.
  • Untuk LSTM, bereksperimenlah dengan arsitektur, laju pembelajaran, dan durasi pelatihan yang berbeda.
  • Validasi model secara teratur menggunakan metrik seperti RMSE atau MAE pada set validasi.


3. Data Tidak Cukup

Mengapa hal ini terjadi: Jika kumpulan data terlalu kecil atau tidak memiliki variabilitas, model mungkin kesulitan mempelajari pola yang bermakna.

Cara memperbaikinya:
  • Pastikan Anda memiliki cukup data historis untuk melatih model secara efektif.
  • Jika datanya jarang, pertimbangkan untuk menggabungkannya (misalnya, harian → mingguan) untuk mengurangi gangguan dan menyorot pola.

4. Pemulusan Berlebihan Selama Prapemrosesan

Mengapa hal ini terjadi: Langkah-langkah prapemrosesan seperti pemulusan berlebihan, pembedaan, atau normalisasi dapat menghilangkan pola penting dari data.

Cara memperbaikinya:
  • Hindari pembedaan berlebihan pada data dalam ARIMA (gunakan d minimum yang diperlukan untuk mencapai stasioneritas).
  • Berhati-hatilah dengan normalisasi. Misalnya, jika rentang nilai terlalu padat, model mungkin memprediksi mendekati rata-rata.
  • Pertahankan skala asli data saat mengevaluasi prediksi. 


5. Model Memprediksi Rata-rata

Mengapa hal ini terjadi: Banyak model, terutama yang lebih sederhana seperti ARIMA, cenderung memprediksi rata-rata data ketika tidak dapat mengidentifikasi pola yang jelas.

Cara memperbaikinya:
  • Tambahkan regresor eksternal (misalnya, cuaca, hari libur) untuk memberikan konteks tambahan.
  • Gunakan model yang lebih kompleks seperti LSTM atau peningkatan gradien yang dapat mempelajari hubungan non-linier.
  • Periksa residual model untuk memastikannya acak. Jika residual menunjukkan pola, model tersebut kurang sesuai.

6. Fitur Input yang Salah

Mengapa hal ini terjadi: Jika fitur input tidak cukup mewakili dependensi temporal, model mungkin gagal untuk belajar.
Cara memperbaikinya:
  • Sertakan fitur yang tertinggal (misalnya, pengamatan sebelumnya) untuk model pembelajaran mesin.
  • Gunakan pengetahuan domain untuk merekayasa fitur yang bermakna (misalnya, rata-rata bergulir, indikator hari dalam seminggu). 


7. Evaluasi pada Pola yang Tak Terlihat

Mengapa hal ini terjadi: Jika data pengujian berisi pola yang tidak terlihat dalam data pelatihan, model mungkin akan menggunakan prediksi datar secara default.

Cara memperbaikinya:
  • Pastikan set data pelatihan dan pengujian berasal dari distribusi yang sama.
  • Gunakan teknik validasi silang seperti pemisahan deret waktu untuk mengevaluasi kinerja model pada data yang tak terlihat.


8. Regresor Eksternal yang Konstan

Mengapa hal ini terjadi: Jika fitur eksternal (misalnya, cuaca, peristiwa) konstan atau tidak memiliki variabilitas, model mungkin tidak mempelajari hubungan yang bermakna.

Cara memperbaikinya:
  • Pastikan fitur eksternal memiliki variabilitas dan relevansi yang cukup terhadap variabel target.
  • Hapus fitur yang tidak relevan atau konstan dari set data.


9. Pelatihan pada Cakrawala yang Terlalu Pendek

Mengapa hal ini terjadi: Jika model dilatih pada urutan yang sangat pendek atau cakrawala prakiraan yang terbatas, model mungkin gagal untuk digeneralisasi ke cakrawala yang lebih panjang.

Cara memperbaikinya:
  • Latih model pada urutan yang lebih panjang atau perluas cakrawala prakiraan selama pelatihan.
  • Gunakan teknik peramalan multi-langkah (misalnya, peramalan rekursif atau langsung) untuk prediksi jangka panjang.

10. Kebocoran Data

Mengapa hal ini terjadi: Jika informasi masa depan bocor ke dalam data pelatihan, model mungkin gagal untuk digeneralisasi dan menghasilkan prediksi yang tidak realistis.

Cara memperbaikinya:
  • Pastikan set pelatihan dan pengujian dipisahkan secara ketat dalam waktu.
  • Hindari penggunaan data masa depan (misalnya, nilai target) sebagai fitur selama pelatihan.


- Powered by Qwen AI -
Share:

Mengulik Statistik Transportasi - Prediksi Deret Waktu Dengan ARIMA

 


Untuk mengikuti tulisan kali ini diharapkan membaca dulu bagian scraping data agar contoh dataset yang digunakan  dapat diambil dengan benar ...( baca disini )


ARIMA (AutoRegressive Integrated Moving Average) adalah model statistik yang banyak digunakan untuk peramalan deret waktu. Model ini sangat efektif untuk data deret waktu univariat, yang tujuannya adalah untuk memprediksi nilai masa depan berdasarkan pengamatan masa lalu. Dalam konteks prediksi lalu lintas, ARIMA dapat digunakan untuk meramalkan parameter lalu lintas seperti jumlah kendaraan, kecepatan, atau tingkat kemacetan di persimpangan atau di sepanjang ruas jalan.

Di bawah ini, saya akan menjelaskan ARIMA secara terperinci, membahas komponen-komponennya, dan menunjukkan bagaimana ARIMA dapat diterapkan pada prediksi lalu lintas.


Apa itu ARIMA?

ARIMA merupakan kombinasi dari tiga komponen utama:

AutoRegressive (AR):

Menangkap hubungan antara pengamatan dan sejumlah pengamatan yang tertinggal (nilai masa lalu).

Parameter "p" menentukan jumlah istilah yang tertinggal yang akan disertakan.

Integrated(I):

Mengacu pada pembedaan data untuk membuatnya stasioner (misalnya, menghilangkan tren dan musim).

Parameter "d" menentukan berapa kali data dibedakan.

Moving Average (MA):

Menggunakan ketergantungan antara pengamatan dan kesalahan residual dari model rata-rata bergerak yang diterapkan pada pengamatan yang tertunda.

Parameter "q" menentukan ukuran jendela rata-rata bergerak.


Model ARIMA dilambangkan sebagai ARIMA(p, d, q) , di mana:


p : Jumlah suku autoregresif.

d : Derajat perbedaan.

q : Jumlah suku rata-rata bergerak.


Mengapa Menggunakan ARIMA untuk Prediksi Lalu Lintas?

ARIMA sangat cocok untuk prediksi lalu lintas karena:

  • Peramalan Univariat: Bekerja langsung dengan data lalu lintas historis (misalnya, jumlah kendaraan dari waktu ke waktu) tanpa memerlukan fitur tambahan.
  • Penanganan Tren dan Musiman: Pola lalu lintas sering kali menunjukkan siklus harian, mingguan, atau musiman. ARIMA dapat menangkap tren berulang ini.
  • Interpretabilitas: Tidak seperti model pembelajaran mendalam, ARIMA memberikan hasil yang dapat diinterpretasikan, sehingga lebih mudah untuk memahami pola yang mendasarinya.
  • Kesederhanaan: ARIMA relatif mudah diimplementasikan dan memerlukan sumber daya komputasi minimal dibandingkan dengan model pembelajaran mesin. 


Namun, ARIMA memiliki keterbatasan:

  • Bermasalah dengan input multivariat (misalnya, menggabungkan data cuaca atau kejadian dengan data lalu lintas).
  • Mungkin tidak berfungsi dengan baik untuk pola lalu lintas yang sangat kompleks atau non-linier.


Langkah-langkah untuk Menerapkan ARIMA untuk Prediksi Lalu Lintas


Langkah 1: Pengumpulan Data

Kumpulkan data lalu lintas historis (misalnya, jumlah kendaraan, kecepatan, atau tingkat kemacetan) secara berkala (misalnya, setiap 5, 15, atau 60 menit).

Pastikan data bersih (tidak ada nilai yang hilang atau outlier).

Langkah 2: Visualisasikan Data

Buat plot data deret waktu untuk mengidentifikasi tren, musim, dan gangguan.

Contoh koding:

import matplotlib.pyplot as plt
plt.plot(traffic_data)
plt.title("Traffic Counts Over Time")
plt.show()


Langkah 3: Periksa apakah data Stasioner

ARIMA mengasumsikan bahwa deret waktu bersifat stasioner (nilai rata-rata, varians, dan autokorelasi konstan dari waktu ke waktu).

Gunakan uji statistik seperti uji Augmented Dickey-Fuller (ADF) untuk memeriksa stasioneritas:


Contoh koding:

from statsmodels.tsa.stattools import adfuller
result = adfuller(traffic_data)
print(f"ADF Statistic: {result[0]}, p-value: {result[1]}")

Jika data tidak stasioner, terapkan differencing (d > 0) untuk membuatnya stasioner.


Langkah 4: Tentukan Parameter ARIMA (p, d, q)

Gunakan alat seperti plot Autocorrelation Function (ACF) dan Partial Autocorrelation Function (PACF) untuk memperkirakan p dan q:


Contoh koding:

from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
plot_acf(traffic_data)
plot_pacf(traffic_data)
plt.show()

Plot ACF membantu menentukan q (lag yang melampaui batas korelasi), dan plot PACF membantu menentukan p.


Langkah 5: Melatih Model ARIMA

Sesuaikan model ARIMA menggunakan parameter yang diidentifikasi:

Contoh koding:

from statsmodels.tsa.arima.model import ARIMA
model = ARIMA(traffic_data, order=(p, d, q))
model_fit = model.fit()
print(model_fit.summary())


Langkah 6: Buat Prediksi

Gunakan model yang telah dilatih untuk memperkirakan nilai lalu lintas di masa mendatang:

Contoh koding:

forecast = model_fit.forecast(steps=10)  # Predict next 10 time steps
print(forecast)


Langkah 7: Mengevaluasi Model

Bandingkan nilai prediksi dengan data aktual menggunakan metrik seperti:

Mean Absolute Error (MAE):

from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error(actual_values, predicted_values)
print(f"MAE: {mae}")

Root Mean Square Error (RSME):

from sklearn.metrics import mean_squared_error
rmse = mean_squared_error(actual_values, predicted_values, squared=False)
print(f"RMSE: {rmse}")

Contoh yang saya gunakan adalah data lalu lintas harian di kota bandung yang saya dapatkan di : https://satudata.bandungkab.go.id/dataset/data-lalu-lintas-masuk , dan kemudian saya jalankan dengan google colab. Unduh datanya dalam bentuk CSV dan kemudian satu persatu kita olah.


1. Pengolahan data awal

#Load and Preprocess the Data
import pandas as pd

# Load the dataset, skipping the first two rows (headers)
data = pd.read_csv('data_bandung.csv', header=None, skiprows=2, names=['Wilayah', 'Year', 'Month', 'Day', 'Golongan', 'Jumlah'])

# Display the first few rows to verify
print(data.head())

# Filter the data for 'Golongan' equal to "I"
filtered_data = data[data['Golongan'] == "II"]

# Create a datetime column for time-series analysis
#filtered_data['Date'] = pd.to_datetime(filtered_data[['Year', 'Month', 'Day']])
filtered_data = filtered_data.assign(Date=pd.to_datetime(filtered_data[['Year', 'Month', 'Day']]))

# Sort the data by date
data = filtered_data.sort_values(by='Date').reset_index(drop=True)

# Display the cleaned data
print(data.head())


Hasilnya seperti ini :
Wilayah Year Month Day Golongan Jumlah 0 Kabupaten Bandung 2020 1 2 I 35576 1 Kabupaten Bandung 2020 1 3 I 36028 2 Kabupaten Bandung 2020 1 4 I 37828 3 Kabupaten Bandung 2020 1 5 I 33637 4 Kabupaten Bandung 2020 1 6 I 33657 Wilayah Year Month Day Golongan Jumlah Date 0 Kabupaten Bandung 2020 1 1 II 340 2020-01-01 1 Kabupaten Bandung 2020 1 2 II 1149 2020-01-02 2 Kabupaten Bandung 2020 1 3 II 1649 2020-01-03 3 Kabupaten Bandung 2020 1 4 II 1483 2020-01-04 4 Kabupaten Bandung 2020 1 5 II 893 2020-01-05

2. Visualisasi Data

# Visualize the Data
import matplotlib.pyplot as plt

# Plot the time series
plt.figure(figsize=(12, 6))
plt.plot(data['Date'], data['Jumlah'], label='Traffic Data')
plt.title('Traffic Data Over Time')
plt.xlabel('Date')
plt.ylabel('Jumlah')
plt.legend()
plt.show()

Hasil visualisasinya seperti ini :





2. Cek apakah data statisioner : 

#Check for Stationarity
from statsmodels.tsa.stattools import adfuller

# Perform ADF test
result = adfuller(data['Jumlah'])
print(f"ADF Statistic: {result[0]}")
print(f"p-value: {result[1]}")

# Interpretation
if result[1] <= 0.05:
    print("The data is stationary.")
else:
    print("The data is non-stationary. Differencing may be required.")

Hasilnya ini :

ADF Statistic: -4.2035830664815785 p-value: 0.0006497583886865874 The data is stationary.


4. Jika tidak statisioner lakukan ini :

#if non stationary
data['Value_Diff'] = data['Jumlah'].diff().dropna()

# Plot the differenced data
plt.figure(figsize=(12, 6))
plt.plot(data['Date'][1:], data['Value_Diff'], label='Differenced Data')
plt.title('Differenced Traffic Data')
plt.xlabel('Date')
plt.ylabel('Differenced Value')
plt.legend()
plt.show()


5. Buat pemodelan ARIMA dengan library python pmdarima


Jangan lupa jika menggunakan google colab install dulu librarynya: 

#Build the ARIMA Model
!pip install pmdarima

Lanjut ini : 

from pmdarima import auto_arima

# Fit the auto_arima model to find optimal parameters
model = auto_arima(data['Jumlah'], seasonal=True, m=12, trace=True, error_action='ignore', suppress_warnings=True)
print(model.summary())

Lalu Training model arima nya:
#train the arima model
from statsmodels.tsa.arima.model import ARIMA

# Extract optimal parameters from auto_arima
order = model.order

# Train the ARIMA model
arima_model = ARIMA(data['Jumlah'], order=order)
arima_fit = arima_model.fit()

# Print model summary
print(arima_fit.summary())

Hasilnya training seperti ini :


ARIMAX Results ============================================================================== Dep. Variable: Jumlah No. Observations: 1813 Model: ARIMA(0, 1, 2) Log Likelihood -14093.174 Date: Sun, 16 Mar 2025 AIC 28192.348 Time: 03:48:09 BIC 28208.854 Sample: 0 HQIC 28198.439 - 1813 Covariance Type: opg ============================================================================== coef std err z P>|z| [0.025 0.975] ------------------------------------------------------------------------------ ma.L1 -0.7766 0.020 -39.006 0.000 -0.816 -0.738 ma.L2 -0.1608 0.020 -7.989 0.000 -0.200 -0.121 sigma2 3.331e+05 1.03e+04 32.290 0.000 3.13e+05 3.53e+05 =================================================================================== Ljung-Box (L1) (Q): 0.00 Jarque-Bera (JB): 332.12 Prob(Q): 0.98 Prob(JB): 0.00 Heteroskedasticity (H): 1.69 Skew: -1.02 Prob(H) (two-sided): 0.00 Kurtosis: 3.45 =================================================================================== Warnings: [1] Covariance matrix calculated using the outer product of gradients (complex-step).


6. Lanjut ke prediksi 1 tahun / 365 hari kedepan menggunakan arima :
# Forecast for the next 365 days (or desired horizon)
forecast_steps = 365
forecast = arima_fit.forecast(steps=forecast_steps)

# Create a date range for the forecast period
forecast_dates = pd.date_range(start='2025-01-01', periods=forecast_steps, freq='D')

# Combine forecast dates and values into a DataFrame
forecast_data = pd.DataFrame({'Date': forecast_dates, 'Forecasted_Value': forecast})

# Display the forecasted data
print(forecast_data.head())

# Plot the forecast
plt.figure(figsize=(12, 6))
plt.plot(data['Date'], data['Jumlah'], label='Historical Data')
plt.plot(forecast_data['Date'], forecast_data['Forecasted_Value'], label='Forecasted Data', color='red')
plt.title('Traffic Data Forecast for 2025')
plt.xlabel('Date')
plt.ylabel('Value')
plt.legend()
plt.show()


Hasilnya seperti ini dan grafiknya seperti gambar paling atas tulisan ini : 
Date Forecasted_Value 1813 2025-01-01 1791.804722 1814 2025-01-02 1798.622821 1815 2025-01-03 1798.622821 1816 2025-01-04 1798.622821 1817 2025-01-05 1798.622821


Keunggulan ARIMA

  • Dapat ditafsirkan: Mudah dipahami dan dijelaskan kepada pemangku kepentingan.
  • Efisien: Memerlukan daya komputasi yang lebih sedikit dibandingkan dengan model pembelajaran mendalam.
  • Menangani Tren dan Musiman: Efektif untuk menangkap pola berulang dalam data lalu lintas.


Keterbatasan ARIMA

  • Fokus Univariat: Tidak dapat menggabungkan faktor eksternal seperti cuaca, peristiwa, atau kondisi jalan.
  • Persyaratan Stasioneritas: Data non-stasioner harus ditransformasikan, yang mungkin akan mempersulit proses.
  • Asumsi Linier: Kesulitan dengan pola lalu lintas yang sangat non-linier atau kacau.


Kapan Menggunakan ARIMA vs. Model Lain

Gunakan ARIMA Saat:
  • Anda memiliki data lalu lintas univariat (misalnya, jumlah kendaraan dari waktu ke waktu).
  • Data menunjukkan tren dan musim yang jelas.
  • Anda memerlukan model yang sederhana dan dapat ditafsirkan.

Pertimbangkan Alternatif Saat:

  • Anda ingin menggabungkan input multivariat (gunakan model LSTM atau pembelajaran mesin). Data tersebut sangat non-linier atau kompleks (gunakan model pembelajaran mendalam seperti LSTM atau GRU).
  • Diperlukan prediksi waktu nyata (gunakan model hibrida atau pembelajaran penguatan).

Kesimpulan 

ARIMA adalah alat yang ampuh dan dapat ditafsirkan untuk prediksi lalu lintas, terutama saat menangani data deret waktu univariat. Dengan memahami komponennya dan mengikuti pendekatan terstruktur, Anda dapat menggunakan ARIMA secara efektif untuk memperkirakan pola lalu lintas. Namun, untuk skenario yang lebih kompleks yang melibatkan beberapa variabel atau prediksi waktu nyata, pertimbangkan untuk menggabungkan ARIMA dengan model lain atau beralih ke teknik lanjutan seperti LSTM ( dibahas pada tulisan selanjutnya ).


- Powered by Qwen AI -
Share:

Mengulik Prediksi Statistik : Kesalahan Regresi Linear di Rekor Lari 100m

Seperti kita sudah pahami Regresi Linear adalah metode statistik yang digunakan untuk memodelkan hubungan antara variabel dependen (misalnya, waktu rekor dunia) dan satu atau lebih variabel independen (misalnya, tahun). Tujuannya adalah untuk menemukan "garis yang paling sesuai" yang meminimalkan kesalahan antara nilai yang diprediksi dan nilai aktual.

Anda dapat menggunakan persamaan garis lurus y=mx+b, di mana:

  • y: Variabel dependen (waktu rekor dunia)
  • x: Variabel independen (tahun)
  • m: Kemiringan (laju perubahan waktu rekor dunia per tahun)
  • b: Intersep (waktu rekor dunia yang diprediksi pada tahun 0)
Perhatikan contoh berikut berupa data rekor dunia lari 100 meter pria:

YEAR
TIME (SECONDS)
1912
10.6
1921
10.4
1930
10.3
1936
10.2
1956
10.1
1960
10.0
1968
9.95
1983
9.93
1988
9.92
1991
9.86
1994
9.85
1996
9.84
1999
9.79
2005
9.77
2008
9.72
2009
9.58

 

Dari  kumpulan data di atas, kita bisa menurunkan model regresi linear sebagai berikut:

Buatlah titik-titik data pada grafik dengan tahun pada sumbu x dan waktu rekor dunia pada sumbu y. Pasang model regresi linier pada data tersebut. Ini melibatkan penghitungan kemiringan (m) dan intersep (b). Untuk mempermudah, Anda dapat menggunakan perangkat lunak seperti Excel, Python (dengan scikit-learn), atau bahkan kalkulasi pena dan kertas untuk menemukan garis yang paling sesuai.

Misalnya, dengan menggunakan alat seperti Excel atau Python, Anda mungkin menemukan:


y=−0,01x+29,5


di mana y adalah waktu rekor dunia yang diprediksi, dan x adalah tahun.


Sekarang, kita lanjutkan menggunakan model regresi linier untuk memprediksi:

Berapakah rekor dunia lari 100m pria  pada tahun 2050?
Kapan rekor dunia akan mencapai 0 detik (yang jelas tidak mungkin).


Contoh Prediksi:

Untuk tahun 2050:
y=−0,01(2050)+29,5=9,0 detik.
Untuk saat rekor mencapai 0 detik:
Pecahkan 0=−0,01x+29,5:
x=2950.


Jelas, prediksi ini tidak realistis. Seorang manusia yang berlari 100 meter dalam 0 detik melanggar hukum fisika!

Mari kita bahas mengapa model regresi linier gagal dalam konteks ini?

  • Batasan Biologis dan Fisik: Performa manusia memiliki batasan alami karena biologi, fisiologi, dan fisika. Model linier mengasumsikan peningkatan tak terbatas, yang tidak realistis.
  • Tren Nonlinier: Peningkatan rekor dunia cenderung melambat seiring waktu saat atlet mendekati batas fisik mereka. Model linier tidak dapat menangkap tren perlambatan ini.
  • Objek Luar Biasa dan Kejutan: Terkadang, ada objek luar biasa (misalnya, rekor Usain Bolt 9,58 detik pada tahun 2009). Ini dapat mendistorsi model linier dan membuatnya kurang akurat.

Untuk mengilustrasikan ini, plot residual (selisih antara nilai aktual dan nilai prediksi) dan tunjukkan bagaimana mereka meningkat seiring waktu, yang menunjukkan kerusakan model.



Model Nonlinier

Sebagai tambahan,  model nonlinier (misalnya, peluruhan logaritmik atau eksponensial) yang lebih baik menangkap tren perlambatan dalam peningkatan rekor dunia. Misalnya:

y=aln(x)+b
atau
y=aebx+c

Model-model ini memperhitungkan hasil yang semakin berkurang dan memberikan prediksi yang lebih realistis.

Lalu ada pertanyaan :

  • Mengapa regresi linier gagal memprediksi rekor dunia di masa mendatang secara akurat?
  • Faktor apa yang memengaruhi perkembangan rekor dunia (misalnya, metode pelatihan, teknologi, genetika)?
  • Dapatkah kita memprediksi kapan batas akhir kinerja manusia akan tercapai? Mengapa atau mengapa tidak?
Rangkuman:

  • Regresi linier adalah alat yang ampuh untuk memodelkan hubungan tetapi memiliki keterbatasan.
  • Data dunia nyata sering kali menunjukkan pola kompleks yang tidak dapat ditangkap oleh model linier.
  • Memahami keterbatasan ini sangat penting untuk membuat prediksi yang tepat.


Pemodelan Python :


import matplotlib.pyplot as plt
import numpy as np

# Historical data
years = [1912, 1921, 1930, 1936, 1956, 1960, 1968, 1983, 1988, 1991, 1994, 1996, 1999, 2005, 2008, 2009]
times = [10.6, 10.4, 10.3, 10.2, 10.1, 10.0, 9.95, 9.93, 9.92, 9.86, 9.85, 9.84, 9.79, 9.77, 9.72, 9.58]

# Linear regression model
m = -0.01  # Slope
b = 29.5   # Intercept

# Generate predicted values
future_years = np.linspace(1900, 3000, 10)
predicted_times = m * future_years + b

# Plot
plt.figure(figsize=(10, 6))
plt.scatter(years, times, color='blue', label='Actual World Records')
plt.plot(future_years, predicted_times, color='red', label='Linear Regression Prediction')
plt.axhline(0, color='black', linestyle='--', linewidth=1)  # Horizontal line at y=0
plt.title("Failure of Linear Regression: Men's 100m World Record")
plt.xlabel("Year")
plt.ylabel("World Record Time (seconds)")
plt.legend()
plt.grid(True)
plt.ylim(-1, 12)  # Set y-axis limits to show negative predictions
plt.show()

Terus pemodelan regresi linear lainnya yg benar kayak gimana ? Perhatikan contoh okupansi parkir berikut :


#ini coba parkir
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# Step 1: Sample Data (Monthly Parking Lot Occupancy)
months = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]).reshape(-1, 1)  # Month numbers (1 = January, 12 = December)
occupancy = np.array([80, 75, 65, 70, 62, 55, 45, 52, 45, 52, 68, 72])    # Occupancy percentages

# Step 2: Fit Linear Regression Model
model = LinearRegression()
model.fit(months, occupancy)

# Extract slope (m) and intercept (b)
m = model.coef_[0]  # Slope
b = model.intercept_  # Intercept

print(f"Linear Regression Model: y = {m:.2f} * x + {b:.2f}")

# Step 3: Predict Occupancy for Next Year (Months 13 to 24)
next_year_months = np.array(range(13, 25)).reshape(-1, 1)  # Months for the next year
predicted_occupancy = model.predict(next_year_months)

# Print Predictions
for month, pred in zip(range(13, 25), predicted_occupancy):
    print(f"Month {month}: Predicted Occupancy = {pred:.2f}%")

# Step 4: Visualize Results
plt.figure(figsize=(10, 6))

# Plot Historical Data
plt.scatter(months, occupancy, color='blue', label='Historical Data')

# Plot Regression Line for Historical Data
x_range = np.array(range(1, 25)).reshape(-1, 1)  # Extend line to cover both years
y_range = model.predict(x_range)
plt.plot(x_range, y_range, color='red', label='Linear Regression Fit')

# Plot Predictions for Next Year
plt.scatter(next_year_months, predicted_occupancy, color='green', label='Next Year Predictions')

# Add Labels and Legend
plt.title("Parking Lot Occupancy Prediction")
plt.xlabel("Month Number")
plt.ylabel("Occupancy (%)")
plt.axvline(x=12.5, color='gray', linestyle='--', linewidth=1, label='End of First Year')  # Separator between years
plt.legend()
plt.grid(True)
plt.show()

Hasilnya lebih masuk akal seperti berikut :






- powered by qwen ai -
Share:

Kontak Penulis



12179018.png (60×60)
+628155737755

Mail : ahocool@gmail.com

Site View

Categories

555 (8) 7 segmen (3) adc (4) amplifier (2) analog (19) android (14) antares (11) arduino (28) artikel (11) attiny (3) attiny2313 (19) audio (5) baterai (5) blog (1) bluetooth (1) chatgpt (2) cmos (2) crypto (2) dasar (46) digital (11) dimmer (5) display (3) esp8266 (26) euro2020 (13) gcc (1) gis (3) gsm (1) iklan (1) infrared (2) Input Output (3) iot (78) jam (7) jualan (12) kereta api (1) keyboard (1) keypad (3) kios pulsa (2) kit (6) komponen (17) komputer (3) komunikasi (1) kontrol (8) lain-lain (8) lcd (2) led (14) led matrix (6) line tracer (1) lm35 (1) lora (11) lorawan (2) MATV (1) memory (1) metal detector (4) microcontroller (70) micropython (6) mikrokontroler (2) mikrokontroller (14) mikrotik (5) modbus (9) mqtt (3) ninmedia (5) ntp (1) paket belajar (19) palang pintu otomatis (1) parabola (88) pcb (2) power (1) praktek (2) project (33) proyek (1) python (9) radio (28) raspberry pi (9) remote (1) revisi (1) rfid (1) robot (1) rpm (2) rs232 (1) script break down (3) sdcard (3) sensor (2) sharing (3) signage (1) sinyal (1) sms (6) software (18) solar (1) solusi (1) statistik (5) tachometer (2) technology (1) teknologi (2) telegram (2) telepon (9) televisi (167) television (28) telkomiot (5) transistor (2) troubleshoot (3) tulisan (94) tutorial (108) tv digital (6) tvri (2) unesa (8) vu meter (2) vumeter (2) wav player (3) wayang (1) wifi (3) yolo (9)

Arsip Blog

Diskusi


kaskus
Forum Hobby Elektronika