kcg-ai-monitoring/prediction/pipeline/resampler.py
htlee e2fc355b2c feat: S2 prediction 분석 엔진 모노레포 이식
iran prediction 47개 Python 파일을 prediction/ 디렉토리로 복제:
- algorithms/ 14개 분석 알고리즘 (어구추론, 다크베셀, 스푸핑, 환적, 위험도 등)
- pipeline/ 7단계 분류 파이프라인
- cache/vessel_store (24h 슬라이딩 윈도우)
- db/ 어댑터 (snpdb 원본조회, kcgdb 결과저장)
- chat/ AI 채팅 (Ollama, 후순위)
- data/ 정적 데이터 (기선, 특정어업수역 GeoJSON)

config.py를 kcgaidb로 재구성 (DB명, 사용자, 비밀번호)
DB 연결 검증 완료 (kcgaidb 37개 테이블 접근 확인)
Makefile에 dev-prediction / dev-all 타겟 추가
CLAUDE.md에 prediction 섹션 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 12:56:51 +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