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>
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
|