1. Analiis Lanjutan : a. Autokorelasi memilih lag b. Menghitung MAPE c. Menyimpan model untuk implementasi d. Menghasilkan indikator kualitas udara # Ektraksi Fitur Time series Bentuk representasi ektraksi fitur time series --- ![image](https://hackmd.io/_uploads/rkRm4mhAel.png) ![image](https://hackmd.io/_uploads/Sk0rBXhAeg.png) ![image](https://hackmd.io/_uploads/B14YH7h0gl.png) ![image](https://hackmd.io/_uploads/r1H0HX2Cxl.png) ## Statistik - **Total Fitur:** 60 - **Fitur Spektral:** 26 - **Fitur Statistik:** 20 - **Fitur Temporal:** 14 **Fitur temporal** menganalisis perubahan dan pola dalam data seiring waktu. Mereka menangkap informasi seperti tren, siklus, dan korelasi temporal, yang penting untuk memahami perilaku dinamis dan memprediksi nilai masa depan. Fitur-fitur domain waktu yang sensitif terhadap urutan pengamatan termasuk dalam kelompok ini. **Fitur statistik** merangkum data menggunakan statistik deskriptif. Mereka mencakup ukuran seperti rata-rata, varians, kemiringan (skewness), dan keruncingan (kurtosis), yang memberikan gambaran menyeluruh tentang distribusi data, kecenderungan pusat, penyebaran, dan bentuknya. Fitur-fitur yang tidak sensitif terhadap urutan pengamatan termasuk dalam kelompok ini. **Fitur spektral** berfokus pada ranah frekuensi dari data. Dengan mentransformasi data menggunakan teknik seperti transformasi Fourier atau wavelet, mereka mengungkap periodisitas, harmonik, dan komponen frekuensi yang mendasari — yang penting untuk mengidentifikasi pola siklik dan osilasi. **Fitur fraktal** menggambarkan kompleksitas dan kesamaan diri (self-similarity) data di berbagai skala. Mereka diturunkan dari teori fraktal dan mencakup ukuran seperti dimensi fraktal, yang menangkap pola rumit dan ketidakteraturan yang sering ditemukan dalam sistem alami dan kompleks. --- Saya akan menjelaskan secara detail tentang **Fitur Temporal** dalam analisis data time series! --- ## Apa itu Fitur Temporal? **Fitur Temporal** adalah fitur yang menganalisis bagaimana data **berubah seiring waktu**. Berbeda dengan fitur statistik yang hanya melihat nilai-nilai data tanpa memperhatikan urutan, fitur temporal **sangat peduli dengan urutan** dan **waktu** terjadinya setiap pengamatan. --- ## Karakteristik Utama Fitur Temporal ### 1. Sensitif terhadap Urutan (Order Matters) **Contoh:** ``` Data A: [1, 2, 3, 4, 5] - Naik bertahap Data B: [5, 4, 3, 2, 1] - Turun bertahap Data C: [3, 1, 5, 2, 4] - Acak ``` **Fitur Statistik (tidak peduli urutan):** - Mean: Sama untuk semua (3.0) - Variance: Sama untuk semua **Fitur Temporal (peduli urutan):** - Slope: A (positif), B (negatif), C (tidak konsisten) - Trend: A (naik), B (turun), C (tidak ada trend jelas) ### 2. Menangkap Informasi Dinamis Fitur temporal tidak hanya melihat "apa" nilainya, tetapi juga: - **Bagaimana** perubahan terjadi - **Kapan** perubahan terjadi - **Seberapa cepat** perubahan terjadi --- ## Jenis Informasi yang Ditangkap Fitur Temporal ### 1. TREN (Trend) **Definisi:** Arah umum pergerakan data dalam jangka panjang. **Contoh Kasus:** ```python # Tren Naik (Uptrend) harga_saham = [100, 105, 110, 115, 120, 125] # Tren: Harga saham cenderung naik # Tren Turun (Downtrend) suhu_es = [25, 20, 15, 10, 5, 0] # Tren: Suhu es turun saat mencair # Tanpa Tren (Flat) detak_jantung_istirahat = [70, 71, 70, 69, 70, 71] # Tren: Stabil, tidak ada perubahan signifikan ``` **Fitur yang Mengukur Tren:** - **Slope**: Kemiringan garis trend - **Mean diff**: Rata-rata perubahan antar titik - **Centroid**: Pusat massa temporal **Cara Menghitung Slope:** ```python import numpy as np # Data data = [100, 105, 110, 115, 120, 125] time = list(range(len(data))) # Hitung slope dengan linear regression coefficients = np.polyfit(time, data, 1) slope = coefficients[0] print(f"Slope: {slope}") # Output: 5.0 (naik 5 per waktu) ``` --- ### 2. SIKLUS (Cycles) **Definisi:** Pola yang berulang secara periodik dalam interval waktu tertentu. **Contoh Kasus:** ```python # Siklus Harian - Suhu waktu = [0, 6, 12, 18, 24, 30, 36, 42, 48] # jam suhu = [20, 25, 30, 25, 20, 25, 30, 25, 20] # celsius # Siklus 24 jam: Dingin (malam) → Panas (siang) → Dingin (malam) # Siklus Mingguan - Penjualan Restoran hari = ['Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab', 'Min'] pelanggan = [50, 60, 55, 65, 80, 150, 120] # Siklus mingguan: Weekday (sedikit) → Weekend (ramai) # Siklus Tahunan - Penjualan AC bulan = ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Ags', 'Sep', 'Okt', 'Nov', 'Des'] penjualan = [10, 12, 20, 35, 50, 80, 90, 85, 60, 30, 15, 8] # Siklus tahunan: Rendah (musim dingin) → Tinggi (musim panas) ``` **Fitur yang Mengukur Siklus:** - **Autocorrelation**: Korelasi dengan versi delayed dari dirinya sendiri - **Zero crossing rate**: Frekuensi perubahan tanda (+ ke - atau sebaliknya) - **Positive/Negative turning points**: Titik balik naik/turun **Cara Menghitung Autocorrelation:** ```python import numpy as np data = [20, 25, 30, 25, 20, 25, 30, 25, 20] # Autocorrelation dengan lag=4 (1 siklus penuh) mean = np.mean(data) c0 = np.sum((data - mean) ** 2) c_lag = np.sum((data[:-4] - mean) * (data[4:] - mean)) autocorr = c_lag / c0 print(f"Autocorrelation: {autocorr:.3f}") # Nilai tinggi = ada pola berulang ``` --- ### 3. KORELASI TEMPORAL (Temporal Correlation) **Definisi:** Hubungan antara nilai sekarang dengan nilai di masa lalu atau masa depan. **Contoh Kasus:** ```python # Korelasi Positif # Jika suhu kemarin tinggi, hari ini juga cenderung tinggi suhu_kemarin = [25, 26, 27, 28, 29] suhu_hari_ini = [26, 27, 28, 29, 30] # Korelasi tinggi: Hari ini mengikuti kemarin # Korelasi Negatif # Jika harga saham naik tajam, besok mungkin turun (koreksi) perubahan_hari1 = [+10, +8, +12, +15, +20] # naik tajam perubahan_hari2 = [-5, -3, -6, -8, -10] # koreksi turun # Tanpa Korelasi # Hasil lemparan dadu tidak bergantung pada lemparan sebelumnya dadu_lemparan1 = [3, 1, 5, 2, 6] dadu_lemparan2 = [4, 6, 1, 5, 3] # Tidak ada korelasi: Independen ``` **Fitur yang Mengukur Korelasi Temporal:** - **Autocorrelation**: Korelasi dengan diri sendiri di waktu berbeda - **Mean/Median diff**: Rata-rata perubahan berturutan - **Signal distance**: Total jarak yang "ditempuh" sinyal --- ## Perbedaan: Fitur Temporal vs Fitur Statistik vs Fitur Spektral | Aspek | Fitur Temporal | Fitur Statistik | Fitur Spektral | |-------|---------------|-----------------|----------------| | **Domain** | Waktu | Tidak peduli waktu | Frekuensi | | **Urutan** | Sangat penting | Tidak penting | Tidak penting | | **Fokus** | Perubahan, pola | Distribusi nilai | Komponen frekuensi | | **Contoh** | Slope, Autocorr | Mean, Variance | FFT, Power Spectrum | | **Pertanyaan** | "Bagaimana data berubah?" | "Seperti apa datanya?" | "Frekuensi apa yang dominan?" | --- ## Contoh Fitur Temporal dalam TSFEL ### 1. Slope (Kemiringan) **Apa yang diukur:** Arah dan kecepatan perubahan data. ```python import numpy as np # Data dengan tren naik data_naik = [1, 2, 3, 4, 5] time = range(len(data_naik)) # Hitung slope slope = np.polyfit(time, data_naik, 1)[0] print(f"Slope: {slope}") # 1.0 (naik 1 unit per waktu) # Interpretasi: # Slope > 0: Tren naik # Slope < 0: Tren turun # Slope ≈ 0: Stabil/flat ``` ### 2. Autocorrelation **Apa yang diukur:** Seberapa mirip data dengan versi shifted-nya. ```python # Data dengan pola berulang data_siklus = [1, 2, 3, 2, 1, 2, 3, 2, 1] # Autocorrelation lag=4 (satu siklus) from scipy import signal autocorr = signal.correlate(data_siklus, data_siklus, mode='full') autocorr = autocorr[len(autocorr)//2:] # Ambil separuh # Interpretasi: # Nilai tinggi di lag tertentu = ada siklus dengan periode tersebut ``` ### 3. Mean Absolute Diff **Apa yang diukur:** Rata-rata perubahan absolut antar titik berurutan. ```python data = [10, 12, 9, 15, 11] # Hitung perbedaan berurutan diffs = [abs(data[i+1] - data[i]) for i in range(len(data)-1)] mean_abs_diff = sum(diffs) / len(diffs) print(f"Mean Absolute Diff: {mean_abs_diff}") # Nilai tinggi = data berubah-ubah cepat (volatilitas tinggi) # Nilai rendah = data stabil ``` ### 4. Zero Crossing Rate **Apa yang diukur:** Seberapa sering sinyal berubah tanda (dari + ke - atau sebaliknya). ```python data = [1, 2, -1, 3, -2, 1, -1, 2] # Hitung zero crossing zero_crossings = 0 for i in range(len(data)-1): if data[i] * data[i+1] < 0: # Tanda berbeda zero_crossings += 1 zcr = zero_crossings / (len(data) - 1) print(f"Zero Crossing Rate: {zcr}") # Interpretasi: # Tinggi = data berfluktuasi cepat (frekuensi tinggi) # Rendah = data stabil atau tren konsisten ``` ### 5. Centroid **Apa yang diukur:** Pusat massa temporal (kapan "energi" data terpusat). ```python data = [1, 2, 5, 3, 1] # Puncak di tengah (indeks 2) time = range(len(data)) # Hitung centroid centroid = sum([t * d for t, d in zip(time, data)]) / sum(data) print(f"Centroid: {centroid}") # ≈ 2.0 # Interpretasi: # Centroid awal = aktivitas di awal periode # Centroid tengah = aktivitas di tengah # Centroid akhir = aktivitas di akhir ``` --- ## Aplikasi Praktis Fitur Temporal ### 1. Prediksi Harga Saham ```python # Fitur temporal yang berguna: # - Slope: Apakah harga sedang naik atau turun? # - Autocorrelation: Apakah ada pola berulang? # - Mean diff: Seberapa volatile harga? ``` ### 2. Deteksi Aktivitas Manusia (dari Sensor) ```python # Data accelerometer # - Slope: Perubahan kecepatan (akselerasi/deselerasi) # - Zero crossing: Frekuensi gerakan (berjalan vs berlari) # - Turning points: Perubahan arah gerakan ``` ### 3. Monitoring Kesehatan (ECG, EEG) ```python # ECG (jantung) # - Autocorrelation: Deteksi ritme jantung # - Turning points: Deteksi beat jantung # - Slope: Kecepatan perubahan (aritmia?) ``` ### 4. Analisis Cuaca ```python # Suhu harian # - Slope: Tren pemanasan/pendinginan # - Autocorrelation: Siklus harian/musiman # - Centroid: Kapan suhu tertinggi terjadi ``` --- ## Visualisasi: Mengapa Urutan Penting ```python import numpy as np import matplotlib.pyplot as plt # Dua sinyal dengan nilai statistik sama tetapi temporal berbeda signal1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # Naik steady signal2 = [1, 10, 2, 9, 3, 8, 4, 7, 5, 6] # Naik-turun # Statistik (sama) print(f"Mean: {np.mean(signal1)} vs {np.mean(signal2)}") # Sama print(f"Std: {np.std(signal1):.2f} vs {np.std(signal2):.2f}") # Sama # Temporal (berbeda) slope1 = np.polyfit(range(10), signal1, 1)[0] slope2 = np.polyfit(range(10), signal2, 1)[0] print(f"Slope: {slope1} vs {slope2:.2f}") # Berbeda! # Plot plt.figure(figsize=(12, 4)) plt.subplot(1, 2, 1) plt.plot(signal1, marker='o') plt.title(f'Signal 1: Smooth (Slope={slope1})') plt.grid(True) plt.subplot(1, 2, 2) plt.plot(signal2, marker='o') plt.title(f'Signal 2: Zigzag (Slope={slope2:.2f})') plt.grid(True) plt.tight_layout() plt.show() ``` --- **Fitur Temporal Penting Karena:** 1. **Menangkap Dinamika**: Memahami bagaimana sistem berubah, bukan hanya keadaan staticnya 2. **Prediksi Lebih Baik**: Tren dan pola membantu memprediksi nilai masa depan 3. **Deteksi Anomali**: Perubahan mendadak terdeteksi dari pola temporal 4. **Pemahaman Konteks**: Urutan memberikan makna (contoh: "jatuh lalu bangun" vs "bangun lalu jatuh") **Kapan Menggunakan Fitur Temporal:** - Data yang berurutan waktu (time series) - Perubahan dari waktu ke waktu itu penting - Ingin memahami tren, siklus, atau momentum - Prediksi berbasis pola historis **Kombinasi dengan Fitur Lain:** Untuk analisis lengkap, kombinasikan: - **Temporal**: Tren dan perubahan - **Statistik**: Distribusi dan nilai pusat - **Spektral**: Frekuensi dan periodisitas # Fitur Statistik pada Data Time Series ## Karakteristik Khusus dalam Time Series Pada data time series (deret waktu), fitur statistik memiliki peran dan interpretasi yang sedikit berbeda dibandingkan data biasa karena ada dimensi waktu yang perlu dipertimbangkan. ## 1. Rata-rata dalam Time Series Rata-rata menunjukkan nilai tengah dari seluruh periode pengamatan. Ini memberikan gambaran level atau tingkat umum dari variabel yang diamati sepanjang waktu. Misalnya, rata-rata suhu harian selama satu tahun, atau rata-rata harga saham selama sebulan. **Catatan penting**: Meskipun rata-rata tidak peduli urutan, dalam time series kita sering tertarik pada rata-rata bergerak (moving average) yang justru mempertimbangkan urutan untuk melihat tren. ## 2. Varians dalam Time Series Varians mengukur volatilitas atau fluktuasi data sepanjang waktu. Dalam konteks time series: - **Varians tinggi**: Data sangat berfluktuasi, tidak stabil (misalnya harga saham yang volatil) - **Varians rendah**: Data relatif stabil dan konsisten dari waktu ke waktu - Varians yang berubah seiring waktu disebut heteroskedastisitas, yang penting dalam analisis keuangan ## 3. Kemiringan (Skewness) dalam Time Series Kemiringan menunjukkan apakah nilai ekstrem lebih sering terjadi di satu sisi: - **Positif**: Lebih banyak lonjakan mendadak ke atas (misalnya harga saham yang kadang naik drastis) - **Negatif**: Lebih banyak penurunan drastis (misalnya suhu yang kadang turun ekstrem) - Ini membantu mengidentifikasi risiko asimetris dalam data ## 4. Keruncingan (Kurtosis) dalam Time Series Keruncingan menunjukkan seberapa sering kejadian ekstrem terjadi: - **Kurtosis tinggi**: Sering ada nilai ekstrem atau outlier (misalnya return saham dengan kejutan besar yang sering) - **Kurtosis rendah**: Kejadian ekstrem jarang, data lebih "normal" - Penting untuk manajemen risiko dan deteksi anomali ## Penggunaan dalam Analisis Time Series ### Window Analysis (Analisis Jendela Waktu) Fitur statistik sering dihitung pada window atau segmen waktu tertentu: - Rata-rata per bulan, per kuartal, atau per tahun - Varians pada periode tertentu untuk melihat perubahan volatilitas - Membandingkan statistik antar periode untuk deteksi perubahan pola ### Feature Engineering Dalam machine learning untuk time series, fitur-fitur ini dihitung sebagai: - **Lag features**: Statistik dari periode sebelumnya - **Rolling statistics**: Statistik bergerak dalam window tertentu - **Expanding statistics**: Statistik kumulatif dari awal hingga titik tertentu ## Keterbatasan: Tidak Menangkap Dependensi Temporal Ini adalah poin krusial - fitur statistik tradisional **tidak sensitif terhadap urutan** sehingga: - **Tidak menangkap tren**: Apakah data naik, turun, atau stabil dari waktu ke waktu - **Tidak menangkap musiman**: Pola berulang seperti penjualan tinggi di akhir tahun - **Tidak menangkap autokorelasi**: Hubungan antara nilai sekarang dengan nilai sebelumnya - **Tidak menangkap siklus**: Pola naik-turun yang berulang ### Contoh Ilustrasi Dua time series ini akan memiliki statistik yang sama persis: - **Series A**: 10, 20, 30, 40, 50 (tren naik) - **Series B**: 50, 30, 10, 40, 20 (acak) Keduanya punya rata-rata 30, varians sama, tapi makna dan pola waktunya sangat berbeda! ## Solusi: Kombinasi dengan Fitur Temporal Untuk analisis time series yang lengkap, fitur statistik harus dikombinasikan dengan: - **Fitur autokorelasi**: Mengukur korelasi dengan lag sebelumnya - **Fitur tren**: Gradien atau slope dari data - **Fitur musiman**: Pola berulang periodik - **Fitur spectral**: Analisis frekuensi dari data - **Change point features**: Deteksi perubahan mendadak Fitur statistik tetap berguna untuk time series sebagai gambaran umum karakteristik data, terutama untuk: - Memahami level dan variabilitas umum - Deteksi anomali statistik - Perbandingan antar periode - Input tambahan untuk model prediksi Namun, mereka tidak cukup sendiri dan harus dilengkapi dengan fitur yang menangkap struktur temporal untuk analisis time series yang komprehensif. ## FITUR SPEKTRAL (26) | No | Nama Fitur | Deskripsi | Fungsi | Kompleksitas | Jumlah Fitur | Parameter | Tag | Digunakan | |----|------------|-----------|--------|--------------|--------------|-----------|-----|-----------| | 1 | FFT mean coefficient | Menghitung nilai rata-rata dari setiap frekuensi spektrogram. | `tsfel.fft_mean_coeff` | CONSTANT | nfreq | fs=100, nfreq=256 | - | ya | | 2 | Fundamental frequency | Menghitung frekuensi fundamental. | `tsfel.fundamental_frequency` | LOG | 1 | fs=100 | - | ya | | 3 | Human range energy | Menghitung rasio energi rentang manusia yang diberikan oleh rasio antara energi pada frekuensi 0.6-2.5Hz dan seluruh pita energi. | `tsfel.human_range_energy` | LOG | 1 | fs=100 | inertial | ya | | 4 | LPCC | Menghitung koefisien cepstral prediksi linear. | `tsfel.lpcc` | LOG | n_coeff | n_coeff=12 | audio | ya | | 5 | MFCC | Menghitung koefisien cepstral MEL. | `tsfel.mfcc` | CONSTANT | num_ceps | cep_lifter=22, fs=100, nfft=512, nfilt=40, num_ceps=12, pre_emphasis=0.97 | audio, emg | ya | | 6 | Max power spectrum | Menghitung kepadatan spektrum daya maksimum. | `tsfel.max_power_spectrum` | LOG | 1 | fs=100 | - | ya | | 7 | Maximum frequency | Menghitung frekuensi maksimum. | `tsfel.max_frequency` | LOG | 1 | fs=100 | - | ya | | 8 | Median frequency | Menghitung frekuensi median. | `tsfel.median_frequency` | LOG | 1 | fs=100 | - | ya | | 9 | Power bandwidth | Menghitung bandwidth kepadatan spektrum daya dari sinyal. | `tsfel.power_bandwidth` | LOG | 1 | fs=100 | - | ya | | 10 | Spectral centroid | Menghitung pusat massa dari spektrum. | `tsfel.spectral_centroid` | LINEAR | 1 | fs=100 | audio | ya | | 11 | Spectral decrease | Menghitung jumlah penurunan amplitudo spektra. | `tsfel.spectral_decrease` | LOG | 1 | fs=100 | - | ya | | 12 | Spectral distance | Menghitung jarak spektral sinyal. | `tsfel.spectral_distance` | LOG | 1 | fs=100 | - | ya | | 13 | Spectral entropy | Menghitung entropi spektral sinyal berdasarkan transformasi Fourier. | `tsfel.spectral_entropy` | LOG | 1 | fs=100 | eeg | ya | | 14 | Spectral kurtosis | Menghitung keruncingan distribusi di sekitar nilai rata-ratanya. | `tsfel.spectral_kurtosis` | LINEAR | 1 | fs=100 | - | ya | | 15 | Spectral positive turning points | Menghitung jumlah titik balik positif dari sinyal magnitudo fft. | `tsfel.spectral_positive_turning` | LOG | 1 | fs=100 | - | ya | | 16 | Spectral roll-off | Menghitung frekuensi di mana 95% dari magnitudo sinyal terkandung di bawah nilai ini. | `tsfel.spectral_roll_off` | LOG | 1 | fs=100 | audio | ya | | 17 | Spectral roll-on | Menghitung frekuensi di mana 5% dari magnitudo sinyal terkandung di bawah nilai ini. | `tsfel.spectral_roll_on` | LOG | 1 | fs=100 | - | ya | | 18 | Spectral skewness | Menghitung asimetri distribusi di sekitar nilai rata-ratanya. | `tsfel.spectral_skewness` | LINEAR | 1 | fs=100 | - | ya | | 19 | Spectral slope | Menghitung kemiringan spektral, diperoleh dengan regresi linear dari amplitudo spektral. | `tsfel.spectral_slope` | LOG | 1 | fs=100 | - | ya | | 20 | Spectral spread | Menghitung penyebaran spektrum di sekitar nilai rata-ratanya. | `tsfel.spectral_spread` | LINEAR | 1 | fs=100 | - | ya | | 21 | Spectral variation | Menghitung jumlah variasi spektrum sepanjang waktu. | `tsfel.spectral_variation` | LOG | 1 | fs=100 | - | ya | | 22 | Wavelet absolute mean | Menghitung nilai rata-rata absolut CWT dari setiap skala wavelet. | `tsfel.wavelet_abs_mean` | LINEAR | widths | function=scipy.signal.ricker, widths=np.arange(1,10) | eeg, ecg | ya | | 23 | Wavelet energy | Menghitung energi CWT dari setiap skala wavelet. | `tsfel.wavelet_energy` | LINEAR | widths | function=scipy.signal.ricker, widths=np.arange(1,10) | eeg | ya | | 24 | Wavelet entropy | Menghitung entropi CWT dari sinyal. | `tsfel.wavelet_entropy` | LINEAR | 1 | function=scipy.signal.ricker, widths=np.arange(1,10) | eeg | ya | | 25 | Wavelet standard deviation | Menghitung nilai standar deviasi CWT dari setiap skala wavelet. | `tsfel.wavelet_std` | LINEAR | widths | function=scipy.signal.ricker, widths=np.arange(1,10) | eeg | ya | | 26 | Wavelet variance | Menghitung nilai varians CWT dari setiap skala wavelet. | `tsfel.wavelet_var` | LINEAR | widths | function=scipy.signal.ricker, widths=np.arange(1,10) | eeg | ya | --- ## FITUR STATISTIK (20) | No | Nama Fitur | Deskripsi | Fungsi | Kompleksitas | Jumlah Fitur | Parameter | Tag | Digunakan | |----|------------|-----------|--------|--------------|--------------|-----------|-----|-----------| | 27 | Absolute energy | Menghitung energi absolut dari sinyal. | `tsfel.abs_energy` | LOG | 1 | - | audio | ya | | 28 | Average power | Menghitung daya rata-rata dari sinyal. | `tsfel.average_power` | CONSTANT | 1 | fs=100 | audio | ya | | 29 | ECDF | Menghitung nilai-nilai ECDF (fungsi distribusi kumulatif empiris) sepanjang sumbu waktu. | `tsfel.ecdf` | LOG | d | d=10 | - | ya | | 30 | ECDF Percentile | Menentukan nilai persentil dari ECDF. | `tsfel.ecdf_percentile` | LOG | percentile | percentile=[0.2, 0.8] | - | ya | | 31 | ECDF Percentile Count | Menentukan jumlah kumulatif sampel yang kurang dari persentil. | `tsfel.ecdf_percentile_count` | LOG | percentile | percentile=[0.2, 0.8] | - | ya | | 32 | Entropy | Menghitung entropi sinyal menggunakan Entropi Shannon. | `tsfel.entropy` | LOG | 1 | prob=standard | eeg | ya | | 33 | Histogram | Menghitung histogram dari sinyal. | `tsfel.hist` | LOG | nbins | nbins=10, r=1 | - | ya | | 34 | Interquartile range | Menghitung rentang interkuartil dari sinyal. | `tsfel.interq_range` | CONSTANT | 1 | - | - | ya | | 35 | Kurtosis | Menghitung kurtosis dari sinyal. | `tsfel.kurtosis` | CONSTANT | 1 | - | - | ya | | 36 | Max | Menghitung nilai maksimum dari sinyal. | `tsfel.calc_max` | CONSTANT | 1 | - | - | ya | | 37 | Mean | Menghitung nilai rata-rata dari sinyal. | `tsfel.calc_mean` | CONSTANT | 1 | - | inertial | ya | | 38 | Mean absolute deviation | Menghitung deviasi absolut rata-rata dari sinyal. | `tsfel.mean_abs_deviation` | LOG | 1 | - | - | ya | | 39 | Median | Menghitung median dari sinyal. | `tsfel.calc_median` | CONSTANT | 1 | - | - | ya | | 40 | Median absolute deviation | Menghitung deviasi absolut median dari sinyal. | `tsfel.median_abs_deviation` | CONSTANT | 1 | - | - | ya | | 41 | Min | Menghitung nilai minimum dari sinyal. | `tsfel.calc_min` | CONSTANT | 1 | - | - | ya | | 42 | Peak to peak distance | Menghitung jarak puncak ke puncak. | `tsfel.pk_pk_distance` | CONSTANT | 1 | - | - | ya | | 43 | Root mean square | Menghitung akar kuadrat rata-rata dari sinyal. | `tsfel.rms` | CONSTANT | 1 | - | emg, inertial | ya | | 44 | Skewness | Menghitung kemiringan (skewness) dari sinyal. | `tsfel.skewness` | CONSTANT | 1 | - | - | ya | | 45 | Standard deviation | Menghitung standar deviasi dari sinyal. | `tsfel.calc_std` | CONSTANT | 1 | - | - | ya | | 46 | Variance | Menghitung varians dari sinyal. | `tsfel.calc_var` | CONSTANT | 1 | - | - | ya | --- ## FITUR TEMPORAL (14) | No | Nama Fitur | Deskripsi | Fungsi | Kompleksitas | Jumlah Fitur | Parameter | Tag | Digunakan | |----|------------|-----------|--------|--------------|--------------|-----------|-----|-----------| | 47 | Area under the curve | Menghitung luas di bawah kurva sinyal yang dihitung dengan aturan trapesium. | `tsfel.auc` | LOG | 1 | fs=100 | - | ya | | 48 | Autocorrelation | Menghitung autokorelasi dari sinyal. | `tsfel.autocorr` | CONSTANT | 1 | - | inertial | ya | | 49 | Centroid | Menghitung pusat massa sepanjang sumbu waktu. | `tsfel.calc_centroid` | CONSTANT | 1 | fs=100 | - | ya | | 50 | Mean absolute diff | Menghitung perbedaan absolut rata-rata dari sinyal. | `tsfel.mean_abs_diff` | CONSTANT | 1 | - | - | ya | | 51 | Mean diff | Menghitung rata-rata perbedaan dari sinyal. | `tsfel.mean_diff` | CONSTANT | 1 | - | - | ya | | 52 | Median absolute diff | Menghitung perbedaan absolut median dari sinyal. | `tsfel.median_abs_diff` | CONSTANT | 1 | - | - | ya | | 53 | Median diff | Menghitung median perbedaan dari sinyal. | `tsfel.median_diff` | CONSTANT | 1 | - | - | ya | | 54 | Negative turning points | Menghitung jumlah titik balik negatif dari sinyal. | `tsfel.negative_turning` | CONSTANT | 1 | - | emg | ya | | 55 | Neighbourhood peaks | Menghitung jumlah puncak dari lingkungan yang ditentukan dari sinyal. | `tsfel.neighbourhood_peaks` | CONSTANT | 1 | n=10 | - | ya | | 56 | Positive turning points | Menghitung jumlah titik balik positif dari sinyal. | `tsfel.positive_turning` | CONSTANT | 1 | - | emg | ya | | 57 | Signal distance | Menghitung jarak perjalanan sinyal. | `tsfel.distance` | CONSTANT | 1 | - | - | ya | | 58 | Slope | Menghitung kemiringan sinyal dengan menyesuaikan persamaan linear pada data yang diamati. | `tsfel.slope` | LOG | 1 | - | - | ya | | 59 | Sum absolute diff | Menghitung jumlah perbedaan absolut dari sinyal. | `tsfel.sum_abs_diff` | CONSTANT | 1 | - | - | ya | | 60 | Zero crossing rate | Menghitung tingkat penyeberangan nol dari sinyal. | `tsfel.zero_cross` | CONSTANT | 1 | - | audio, emg | ya | --- ## Referensi Tag Fitur - **audio** - Fitur yang dirancang khusus untuk pemrosesan sinyal audio - **eeg** - Fitur untuk elektroensefalografi (sinyal otak) - **emg** - Fitur untuk elektromiografi (sinyal otot) - **ecg** - Fitur untuk elektrokardiografi (sinyal jantung) - **inertial** - Fitur untuk sinyal unit pengukuran inersia (IMU) --- ## Tingkat Kompleksitas - **CONSTANT** - Kompleksitas komputasi O(1) - paling cepat - **LOG** - Kompleksitas komputasi O(log n) - sedang - **LINEAR** - Kompleksitas komputasi O(n) - lebih lambat tetapi masih efisien --- ## Catatan Penggunaan Semua fitur dalam library ini diaktifkan (`use: yes`) dan dapat diekstraksi menggunakan library TSFEL. Parameter `fs` biasanya mengacu pada frekuensi sampling (default: 100 Hz), yang dapat disesuaikan berdasarkan karakteristik sinyal Anda. Untuk informasi lebih lanjut, kunjungi: [Dokumentasi TSFEL](https://tsfel.readthedocs.io/) ## Apa itu ECDF? **ECDF (Empirical Cumulative Distribution Function)** atau Fungsi Distribusi Kumulatif Empiris adalah fungsi yang menunjukkan **proporsi data yang bernilai kurang dari atau sama dengan x**. --- ## Rumus ECDF ``` ECDF(x) = (Jumlah nilai ≤ x) / (Total jumlah data) ``` atau dalam notasi matematika: ``` F̂(x) = (1/n) × Σ I(Xi ≤ x) ``` Dimana: - **F̂(x)** = nilai ECDF pada titik x - **n** = jumlah total data - **I(Xi ≤ x)** = fungsi indikator (1 jika Xi ≤ x, 0 jika tidak) --- ## Langkah-langkah Menghitung ECDF ### **Contoh Data:** ``` Data: [3, 7, 1, 9, 2, 5, 8, 4, 6] ``` ### **Langkah 1: Urutkan Data** ``` Data terurut: [1, 2, 3, 4, 5, 6, 7, 8, 9] Total data (n) = 9 ``` ### **Langkah 2: Hitung ECDF untuk Setiap Nilai** Untuk setiap nilai x, hitung berapa banyak data yang ≤ x, lalu bagi dengan total data. | Nilai (x) | Jumlah Data ≤ x | ECDF(x) = Jumlah/Total | Persentase | |-----------|-----------------|------------------------|------------| | 1 | 1 | 1/9 | 0.111 (11.1%) | | 2 | 2 | 2/9 | 0.222 (22.2%) | | 3 | 3 | 3/9 | 0.333 (33.3%) | | 4 | 4 | 4/9 | 0.444 (44.4%) | | 5 | 5 | 5/9 | 0.556 (55.6%) | | 6 | 6 | 6/9 | 0.667 (66.7%) | | 7 | 7 | 7/9 | 0.778 (77.8%) | | 8 | 8 | 8/9 | 0.889 (88.9%) | | 9 | 9 | 9/9 | 1.000 (100%) | --- ## Visualisasi ECDF ECDF membentuk **fungsi tangga naik** (step function): ``` ECDF 1.0 | ┌───── | │ 0.8 | ┌─────┤ | │ │ 0.6 | ┌─────┤ │ | │ │ │ 0.4 | ┌─────┤ │ │ | │ │ │ │ 0.2 |──┤ │ │ │ | │ │ │ │ 0.0 └──┴─────┴─────┴─────┴─── 1 2 3 4 5 6 7 8 9 → Nilai x ``` --- ## Implementasi dalam Python ### **Cara 1: Manual** ```python import numpy as np # Data data = [3, 7, 1, 9, 2, 5, 8, 4, 6] # Urutkan data sorted_data = np.sort(data) n = len(data) # Hitung ECDF ecdf_values = np.arange(1, n+1) / n print("Nilai | ECDF") print("-" * 20) for val, ecdf in zip(sorted_data, ecdf_values): print(f"{val:5d} | {ecdf:.3f}") ``` ### **Cara 2: Menggunakan Fungsi** ```python def calculate_ecdf(data): """ Menghitung ECDF dari data """ n = len(data) sorted_data = np.sort(data) ecdf = np.arange(1, n+1) / n return sorted_data, ecdf # Contoh penggunaan data = [3, 7, 1, 9, 2, 5, 8, 4, 6] x, y = calculate_ecdf(data) # Plot import matplotlib.pyplot as plt plt.step(x, y, where='post') plt.xlabel('Nilai') plt.ylabel('ECDF') plt.title('Empirical Cumulative Distribution Function') plt.grid(True) plt.show() ``` ### **Cara 3: Menggunakan TSFEL** ```python import tsfel # Data sinyal time series signal = [3, 7, 1, 9, 2, 5, 8, 4, 6] # Hitung ECDF dengan 10 bins ecdf_features = tsfel.ecdf(signal, d=10) print("ECDF values:", ecdf_features) ``` --- ## Interpretasi ECDF ### **Contoh Interpretasi:** Dari tabel di atas: - **ECDF(5) = 0.556** → 55.6% data memiliki nilai ≤ 5 - **ECDF(7) = 0.778** → 77.8% data memiliki nilai ≤ 7 - **ECDF(9) = 1.000** → 100% data memiliki nilai ≤ 9 --- ## Contoh Kasus Nyata ### **Kasus: Analisis Nilai Ujian Siswa** Data nilai: [65, 70, 75, 80, 85, 90, 95] | Nilai | ECDF | Interpretasi | |-------|------|--------------| | 65 | 0.143 | 14.3% siswa mendapat nilai ≤ 65 | | 70 | 0.286 | 28.6% siswa mendapat nilai ≤ 70 | | 75 | 0.429 | 42.9% siswa mendapat nilai ≤ 75 | | 80 | 0.571 | 57.1% siswa mendapat nilai ≤ 80 | | 85 | 0.714 | 71.4% siswa mendapat nilai ≤ 85 | | 90 | 0.857 | 85.7% siswa mendapat nilai ≤ 90 | | 95 | 1.000 | 100% siswa mendapat nilai ≤ 95 | **Insight:** - Median (50%) ada di sekitar nilai 78-79 (antara 75 dan 80) - 71.4% siswa lulus dengan nilai ≥ 85 --- ## ECDF vs Histogram | Aspek | Histogram | ECDF | |-------|-----------|------| | **Bentuk** | Bar chart | Step function | | **Y-axis** | Frekuensi/Count | Probabilitas kumulatif (0-1) | | **Informasi** | Distribusi per bin | Proporsi kumulatif | | **Kelebihan** | Mudah dibaca | Tidak perlu pilih bin, lebih presisi | | **Kekurangan** | Perlu pilih jumlah bin | Kurang intuitif untuk pemula | --- ## Parameter dalam TSFEL Dalam TSFEL, fitur ECDF memiliki parameter `d`: ```python tsfel.ecdf(signal, d=10) ``` **Parameter d:** - Menentukan **jumlah titik** di mana ECDF dihitung - Default: d=10 (menghitung ECDF di 10 titik) - Menghasilkan **d nilai** ECDF yang merepresentasikan distribusi sinyal --- ## Kegunaan ECDF 1. **Analisis Distribusi Data** tanpa asumsi distribusi tertentu 2. **Membandingkan Dua Dataset** secara visual 3. **Mendeteksi Outlier** dengan melihat lompatan besar 4. **Menghitung Persentil** (median, quartile, dll) 5. **Feature Engineering** dalam machine learning --- **Rumus :** ``` ECDF(x) = Berapa persen data yang ≤ x ``` # Absolute Energy ## Apa itu Absolute Energy? **Absolute Energy** adalah total energi dari sinyal yang dihitung dengan menjumlahkan **kuadrat dari semua nilai** dalam sinyal. Ini mengukur seberapa "kuat" atau "aktif" suatu sinyal. --- ## Rumus Absolute Energy ``` Absolute Energy = Σ(xi²) ``` atau lebih lengkap: ``` E = x₁² + x₂² + x₃² + ... + xₙ² ``` Dimana: - **E** = Absolute Energy - **xi** = nilai sinyal pada titik ke-i - **n** = jumlah total titik data --- ## Langkah-langkah Menghitung Absolute Energy ### Contoh Data Sinyal: ``` Sinyal: [2, -3, 4, 1, -2] ``` ### Langkah 1: Kuadratkan Setiap Nilai | Nilai (x) | Kuadrat (x²) | |-----------|--------------| | 2 | 4 | | -3 | 9 | | 4 | 16 | | 1 | 1 | | -2 | 4 | ### Langkah 2: Jumlahkan Semua Nilai Kuadrat ``` Absolute Energy = 4 + 9 + 16 + 1 + 4 = 34 ``` **Hasil: Absolute Energy = 34** --- ## Contoh Perhitungan Lengkap ### Contoh 1: Sinyal Sederhana ``` Sinyal: [1, 2, 3, 4, 5] Perhitungan: 1² = 1 2² = 4 3² = 9 4² = 16 5² = 25 Absolute Energy = 1 + 4 + 9 + 16 + 25 = 55 ``` ### Contoh 2: Sinyal dengan Nilai Negatif ``` Sinyal: [-2, 3, -1, 4, -3] Perhitungan: (-2)² = 4 3² = 9 (-1)² = 1 4² = 16 (-3)² = 9 Absolute Energy = 4 + 9 + 1 + 16 + 9 = 39 ``` **Catatan:** Nilai negatif tetap menjadi positif setelah dikuadratkan! --- ## Implementasi dalam Python ### Cara 1: Manual dengan Loop ```python def absolute_energy_manual(signal): """ Menghitung absolute energy secara manual """ energy = 0 for value in signal: energy += value ** 2 return energy # Contoh penggunaan signal = [2, -3, 4, 1, -2] result = absolute_energy_manual(signal) print(f"Absolute Energy: {result}") # Output: Absolute Energy: 34 ``` ### Cara 2: Menggunakan NumPy (Lebih Efisien) ```python import numpy as np def absolute_energy_numpy(signal): """ Menghitung absolute energy dengan NumPy """ return np.sum(np.square(signal)) # Contoh penggunaan signal = np.array([2, -3, 4, 1, -2]) result = absolute_energy_numpy(signal) print(f"Absolute Energy: {result}") # Output: Absolute Energy: 34 ``` ### Cara 3: Versi Singkat dengan NumPy ```python import numpy as np signal = np.array([2, -3, 4, 1, -2]) energy = np.sum(signal ** 2) print(f"Absolute Energy: {energy}") # Output: Absolute Energy: 34 ``` ### Cara 4: Menggunakan TSFEL ```python import tsfel import numpy as np # Data sinyal signal = np.array([2, -3, 4, 1, -2]) # Hitung absolute energy energy = tsfel.abs_energy(signal) print(f"Absolute Energy: {energy}") # Output: Absolute Energy: 34 ``` --- ## Interpretasi Absolute Energy ### Apa Arti Nilainya? | Nilai Energy | Interpretasi | |--------------|--------------| | Tinggi | Sinyal kuat, amplitudo besar, aktivitas tinggi | | Rendah | Sinyal lemah, amplitudo kecil, aktivitas rendah | | Nol | Tidak ada sinyal (semua nilai = 0) | ### Perbandingan Dua Sinyal: ```python # Sinyal 1: Tenang signal1 = [0.5, -0.3, 0.2, -0.1, 0.4] energy1 = sum([x**2 for x in signal1]) print(f"Energy Sinyal 1: {energy1:.3f}") # 0.550 # Sinyal 2: Aktif signal2 = [5, -8, 6, -3, 7] energy2 = sum([x**2 for x in signal2]) print(f"Energy Sinyal 2: {energy2}") # 183 # Sinyal 2 memiliki energy lebih tinggi → lebih aktif/kuat ``` --- ## Contoh Kasus Nyata ### 1. Analisis Sinyal Audio ```python import numpy as np # Sinyal audio tenang (bisikan) quiet_audio = np.array([0.1, -0.05, 0.08, -0.03, 0.02]) quiet_energy = np.sum(quiet_audio ** 2) # Sinyal audio keras (teriakan) loud_audio = np.array([0.8, -0.9, 0.7, -0.6, 0.85]) loud_energy = np.sum(loud_audio ** 2) print(f"Energy Audio Tenang: {quiet_energy:.4f}") print(f"Energy Audio Keras: {loud_energy:.4f}") print(f"Rasio: {loud_energy/quiet_energy:.1f}x lebih keras") ``` Output: ``` Energy Audio Tenang: 0.0198 Energy Audio Keras: 2.9200 Rasio: 147.5x lebih keras ``` ### 2. Deteksi Aktivitas pada Sensor Gerak (Accelerometer) ```python # Data accelerometer saat diam still = np.array([0.01, -0.02, 0.01, -0.01, 0.00]) still_energy = np.sum(still ** 2) # Data accelerometer saat bergerak moving = np.array([2.5, -3.2, 4.1, -2.8, 3.5]) moving_energy = np.sum(moving ** 2) print(f"Energy Diam: {still_energy:.5f}") print(f"Energy Bergerak: {moving_energy:.2f}") # Deteksi gerakan threshold = 10 if moving_energy > threshold: print("Status: BERGERAK") else: print("Status: DIAM") ``` ### 3. Analisis Sinyal EMG (Otot) ```python # Sinyal EMG saat otot rileks relaxed = np.array([0.1, 0.2, -0.1, 0.15, -0.05]) relaxed_energy = np.sum(relaxed ** 2) # Sinyal EMG saat otot kontraksi contracted = np.array([3.2, -4.5, 5.1, -3.8, 4.2]) contracted_energy = np.sum(contracted ** 2) print(f"Energy Rileks: {relaxed_energy:.3f}") print(f"Energy Kontraksi: {contracted_energy:.2f}") print(f"Tingkat kontraksi: {contracted_energy/relaxed_energy:.1f}x") ``` --- ## Absolute Energy vs Fitur Lainnya | Fitur | Formula | Kegunaan | |-------|---------|----------| | Absolute Energy | Σ(xi²) | Total kekuatan sinyal | | Average Power | Σ(xi²) / n | Rata-rata kekuatan per sampel | | RMS (Root Mean Square) | √(Σ(xi²) / n) | Amplitudo efektif | | Standard Deviation | √(Σ(xi-μ)² / n) | Variabilitas dari mean | ### Hubungan Matematika: ``` Average Power = Absolute Energy / n RMS = √(Average Power) ``` --- ## Visualisasi ```python import numpy as np import matplotlib.pyplot as plt # Buat tiga sinyal dengan energy berbeda t = np.linspace(0, 1, 100) signal_low = 0.5 * np.sin(2 * np.pi * 5 * t) signal_mid = 1.0 * np.sin(2 * np.pi * 5 * t) signal_high = 2.0 * np.sin(2 * np.pi * 5 * t) # Hitung energy energy_low = np.sum(signal_low ** 2) energy_mid = np.sum(signal_mid ** 2) energy_high = np.sum(signal_high ** 2) # Plot fig, axes = plt.subplots(3, 1, figsize=(10, 8)) axes[0].plot(t, signal_low) axes[0].set_title(f'Sinyal Rendah - Energy: {energy_low:.2f}') axes[0].grid(True) axes[1].plot(t, signal_mid) axes[1].set_title(f'Sinyal Sedang - Energy: {energy_mid:.2f}') axes[1].grid(True) axes[2].plot(t, signal_high) axes[2].set_title(f'Sinyal Tinggi - Energy: {energy_high:.2f}') axes[2].grid(True) plt.tight_layout() plt.show() ``` --- ## Mengapa Disebut "Absolute"? "Absolute" karena: 1. Semua nilai dikuadratkan → selalu positif 2. Tidak peduli arah (positif/negatif) → hanya besarnya 3. Mengukur total magnitude tanpa memperhatikan tanda Contoh: ``` Sinyal A: [5, -5] → Energy = 25 + 25 = 50 Sinyal B: [5, 5] → Energy = 25 + 25 = 50 ``` Kedua sinyal memiliki energy yang sama meskipun berbeda! --- ## Aplikasi Absolute Energy 1. **Audio Processing** - Deteksi kehadiran suara (Voice Activity Detection) - Mengukur volume/loudness 2. **Sensor Gerak (IMU)** - Deteksi aktivitas fisik - Klasifikasi gerakan 3. **Sinyal Biomedis** - EMG: Mengukur aktivitas otot - ECG: Deteksi abnormalitas jantung - EEG: Analisis aktivitas otak 4. **Machine Learning** - Feature untuk klasifikasi - Normalisasi sinyal --- **Rumus Singkat:** ``` Absolute Energy = Jumlahkan semua nilai kuadrat = x₁² + x₂² + x₃² + ... + xₙ² ```