- 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>
36 lines
1.4 KiB
Python
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
|