feat(prediction): output 정상화 + dark 점수화 + transship 재설계 #23
No reviewers
레이블
레이블 없음
마일스톤 없음
담당자 없음
참여자 2명
알림
마감일
마감일이 설정되지 않았습니다.
의존성
No dependencies set.
Reference: gc/kcg-ai-monitoring#23
불러오는 중...
Reference in New Issue
Block a user
No description provided.
Delete Branch "fix/prediction-output-anomalies"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
변경 사항
prediction 출력 5종 이상 정상화 + dark 의심 점수화 재설계 + transship 베테랑 관점 재설계
커밋
0a4d023fix(prediction): output 5종 이상 정상화 (stats/event/lightweight)2e5d55afix(prediction): dark 판정에 한국 AIS 수신 영역 필터 추가e5d123efeat(prediction): dark 의심 점수화 + transship 베테랑 관점 재설계dac4a3bfix(prediction): features JSONB 중첩 구조 sanitizeb15a940docs: prediction 2차 개편 릴리즈 노트 + hourly snapshot 스크립트핵심 변경
1. 5종 출력 이상 정상화
2. Dark Vessel 의심 점수화 (0~100점)
3. Transshipment 베테랑 관점 재설계
테스트
5가지 출력 이상 동시 해결: 1. stats_aggregator (이상 1, 5) - aggregate_hourly에 by_category, by_zone JSON 집계 추가 - hour_start를 KST 기준으로 변경 (대시보드 표기와 boundary 일치) 2. event_generator 룰 정리 (이상 2, 3, 4) - critical_risk 임계값 90→70 (risk.py CRITICAL 분류와 일치) - territorial_sea_violation, contiguous_zone_high_risk, special_zone_entry 신설 (실측 zone_code: TERRITORIAL_SEA/CONTIGUOUS_ZONE/ZONE_*) - 잘못된 NLL/SPECIAL_FISHING_* 룰 제거 - HIGH_RISK_VESSEL 신규 카테고리 (50~69 MEDIUM, 70+ CRITICAL) - break 제거: 한 분석결과가 여러 카테고리에 동시 매칭 가능 3. dedup window prime 분산 (이상 5) - 30/60/120/360분 → 33/67/127/367분 - 5분 사이클 boundary와 LCM 회피하여 정시 일제 만료 패턴 완화 4. lightweight path 신호 보강 (이상 2, 3, 4 근본 해결) - vessel_store._tracks의 24h 누적 궤적으로 dark/spoof/speed_jump 산출 - 6,500 vessels(전체 93%)의 is_dark, spoofing_score가 비로소 채워짐 - compute_lightweight_risk_score에 dark gap, spoofing 가점 추가 (max 60→100 가능, CRITICAL 도달 가능) 시간 처리 원칙 적용: - DB 컬럼은 모두 timestamptz 확인 완료 - aggregate_hourly KST aware datetime 사용 - pandas Timestamp는 source-internal 비교만 (안전)12h 누적 분석 결과 dark/transship이 운영 불가 수준으로 판정되어 탐지 철학을 근본부터 전환. ## dark 재설계: 넓은 탐지 + 의도적 OFF 의심 점수화 기존 "필터 제외" 방식에서 "넓게 기록 + 점수 산출 + 등급별 알람"으로 전환. 해경 베테랑 관점의 8가지 패턴을 가점 합산하여 0~100점 산출. - P1 이동 중 OFF (gap 직전 SOG > 2kn) - P2 민감 수역 경계 근처 OFF (영해/접속수역/특정조업수역) - P3 반복 이력 (7일 내 재발) — 가장 강력 - P4 gap 후 이동거리 비정상 (은폐 이동) - P5 주간 조업 시간 OFF - P6 gap 직전 이상 행동 (teleport/급변) - P7 무허가 선박 가점 - P8 장기 gap (3h/6h 구간별) - 감점: gap 시작 위치가 한국 AIS 수신 커버리지 밖 완전 제외: - 어구 AIS (GEAR_PATTERN 매칭, fleet_tracker SSOT) - 한국 선박 (MMSI 440*, 441*) — 해경 관할 아님 등급: CRITICAL(70+) / HIGH(50~69) / WATCH(30~49) / NONE 이벤트는 HIGH 이상만 생성 (WATCH는 DB 저장만). 신규 함수: - algorithms/dark_vessel.py: analyze_dark_pattern, compute_dark_suspicion - scheduler.py: _is_dark_excluded, _fetch_dark_history (사이클당 1회 7일 이력 일괄 조회) pipeline path + lightweight path 모두 동일 로직 적용. 결과는 features JSONB에 {dark_suspicion_score, dark_patterns, dark_tier, dark_history_7d, dark_history_24h, gap_start_*} 저장. ## transship 재설계: 베테랑 함정근무자 기준 한정된 함정 자원으로 단속 출동을 결정할 수 있는 신뢰도 확보. 상수 재조정: - SOG_THRESHOLD_KN: 2.0 → 1.0 (완전 정박만) - PROXIMITY_DEG: 0.001 → 0.0007 (~77m) - SUSPECT_DURATION_MIN: 60 → 45 (gap tolerance 있음) - PAIR_EXPIRY_MIN: 120 → 180 - GAP_TOLERANCE_CYCLES: 2 신규 (GPS 노이즈 완화) 필수 조건 (모두 충족): - 한국 EEZ 관할 수역 이내 - 환적 불가 선종 제외 (passenger/military/tanker/pilot/tug/sar) - 어구 AIS 양쪽 제외 - 45분 이상 지속 (miss_count 2 사이클까지 용인) 점수 체계 (base 40): - 야간(KST 20~04): +15 - 무허가 가점: +20 - COG 편차 > 45°: +20 (나란히 가는 선단 배제) - 지속 ≥ 90분: +20 - 영해/접속수역 위치: +15 등급: CRITICAL(90+) / HIGH(70~89) / WATCH(50~69) WATCH는 저장 없이 로그만. HIGH/CRITICAL만 이벤트. pair_history 구조 확장: - 기존: {(a,b): datetime} - 신규: {(a,b): {'first_seen', 'last_seen', 'miss_count', 'last_lat/lon/cog_a/cog_b'}} - miss_count > GAP_TOLERANCE_CYCLES면 삭제 (즉시 리셋 아님) ## event_generator 룰 교체 - dark_vessel_long 룰 제거 → dark_critical, dark_high (features.dark_tier 기반) - transship 룰 제거 → transship_critical, transship_high (features.transship_tier 기반) - DEDUP: ILLEGAL_TRANSSHIP 67→181, DARK_VESSEL 127→131, ZONE_DEPARTURE 127→89 ## 공통 정리 - scheduler.py의 _gear_re 삭제, fleet_tracker.GEAR_PATTERN 단일 SSOT로 통합MR 승인 (via /mr skill)