Time Series Decomposition dengan Python: Memisahkan Trend, Seasonal, dan Residual menggunakan Statsmodels
Mengapa Time Series Perlu Diurai menjadi Komponen Penyusunnya
Data time series mentah menyimpan banyak informasi di dalamnya, tetapi informasi tersebut hadir dalam bentuk campuran yang sulit dianalisis secara langsung. Sebuah grafik penjualan bulanan misalnya, mengandung pola kenaikan jangka panjang (trend), pola berulang setiap tahun (seasonal), dan fluktuasi acak (residual) yang semuanya tumpang tindih dalam satu garis. Tanpa pemisahan, sangat sulit untuk mengukur seberapa besar pengaruh musim terhadap penjualan atau mendeteksi apakah ada perubahan trend yang signifikan di tengah noise harian.
Dekomposisi time series hadir sebagai solusi untuk memisahkan komponen-komponen ini secara sistematis. Dengan memisahkan setiap komponen, kita dapat menganalisisnya secara independen. Trend bisa kita lihat dengan jelas tanpa gangguan seasonal — apakah bisnis sedang tumbuh, stagnan, atau menurun dalam jangka panjang. Pola musiman bisa diukur amplitudo dan konsistensinya dari tahun ke tahun. Residual, yang berisi sisa fluktuasi yang tidak bisa dijelaskan oleh trend dan seasonal, menjadi alat yang sangat berguna untuk mendeteksi anomali atau kejadian luar biasa seperti lonjakan penjualan karena kampanye promosi.
Pendekatan ini menjadi langkah awal yang esensial sebelum kita masuk ke tahap forecasting, anomaly detection, atau analisis kausal yang lebih kompleks. Banyak model forecasting seperti ARIMA atau Prophet bahkan memanfaatkan hasil dekomposisi sebagai bagian dari pipeline mereka. Memahami dekomposisi berarti kita membangun fondasi yang kuat untuk seluruh rangkaian analisis time series.
Model Additive dan Multiplicative — Dua Pendekatan Dekomposisi Klasik
Dekomposisi klasik bekerja dengan dua asumsi matematis yang berbeda: model additive dan model multiplicative. Model additive menyatakan bahwa time series adalah hasil penjumlahan dari komponen-komponennya: Y = Trend + Seasonal + Residual. Model ini cocok digunakan ketika amplitudo fluktuasi musiman relatif konstan sepanjang waktu. Sebagai contoh, jika penjualan es krim naik 500 unit setiap musim panas terlepas dari apakah total penjualan tahunan sedang rendah atau tinggi, maka model additive adalah pilihan yang tepat.

Gambar: Perbandingan additive seasonality (kiri) di mana amplitudo konstan vs multiplicative seasonality (kanan) di mana amplitudo membesar seiring trend — Sumber: [Portland State University](https://web.pdx.edu/~gerbing/0Forecast/Weeks/08AdditiveMult.html)
Model multiplicative, di sisi lain, menyatakan hubungan perkalian: Y = Trend × Seasonal × Residual. Model ini lebih sesuai ketika amplitudo musiman berubah secara proporsional terhadap trend. Misalnya, jika penjualan selalu naik 20 persen saat musim liburan, maka semakin tinggi trend penjualan, semakin besar pula lonjakan absolutnya. Model additive seperti menumpuk balok terpisah, sementara multiplicative seperti meregangkan pola bergelombang di atas permukaan yang naik.
Untuk menentukan model mana yang cocok, kita bisa memeriksa data secara visual terlebih dahulu. Mari kita bangun simulasi data time series dengan pola additive dan melihat bentuknya.
!pip install pandas matplotlib statsmodels
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
dates = pd.date_range(start='2019-01-01', periods=60, freq='M')
trend = np.linspace(100, 150, 60)
seasonal = 10 * np.sin(2 * np.pi * np.arange(60) / 12)
noise = np.random.normal(0, 3, 60)
data = trend + seasonal + noise
df = pd.DataFrame({'date': dates, 'value': data})
plt.figure(figsize=(12, 4))
plt.plot(df['date'], df['value'])
plt.title('Time Series: Simulated Monthly Data')
plt.xlabel('Date')
plt.ylabel('Value')
plt.grid(True, alpha=0.3)
plt.show()Output:

Dari plot yang dihasilkan, kita bisa mengamati apakah fluktuasi musiman memiliki amplitudo yang konsisten sepanjang waktu. Perhatikan bahwa dalam data simulasi ini, gelombang musiman memiliki tinggi yang kurang lebih sama dari awal hingga akhir periode. Pola seperti ini mengindikasikan bahwa model additive adalah pilihan yang tepat. Jika amplitudo membesar seiring naiknya trend, maka model multiplicative yang harus digunakan.
Mendekomposisi Data dengan Fungsi seasonal_decompose dari Statsmodels
Setelah menentukan model yang sesuai, langkah selanjutnya adalah menjalankan dekomposisi menggunakan fungsi seasonal_decompose dari library Statsmodels. Fungsi ini menerima tiga parameter utama: model untuk menentukan jenis dekomposisi (additive atau multiplicative), period untuk menentukan jumlah observasi dalam satu siklus musiman, dan extrapolate_trend untuk menangani nilai NaN pada komponen trend dengan ekstrapolasi linear.
Data Science with Python
Master the art of data analysis, visualization, and predictive modeling.
Pemilihan periode yang tepat sangat penting. Untuk data bulanan, periode ditetapkan ke 12 karena satu tahun terdiri dari 12 bulan. Untuk data mingguan, periode yang tepat adalah 52, dan untuk data harian dengan siklus mingguan, periode 7. Jika periode salah, komponen seasonal tidak akan menangkap pola musiman dengan benar dan residual akan mengandung sisa pola yang seharusnya sudah dijelaskan oleh seasonal.
Mari kita terapkan seasonal_decompose pada data simulasi yang sudah kita buat.
from statsmodels.tsa.seasonal import seasonal_decompose
decomposition = seasonal_decompose(
df['value'],
model='additive',
period=12,
extrapolate_trend=True
)
observed = decomposition.observed
trend_component = decomposition.trend
seasonal_component = decomposition.seasonal
residual_component = decomposition.resid
fig, axes = plt.subplots(4, 1, figsize=(12, 10), sharex=True)
axes[0].plot(df['date'], observed, color='black')
axes[0].set_title('Observed')
axes[1].plot(df['date'], trend_component, color='blue')
axes[1].set_title('Trend')
axes[2].plot(df['date'], seasonal_component, color='green')
axes[2].set_title('Seasonal')
axes[3].plot(df['date'], residual_component, color='red', marker='o', linestyle='none')
axes[3].set_title('Residual')
plt.tight_layout()
plt.show()Output:

Fungsi ini mengembalikan objek DecomposeResult yang memiliki empat atribut: observed untuk data asli, trend untuk komponen trend, seasonal untuk komponen musiman, dan resid untuk residual. Nilai period=12 memberi tahu fungsi bahwa pola musiman berulang setiap 12 observasi — dalam kasus kita, setiap 12 bulan. Parameter extrapolate_trend=True memastikan komponen trend tetap memiliki nilai di awal dan akhir periode meskipun metode dekomposisi klasik cenderung menghasilkan NaN di ujung-ujung deret.

Gambar: Contoh dekomposisi time series — data asli (Observed) diurai menjadi komponen Trend, Seasonal, dan Remainder (Residual) — Sumber: [Forecasting: Principles and Practice (3rd ed)](https://otexts.com/fpp3/components.html)
Dari hasil plot dengan empat subplot, kita bisa melihat bagaimana setiap komponen berkontribusi terhadap data asli. Trend menunjukkan pergerakan jangka panjang yang mulus dari nilai 100 ke 150 sesuai dengan linspace yang kita buat. Seasonal menampilkan pola sinusoidal yang berulang setiap 12 bulan dengan amplitudo yang konsisten. Residual berisi fluktuasi acak di sekitar nol tanpa pola yang jelas — indikasi bahwa model additive telah menangkap struktur data dengan baik.
Membaca dan Memvalidasi Komponen Hasil Dekomposisi
Setelah dekomposisi selesai, langkah penting berikutnya adalah membaca dan memvalidasi setiap komponen secara kritis. Komponen trend harus menunjukkan pola jangka panjang yang masuk akal secara domain — apakah data cenderung naik, turun, atau stagnan dalam periode pengamatan. Jika kita mendekomposisi data penjualan ritel dan trend menunjukkan penurunan tajam selama periode liburan, ada kemungkinan dekomposisi belum berjalan optimal atau periode yang dipilih tidak tepat.

Gambar: Dekomposisi time series CO2 atmosfer (1959-2024) menggunakan model additive — terlihat trend kenaikan jangka panjang dan pola musiman tahunan yang konsisten — Sumber: [Wikipedia](https://en.wikipedia.org/wiki/Decomposition_of_time_series)
Komponen seasonal harus menunjukkan pola berulang yang konsisten dengan periode yang ditentukan. Validasi sederhana bisa dilakukan dengan memeriksa apakah puncak dan lembah seasonal muncul pada interval yang sesuai dengan ekspektasi bisnis. Dalam data simulasi kita, pola sinusoidal dengan periode 12 bulan seharusnya menunjukkan puncak setiap bulan Desember dan lembah setiap bulan Juni. Jika ada pergeseran fase atau amplitudo yang tidak seragam, kita perlu mencurigai adanya masalah pada asumsi model.
Residual adalah komponen yang paling informatif untuk validasi model. Idealnya, residual bersifat white noise — tersebar di sekitar nol tanpa pola yang jelas, dengan varians yang konstan sepanjang waktu. Kita bisa memeriksa ini secara visual dari plot residual atau menggunakan uji statistik seperti Ljung-Box test untuk mendeteksi autokorelasi yang tersisa. Jika residual masih menunjukkan pola musiman atau trend, itu menandakan bahwa model dekomposisi yang kita pilih belum sepenuhnya menangkap struktur data.
Dalam kasus di mana residual masih mengandung pola, kita bisa mempertimbangkan alternatif yang lebih robust seperti STL Decomposition yang menggunakan LOESS untuk menangani non-linearitas dan data dengan noise tinggi. STL juga unggul dalam menangani missing values dan memberikan fleksibilitas lebih besar dalam mengontrol smoothing parameter.
Practical Considerations — Memilih Periode dan Menangani Data Hilang
Kesalahan yang paling umum dalam dekomposisi adalah menentukan periode yang tidak tepat, dan konsekuensinya cukup serius. Jika kita menetapkan periode 6 untuk data yang sebenarnya memiliki siklus 12 bulanan, komponen seasonal akan memaksakan pola setengah tahunan yang tidak sesuai. Akibatnya, residual akan mengandung sisa pola musiman yang signifikan dan bisa menyesatkan analisis selanjutnya, terutama jika residual digunakan untuk mendeteksi anomali atau sebagai input model forecasting.
Mari kita lihat perbandingan antara dekomposisi dengan periode yang benar dan yang salah.
fig, axes = plt.subplots(1, 2, figsize=(14, 4))
decomp_correct = seasonal_decompose(df['value'], model='additive', period=12)
decomp_wrong = seasonal_decompose(df['value'], model='additive', period=6)
axes[0].plot(decomp_correct.resid, marker='o', linestyle='none', alpha=0.6)
axes[0].set_title('Residual dengan Period=12 (Benar)')
axes[1].plot(decomp_wrong.resid, marker='o', linestyle='none', alpha=0.6, color='red')
axes[1].set_title('Residual dengan Period=6 (Salah)')
plt.tight_layout()
plt.show()Output:

Dari plot di atas, residual dengan periode yang benar akan tersebar acak tanpa pola yang jelas, sementara residual dengan periode yang salah masih mengandung struktur musiman yang jelas terlihat. Perbedaan ini sangat penting karena residual yang masih mengandung pola akan menghasilkan kesimpulan yang keliru jika digunakan untuk mendeteksi anomali — kita bisa saja menandai fluktuasi musiman yang normal sebagai anomali.
Selain periode, data hilang di awal atau akhir deret waktu juga perlu ditangani. Parameter extrapolate_trend=True akan mengisi nilai NaN pada komponen trend menggunakan ekstrapolasi linear, sehingga grafik tetap utuh dari awal hingga akhir. Namun perlu diingat bahwa ekstrapolasi ini bersifat linear dan mungkin tidak akurat jika data memiliki nonlinearitas yang kuat di ujung deret.
Dekomposisi klasik juga memiliki keterbatasan pada data dengan multiple seasonality — misalnya data per jam yang memiliki siklus harian sekaligus mingguan. Untuk kasus seperti ini, pendekatan STL Decomposition atau library seasonal di R menawarkan fleksibilitas yang lebih baik. Multiple seasonality membutuhkan metode yang bisa menangani lebih dari satu periode secara bersamaan, dan dekomposisi klasik dengan satu parameter period tidak cukup untuk menangani skenario tersebut.
Time series decomposition adalah teknik fundamental yang membuka jalan menuju analisis time series yang lebih dalam, mulai dari forecasting hingga anomaly detection. Untuk menguasai keterampilan ini secara menyeluruh beserta implementasinya di industri, ikuti program Data Science Bootcamp di Rumah Coding dan bangun portofolio analisis data yang solid.
Kursus Terkait
Data Science with Python
Master the art of data analysis, visualization, and predictive modeling.
E-commerce Sales Dashboard
- Data Cleaning Pipeline
- Interactive Charts
- Sales Forecasting Model
Deep Learning Bootcamp
A beginner-friendly, highly interactive bootcamp designed to take you from foundational concepts to deploying real-world Artificial Intelligence applications. Through a completely project-based approach, you will master the core of Deep Learning, Artificial Neural Networks, and Computer Vision using Python and TensorFlow, ultimately building a professional-grade AI web application for your portfolio.
GreenGuard: Intelligent Plant Disease Diagnosis Web App
- Interactive Image Upload UI: A clean, user-friendly interface built with Streamlit that supports drag-and-drop image uploads directly from a computer or mobile phone.
- Real-Time AI Inference: Utilizes a lightweight, optimized CNN model (like MobileNetV2) to process the image and return a diagnosis in seconds without heavy server load.
- Confidence Scoring Dashboard: Visually displays the model's prediction probability (e.g., "95% confident this is Tomato Late Blight") using interactive progress bars or charts.
LLM Bootcamp
This project-based bootcamp is designed for beginners to dive practically into the world of Large Language Models (LLMs). Through hands-on building, you will learn how to interact with top-tier AI APIs, master prompt engineering, orchestrate complex workflows using LangChain, and implement Retrieval-Augmented Generation (RAG) to query your own documents. By the end of this course, you will have the skills to build, test, and deploy a fully functional, custom AI web application.
Domain-Specific AI Knowledge Assistant
- Dynamic Document Processing: A sidebar interface allowing users to upload new PDF or TXT files, which the app automatically chunks, embeds, and stores in the vector database.
- Context-Aware Chat UI: A modern chat interface built with Streamlit that maintains conversation history, allowing users to ask follow-up questions naturally.
- Strict Guardrails (Anti-Hallucination): System instructions designed so the AI politely declines to answer questions that fall outside the context of the uploaded documents.
Artikel Terkait
Memahami Konsep Logistic Regression dan Implementasinya dengan Python untuk Klasifikasi Biner
Memahami Algoritma Random Forest dari Teori sampai Implementasi dengan Scikit-learn untuk Klasifikasi dan Regresi