kcg-monitoring/prediction/pipeline/resampler.py
htlee 83b3d80c6d feat: Python 어선 분류기 + 배포 설정 + 백엔드 모니터링 프록시
- prediction/: FastAPI 7단계 분류 파이프라인 + 6개 탐지 알고리즘
  - snpdb 궤적 조회 → 인메모리 캐시(13K척) → 분류 → kcgdb 저장
  - APScheduler 5분 주기, Python 3.9 호환
  - 버그 수정: @property last_bucket, SQL INTERVAL 바인딩, rollback, None 가드
  - 보안: DB 비밀번호 하드코딩 제거 → env 환경변수 필수
- deploy/kcg-prediction.service: systemd 서비스 (redis-211, 포트 8001)
- deploy.yml: prediction CI/CD 배포 단계 추가 (192.168.1.18:32023)
- backend: PredictionProxyController (health/status/trigger 프록시)
- backend: AppProperties predictionBaseUrl + AuthFilter 인증 예외

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 12:07:40 +09:00

36 lines
1.4 KiB
Python

import pandas as pd
from pipeline.constants import RESAMPLE_INTERVAL_MIN
from pipeline.behavior import BehaviorDetector
class TrajectoryResampler:
"""
불균등 AIS 수신 간격을 균등 시간 간격으로 보간
목적: BIRCH 군집화의 입력 벡터 정규화
방법: 선형 보간 (위도·경도·SOG·COG)
기준: 4분 간격 (Shepperson et al. 2017)
"""
def __init__(self, interval_min: int = RESAMPLE_INTERVAL_MIN):
self.interval = pd.Timedelta(minutes=interval_min)
def resample(self, df_vessel: pd.DataFrame) -> pd.DataFrame:
df_vessel = df_vessel.sort_values('timestamp').copy()
if len(df_vessel) < 2:
return df_vessel
t_start = df_vessel['timestamp'].iloc[0]
t_end = df_vessel['timestamp'].iloc[-1]
new_times = pd.date_range(t_start, t_end, freq=self.interval)
df_vessel = df_vessel.set_index('timestamp')
df_vessel = df_vessel.reindex(df_vessel.index.union(new_times))
for col in ['lat', 'lon', 'sog', 'cog']:
if col in df_vessel.columns:
df_vessel[col] = df_vessel[col].interpolate(method='time')
df_vessel = df_vessel.loc[new_times].reset_index()
df_vessel.rename(columns={'index': 'timestamp'}, inplace=True)
df_vessel['state'] = df_vessel['sog'].apply(BehaviorDetector.classify_point)
return df_vessel