0Pricing
AI Agents · Pelajaran

Pemrosesan Data Deret Waktu dalam Agen

Jendela bergulir, agregasi, dan deteksi anomali pada data sensor yang mengalir.

Pemrosesan Data Deret Waktu dalam Agen adalah pelajaran AI Agents gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Agents, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Agents mencakup 4 pelajaran total.

Deret Waktu pada Agen IoT

Data sensor hadir sebagai deret waktu: urutan pasangan (cap waktu, nilai). Pembacaan sensor mentah mengandung derau, celah, dan lonjakan sesekali. Agen yang bertindak berdasarkan data mentah tanpa pemrosesan sering memicu alarm palsu atau melewatkan peristiwa nyata.

Pemrosesan deret waktu mengubah sinyal mentah menjadi wawasan yang dapat ditindaklanjuti.

Membangun Penyangga Jendela Bergulir

Jendela bergulir hanya menyimpan N pembacaan terakhir di memori. Saat jendela penuh, pembacaan tertua dikeluarkan ketika pembacaan terbaru tiba. Ini menjadi dasar bagi semua analisis deret waktu pada agen.

from collections import deque
from datetime import datetime

class SensorBuffer:
    def __init__(self, window_size: int = 60):
        self.window_size = window_size
        self._data = deque(maxlen=window_size)

    def add(self, value: float, timestamp: datetime = None):
        ts = timestamp or datetime.utcnow()
        self._data.append({'ts': ts, 'value': value})

    def values(self) -> list:
        return [d['value'] for d in self._data]

    def timestamps(self) -> list:
        return [d['ts'] for d in self._data]

    def is_full(self) -> bool:
        return len(self._data) == self.window_size

buf = SensorBuffer(window_size=60)
buf.add(22.5)
buf.add(22.8)
buf.add(23.1)
print(f'Buffer: {len(buf._data)} readings, values: {buf.values()}')

Rata-Rata Bergerak

Rata-rata bergerak sederhana (SMA) menghaluskan derau dengan merata-ratakan N nilai terakhir. Cara ini mengurangi pengaruh gangguan sensor individual dan menampilkan tren yang mendasarinya. Gunakan sebagai garis dasar untuk deteksi anomali.

import statistics

def simple_moving_average(values: list, window: int = 10) -> list:
    if len(values) < window:
        return []
    return [
        statistics.mean(values[i - window:i])
        for i in range(window, len(values) + 1)
    ]

def exponential_moving_average(values: list, alpha: float = 0.2) -> list:
    """EMA weights recent values more heavily."""
    if not values:
        return []
    ema = [values[0]]
    for v in values[1:]:
        ema.append(alpha * v + (1 - alpha) * ema[-1])
    return ema

readings = [22.1, 22.3, 22.0, 35.0, 22.2, 22.4, 22.1, 22.3, 22.5, 22.2, 22.4]
sma = simple_moving_average(readings, window=5)
ema = exponential_moving_average(readings, alpha=0.2)
print(f'SMA (last 3): {[round(v,2) for v in sma[-3:]]}')
print(f'EMA (last 3): {[round(v,2) for v in ema[-3:]]}')

Deteksi Lonjakan

Lonjakan adalah pembacaan yang menyimpang dari tren terkini lebih dari N simpangan baku (metode skor-z). Ini merupakan pendekatan deteksi anomali yang paling umum untuk data sensor.

import statistics

def detect_spikes(
    values: list,
    window: int = 20,
    z_threshold: float = 3.0
) -> list:
    """Returns list of (index, value, z_score) for detected spikes."""
    if len(values) < window:
        return []

    spikes = []
    for i in range(window, len(values)):
        window_vals = values[i - window:i]
        mean = statistics.mean(window_vals)
        stdev = statistics.stdev(window_vals)
        if stdev == 0:
            continue
        z_score = abs(values[i] - mean) / stdev
        if z_score > z_threshold:
            spikes.append({
                'index': i,
                'value': values[i],
                'z_score': round(z_score, 2),
                'mean': round(mean, 2)
            })
    return spikes

data = [22.1, 22.3, 22.0, 22.2, 22.4] * 5 + [55.0] + [22.2, 22.3] * 3
spikes = detect_spikes(data, window=10, z_threshold=3.0)
print('Spikes detected:', spikes)

Pandas untuk Analisis Deret Waktu

Untuk analisis yang lebih canggih, muat data sensor ke dalam pandas DataFrame dengan DatetimeIndex. Pandas menyediakan operasi bawaan untuk jendela bergulir, pengambilan sampel ulang, dan interpolasi yang jauh lebih cepat ditulis daripada perulangan manual.

import pandas as pd
from datetime import datetime, timedelta

# Create a sample time series DataFrame
base_time = datetime(2024, 1, 1, 12, 0, 0)
times = [base_time + timedelta(seconds=i*10) for i in range(20)]
values = [22.1, 22.3, None, 22.0, 22.4, 22.2, 35.0, 22.1,
          22.3, 22.2, 22.5, 22.1, None, 22.4, 22.2, 22.3,
          22.0, 22.1, 22.4, 22.2]

df = pd.DataFrame({'value': values}, index=pd.DatetimeIndex(times))
df.index.name = 'timestamp'

print('Shape:', df.shape)
print('Missing values:', df['value'].isna().sum())
print(df.head())

Menangani Cap Waktu yang Hilang

Jaringan sensor sering melewatkan pembacaan akibat masalah konektivitas. Pandas dapat mendeteksi dan mengisi celah: resample membuat kisi reguler, sedangkan interpolate mengisi nilai yang hilang secara linear atau dengan pengisian maju. Selalu catat berapa banyak nilai yang diimputasi.

import pandas as pd

def fill_missing_readings(df: pd.DataFrame, freq: str = '10S') -> pd.DataFrame:
    """
    df: DataFrame with DatetimeIndex and 'value' column
    freq: expected sampling frequency ('10S' = 10 seconds, '1T' = 1 minute)
    """
    original_count = df['value'].notna().sum()

    # Resample to regular grid (introduces NaN for missing periods)
    df_regular = df.resample(freq).mean()

    missing_count = df_regular['value'].isna().sum()
    print(f'Missing readings before fill: {missing_count}')

    # Forward fill then linear interpolate
    df_regular['value'] = df_regular['value'].interpolate(
        method='linear', limit=5  # don't fill gaps longer than 5 periods
    )

    filled_count = df_regular['value'].notna().sum()
    print(f'Filled {filled_count - original_count} missing values')
    return df_regular

Pengambilan Sampel Ulang: Agregasi 1 Menit menjadi 5 Menit

Pengambilan sampel ulang menurunkan data berfrekuensi tinggi ke resolusi yang lebih kasar. Cara ini mengurangi derau dan kebutuhan penyimpanan. Gunakan resample('5T').agg() untuk menghitung nilai minimum, maksimum, mean, dan simpangan baku pada setiap jendela 5 menit.

import pandas as pd

def resample_to_5min(df: pd.DataFrame) -> pd.DataFrame:
    return df.resample('5min').agg({
        'value': ['mean', 'min', 'max', 'std', 'count']
    }).round(3)

# Example with 1-minute data:
times = pd.date_range('2024-01-01 12:00', periods=30, freq='1min')
import random
random.seed(42)
vals = [22.0 + random.gauss(0, 0.5) for _ in range(30)]
df_1min = pd.DataFrame({'value': vals}, index=times)

df_5min = resample_to_5min(df_1min)
print(df_5min)

Deteksi Tren dengan Regresi Linear

Apakah suhu terus meningkat atau hanya berderau? Sesuaikan regresi linear pada jendela bergulir. Kemiringan positif menunjukkan tren naik; kemiringan yang melebihi ambang batas memicu peringatan bahkan sebelum ambang batas tersebut tercapai.

def detect_trend(
    values: list,
    slope_threshold: float = 0.1  # units per second
) -> dict:
    import statistics
    n = len(values)
    if n < 2:
        return {'trend': 'insufficient_data'}

    x = list(range(n))
    x_mean = statistics.mean(x)
    y_mean = statistics.mean(values)

    numerator = sum((xi - x_mean) * (yi - y_mean) for xi, yi in zip(x, values))
    denominator = sum((xi - x_mean) ** 2 for xi in x)
    slope = numerator / denominator if denominator != 0 else 0.0

    return {
        'slope': round(slope, 4),
        'trend': 'rising' if slope > slope_threshold
                 else 'falling' if slope < -slope_threshold
                 else 'stable',
        'alert': abs(slope) > slope_threshold * 2
    }

readings = [22.0, 22.5, 23.0, 23.5, 24.0, 24.5, 25.0]
print(detect_trend(readings, slope_threshold=0.3))

Keputusan Agen dari Deret Waktu

Gabungkan deteksi lonjakan, deteksi tren, dan rata-rata bergerak untuk membuat keputusan komposit. Agen menggunakan hierarki aturan: lonjakan memicu tindakan segera, tren memicu peringatan, dan LLM menangani kasus yang ambigu.

def analyze_sensor_window(
    values: list,
    topic: str
) -> dict:
    if len(values) < 10:
        return {'action': 'collecting_data'}

    spikes = detect_spikes(values, window=10, z_threshold=3.0)
    trend_info = detect_trend(values[-20:], slope_threshold=0.2)
    avg = sum(values[-10:]) / 10

    if spikes:
        return {
            'action': 'IMMEDIATE_ALERT',
            'reason': f'Spike detected: {spikes[-1]["value"]} (z={spikes[-1]["z_score"]})',
            'severity': 'high'
        }
    if trend_info['alert']:
        return {
            'action': 'TREND_WARNING',
            'reason': f'Rapid {trend_info["trend"]} trend: slope={trend_info["slope"]}',
            'severity': 'medium'
        }
    return {
        'action': 'NORMAL',
        'avg_last_10': round(avg, 2),
        'trend': trend_info['trend']
    }

result = analyze_sensor_window([22.0]*15 + [55.0], 'sensors/temp')
print(result)

Menyimpan Deret Waktu ke Basis Data

Untuk analisis jangka panjang, simpan pembacaan sensor secara permanen ke basis data deret waktu. TimescaleDB (ekstensi PostgreSQL) dan InfluxDB adalah pilihan yang populer. Menggunakan psycopg2 dengan TimescaleDB memungkinkan Anda membuat kueri data menggunakan SQL standar beserta fungsi khusus waktu.

import psycopg2
from datetime import datetime

# TimescaleDB connection (standard PostgreSQL connection)
conn = psycopg2.connect(
    host='localhost', port=5432, dbname='iot',
    user='agent', password='YOUR_DB_PASSWORD'
)

def insert_reading(topic: str, value: float, ts: datetime = None):
    ts = ts or datetime.utcnow()
    with conn.cursor() as cur:
        cur.execute(
            'INSERT INTO sensor_readings (time, topic, value) VALUES (%s, %s, %s)',
            (ts, topic, value)
        )
    conn.commit()

def query_last_hour(topic: str) -> list:
    with conn.cursor() as cur:
        cur.execute(
            'SELECT time, value FROM sensor_readings '
            'WHERE topic=%s AND time > NOW() - INTERVAL \'1 hour\' '
            'ORDER BY time ASC',
            (topic,)
        )
        return cur.fetchall()

Periode Masa Jeda Peringatan

Tanpa masa jeda, anomali yang berlangsung lama dapat memicu ratusan peringatan per menit. Terapkan masa jeda per topik: setelah peringatan dikirim untuk suatu topik, tekan peringatan berikutnya untuk topik tersebut selama N detik.

from datetime import datetime, timedelta

class AlertCooldownManager:
    def __init__(self, cooldown_seconds: int = 300):
        self.cooldown_seconds = cooldown_seconds
        self._last_alert: dict = {}  # topic -> last alert datetime

    def should_alert(self, topic: str) -> bool:
        last = self._last_alert.get(topic)
        if last is None:
            return True
        return (datetime.utcnow() - last).seconds >= self.cooldown_seconds

    def mark_alerted(self, topic: str):
        self._last_alert[topic] = datetime.utcnow()

    def cooldown_remaining(self, topic: str) -> int:
        last = self._last_alert.get(topic)
        if last is None:
            return 0
        elapsed = (datetime.utcnow() - last).seconds
        return max(0, self.cooldown_seconds - elapsed)

cooldown = AlertCooldownManager(cooldown_seconds=300)
if cooldown.should_alert('sensors/temperature'):
    print('Sending alert')
    cooldown.mark_alerted('sensors/temperature')
else:
    print(f'Cooldown: {cooldown.cooldown_remaining("sensors/temperature")}s remaining')

Uji Pemahaman

Apa yang ditunjukkan oleh skor-z di atas 3,0 saat digunakan untuk mendeteksi lonjakan?

Ringkasan: Pemrosesan Data Deret Waktu

Anda telah mempelajari perangkat lengkap untuk pemrosesan deret waktu pada agen:

  • Penyangga jendela bergulir: deque dengan maxlen untuk streaming yang hemat memori
  • Rata-rata bergerak: SMA dan EMA untuk mengurangi derau
  • Deteksi lonjakan: metode skor-z berdasarkan statistik jendela bergulir
  • Pandas: resample, interpolate, dan agregasi dengan DatetimeIndex
  • Deteksi tren: kemiringan regresi linear untuk peringatan dini
  • Masa jeda peringatan: menekan peringatan berulang untuk anomali yang berlangsung lama

Berikutnya: respons agen otomatis terhadap peristiwa sensor — antrean tindakan, deduplikasi, dan kebijakan tindakan.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Pemrosesan Data Deret Waktu dalam Agen” gratis?

Ya — teks lengkap “Pemrosesan Data Deret Waktu dalam Agen” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Agents, upgrade ke CoddyKit PRO. Kursus AI Agents mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Pemrosesan Data Deret Waktu dalam Agen”?

Jendela bergulir, agregasi, dan deteksi anomali pada data sensor yang mengalir. Kamu berlatih AI Agents dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai AI Agents?

Tidak diperlukan pengalaman sebelumnya. AI Agents di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.

Berapa lama pelajaran “Pemrosesan Data Deret Waktu dalam Agen” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Agents ini?

Ya. Setiap pelajaran AI Agents menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Protokol MQTT untuk Integrasi Agen
  2. Pemrosesan Data Deret Waktu dalam Agen
  3. Respons Otomatis terhadap Peristiwa Sensor
  4. Penerapan Agen Ringan di Perangkat Tepi
← Kembali ke AI Agents