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 BPSimport requestsr = 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)
- status: Menunjukkan status data (misalnya, "OK").
- data-availability: Menunjukkan apakah data tersedia.
- last_update: Stempel waktu pembaruan terakhir.
- subject: Berisi informasi tentang subjek data, dalam hal ini, "Transportasi".
- var: Menjelaskan variabel yang sedang diukur. Di sini, "Jumlah Penumpang Kereta Api" dengan satuan "Ribu Orang". Ini juga mencakup catatan dan sumber.
- 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: Mencantumkan tahun dari 2006 hingga 2025.
- turtahun: Mencantumkan bulan dan entri tahunan.
- datacontent: Berisi titik data aktual. Setiap kunci mewakili kombinasi variabel dan periode waktu tertentu, dan nilainya mewakili jumlah penumpang.
- related: Bagian ini kosong di berkas Anda, tetapi dapat digunakan untuk menautkan ke kumpulan data terkait lainnya.
- Array subjek terhubung ke array var melalui kolom subj. Misalnya, "Transportasi" terhubung ke "Jumlah Penumpang Kereta Api".
- Array var dirinci lebih lanjut oleh array vervar yang mengkategorikan data ke dalam berbagai jenis layanan kereta api.
- Array tahun dan turtahun menyediakan konteks temporal. Setiap titik data dalam datacontent sesuai dengan tahun dan bulan tertentu (atau tahunan).
- 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.
- 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)
# Import required librariesimport pandas as pdimport jsonwith open('data_KAI.json', 'r') as file:data = json.load(file)# Extract relevant mappingsvervar_map = {str(v['val']): v['label'] for v in data['vervar']} # Train servicestahun_map = {str(t['val']): t['label'] for t in data['tahun']} # Yearsturtahun_map = {str(t['val']): t['label'] for t in data['turtahun']} # Months + Annual# Prepare a dictionary to store the decoded datatime_series_data = {}# Decode the datacontent keysfor key, value in data['datacontent'].items():# Split the key into componentsservice_code = key[0] # First digit: service typeyear_code = key[4:7] # Next three digits: yearmonth_code = key[7:] # Remaining digits: month or annual#print(year_code)# Map codes to labelsservice_label = vervar_map.get(service_code, "Unknown Service")year_label = tahun_map.get(year_code, "Unknown Year") # Use full year_code for lookupmonth_label = turtahun_map.get(month_code, "Unknown Month")# Create a unique identifier for the column (YYYY-MM format)if month_label != "Tahunan": # Exclude annual datadate_key = f"{year_label}-{int(month_code):02d}" # Format: YYYY-MMelse:date_key = f"{year_label}-Annual" # For annual totals# Add to the time_series_data dictionaryif service_label not in time_series_data:time_series_data[service_label] = {}time_series_data[service_label][date_key] = value# Convert to a DataFrameall_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 DataFramefor 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 columndf.reset_index(inplace=True)df.rename(columns={"index": "Service"}, inplace=True)# Save the DataFrame to a CSV filecsv_file = "railway_passenger_time_series.csv"df.to_csv(csv_file, index=False)print(f"CSV file '{csv_file}' has been created successfully!")
# Import required librariesimport pandas as pdimport matplotlib.pyplot as plt# Load the previously created CSV filecsv_file = "railway_passenger_time_series.csv"df = pd.read_csv(csv_file)# Filter data for "Jabodetabek" servicejabodetabek_data = df[df['Service'] == 'Jabodetabek'].drop(columns=['Service']).Tjabodetabek_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 datetimejabodetabek_data = jabodetabek_data.sort_index() # Ensure chronological order# Plot the time series dataplt.figure(figsize=(14, 7))plt.plot(jabodetabek_data.index, jabodetabek_data['PassengerCount'], label='Jabodetabek Passenger Count', color='blue')# Add title and labelsplt.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 readabilityplt.xticks(rotation=45)# Add grid and legendplt.grid(True, linestyle='--', alpha=0.6)plt.legend()# Show the plotplt.tight_layout()plt.show()
# Import required librariesimport pandas as pdimport numpy as npfrom sklearn.linear_model import LinearRegressionimport matplotlib.pyplot as plt# Load the previously created CSV filecsv_file = "railway_passenger_time_series.csv"df = pd.read_csv(csv_file)# Filter data for "Jabodetabek" servicejabodetabek_data = df[df['Service'] == 'Jabodetabek'].drop(columns=['Service']).Tjabodetabek_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 formatjabodetabek_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 2024start_date = '2006-01'end_date = '2024-12'filtered_data = jabodetabek_data.loc[start_date:end_date]# Prepare the data for trainingdef 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 predictionX.append([i]) # Use time step as the featurey.append(series[i + 1]) # Predict the next monthreturn np.array(X), np.array(y)# Extract the passenger count seriesseries = filtered_data['PassengerCount'].values# Prepare training datasetsX_train, y_train = prepare_data(series)# Train the Linear Regression modelmodel = LinearRegression()model.fit(X_train, y_train)# Predict future values for the next 60 months (2029)future_months = 60last_time_step = len(series) - 1future_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 predictionsfuture_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 predictionscombined_data = pd.concat([filtered_data.reset_index().rename(columns={'index': 'Date'}),predictions_df])# Plot the resultsplt.figure(figsize=(14, 7))# Historical dataplt.plot(combined_data['Date'][:-future_months], combined_data['PassengerCount'][:-future_months],label='Historical Data (2006-2024)', color='blue')# Predictionsplt.plot(combined_data['Date'][-future_months:], combined_data['Predicted_PassengerCount'][-future_months:],label='Predicted Data (2025)', color='orange', linestyle='--')# Add title and labelsplt.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 readabilityplt.xticks(rotation=45)# Add grid and legendplt.grid(True, linestyle='--', alpha=0.6)plt.legend()# Show the plotplt.tight_layout()plt.show()
Hasilnya seperti ini grafiknya :
# Create a DataFrame for the predictionsfuture_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 predictionscombined_data = pd.concat([filtered_data.reset_index().rename(columns={'index': 'Date'}),predictions_df])# Plot the resultsplt.figure(figsize=(14, 7))# Historical dataplt.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')# Predictionsplt.plot(combined_data['Date'][-future_months:], combined_data['Predicted_PassengerCount'][-future_months:],label='Predicted Data (2025)', color='orange', linestyle='--')# Add title and labelsplt.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 readabilityplt.xticks(rotation=45)# Add grid and legendplt.grid(True, linestyle='--', alpha=0.6)plt.legend()# Show the plotplt.tight_layout()plt.show()
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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).
- 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.
- Pastikan fitur eksternal memiliki variabilitas dan relevansi yang cukup terhadap variabel target.
- Hapus fitur yang tidak relevan atau konstan dari set data.
- 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.
- Pastikan set pelatihan dan pengujian dipisahkan secara ketat dalam waktu.
- Hindari penggunaan data masa depan (misalnya, nilai target) sebagai fitur selama pelatihan.
0 komentar:
Posting Komentar