kcg-monitoring/prediction/pipeline/behavior.py
htlee a68dfb21b2 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:10:21 +09:00

32 lines
929 B
Python

import pandas as pd
from pipeline.constants import SOG_STATIONARY_MAX, SOG_FISHING_MAX
class BehaviorDetector:
"""
속도 기반 3단계 행동 분류 (Yan et al. 2022, Natale et al. 2015)
정박(STATIONARY) / 조업(FISHING) / 항행(SAILING)
"""
@staticmethod
def classify_point(sog: float) -> str:
if sog < SOG_STATIONARY_MAX:
return 'STATIONARY'
elif sog <= SOG_FISHING_MAX:
return 'FISHING'
else:
return 'SAILING'
def detect(self, df: pd.DataFrame) -> pd.DataFrame:
df = df.copy()
df['state'] = df['sog'].apply(self.classify_point)
return df
@staticmethod
def compute_fishing_ratio(df_vessel: pd.DataFrame) -> float:
total = len(df_vessel)
if total == 0:
return 0.0
fishing = (df_vessel['state'] == 'FISHING').sum()
return round(fishing / total * 100, 2)