2026 AX 아이디어 공모전 도전기

Mini·2026년 7월 7일

공모전

목록 보기
13/13
post-thumbnail

대회 소개

2026년도 기후에너지환경부가 주최한 AX(AI Transformation) 아이디어 경진대회에 참가했다. 부문은 자유분석이 아니라 지정분석이었는데, 이 대회의 지정분석은 한 기관이 아니라 12개 공공기관이 각자 자기 실무 문제를 과제로 내놓는 방식이었다. 국립공원공단은 해안 해양쓰레기 유입 예측을, 한강홍수통제소는 AI 기반 하천 수위 예측과 디지털트윈을, 한국남동발전과 서부발전은 발전소 대기오염물질 배출 최적화를, 한국남부발전은 배출권 가격 예측을, 한국동서발전은 제주 SMP 예측을, 한국원자력환경공단은 처분시설 국지성 기상 예측을, 한국전력공사는 전기요금 과다발생 사전 예측을, 한국지역난방공사는 열사용 이상 탐지를, 한국환경공단과 환경산업기술원은 각각 공급망 분석과 생활화학제품 안전관리 진단을 내놓았다. 그리고 그중에 한국수자원공사가 낸 과제가 있었다.

조류경보 예측 AI 모델 개발 — 대청댐 수질·수문·기상 정보를 바탕으로 유해남조류 발생 및 경보 발령 시점을 예측하고, 녹조 발생 주요 영향 인자를 도출해 사전 시나리오 기반 의사결정 지원체계를 구축한다.

처음 과제 목록을 쭉 훑어볼 때는 이것저것 하고싶어서 고민이 많았다. 그래서 우리는 각자 하고 싶은 주제를 선택해 간단하게 기획서를 작성해 회의때 발표를 진행해서 더 많이 설득되고 좋은 주제에 투표해 많은 투표를 받은 주제를 선정하게 되었다. 그래서 우리 팀은 다애님이 조사해주셨던 수자원공사의 조류경보 과제를 골랐다. 수자원공사는 대청댐의 수질·수문 관측자료를 10개년치 그대로 지정과제 데이터로 제공해줬는데, 이걸 어떻게 가공하고 무엇과 엮어야 진짜 예측이 될지는 온전히 우리 몫이었다.

팀명은 춘배, 팀원은 나(김경민)를 포함해 최현준, 김다애(성현석님은 취업으로 인해 불참하게 되었다) 세 명이었다. 우리가 최종적으로 잡은 과제명은 다음과 같다.

대청댐 유해남조류 선제적 대응을 위한 자율형 의사결정 지원 시스템 구축


조사를 시작하며 확신이 생긴 이유

수자원공사 과제를 고르고 조사를 시작하면서, 이 주제를 선택하길 잘했다는 확신이 점점 커진 이유가 세 가지 있었다.

첫째, 매년 반복되는 사회적 이슈라는 점이다. 국립환경과학원이 조류경보제 지점을 9곳에서 13곳으로, 2030년까지 28곳으로 늘리겠다고 밝힌 걸 확인했다. 정부가 이미 이 문제에 예산과 정책 우선순위를 두고 있다는 신호였고, 우리 아이디어가 허공에 뜬 상상이 아니라 실제 정책 흐름 위에 올라탈 수 있다는 뜻이기도 했다.

둘째, 대청댐 자체의 상징성이다. 대청호는 1998년 팔당호·충주호·주암호와 함께 국내 조류경보제가 최초로 도입된 4개 호소 중 하나다. 조류경보제의 "원조"격인 곳에서, 제도가 확대되어온 20여 년 동안 실제로 무엇이 바뀌었는지 들여다볼 가치가 있다고 판단했다.

셋째, 조사를 하면 할수록 현행 제도의 구조적 한계가 명확하게 보였다는 점이다. 조류경보제 운영지침을 읽어보니 발령 기준 자체가 "2회 연속 유해남조류 세포수가 기준을 초과할 때"였다. 첫 번째 초과가 확인되고서도 두 번째 채수 결과가 나올 때까지 기다려야 하는 구조다. 대청호 문의 수역에서 2023년 8월 30일 경계 단계가 발령된 사례를 역추적해보니, 관측 이후 실제 공식 대응까지 이어지는 데 최소 한 번의 채수 간격만큼, 체감상 열흘 가까운 행정 지연이 있었다.

"이미 나온 결과를 처리하는 시스템은 이미 있다. 데이터도 충분하지만 발생하고 나서 대응하는 방식이다. 우리가 이걸 미리 예측하고 예방한다면 도움이 되지 않을까?"

이 질문 하나로 방향을 잡았다. 그리고 처음부터 이걸 "발령 이전 단계를 보완하는 시스템"으로 포지셔닝하기로 팀 내에서 얘기가 나왔다.


제공된 데이터를 진짜 쓸모 있게 만드는 과정

수자원공사가 준 것, 우리가 채워야 했던 것


지정과제 공고에는 수자원공사가 제공하는 데이터 항목이 명확히 적혀 있었다. 대청댐 수질정보(최근 10개년, 주 단위 — 지점명, 채수위치, 조사일, 수온, pH, DO, 투명도, 탁도, Chl-a, 발령단계, 유해남조류 세포수와 4종별 세포수)와 대청댐 운영 수문정보(최근 10개년 — 날짜, 댐수위, 일유입량, 일방류량), 그리고 기상청 자료로 "날씨, 일조시간 합계, 일강수량" 정도가 함께 제공됐다. 즉 우리가 맨땅에서 대청댐 데이터를 수소문한 게 아니라, 애초에 이 세 축이 지정과제의 재료로 주어져 있었다.

문제는 공고에 적힌 기상 항목이 "날씨, 일조시간 합계, 일강수량" 정도로 꽤 단출했다는 점이다. 녹조 발생 메커니즘을 제대로 설명하려면 기온, 풍속, 일사량, 지면온도 같은 변수가 더 필요했다. 그래서 이 부분만큼은 우리가 직접 채워 넣어야 했다. 기상자료개발포털(data.kma.go.kr)을 뒤지고, 금강홍수통제소 사이트도 참고하면서 다음 관측망을 추가로 확보했다.

  • ASOS(종관기상관측): 국가 공식 기후 자료로서 대표성을 갖는다. 대청호 유역과 관련된 보은(226, 회남 상류), 대전(133, 문의·추동 중하류), 청주(131, 문의 북측) 지점을 골랐다.
  • AWS(방재기상관측): 위험 기상을 실시간으로 감시하는 데 주목적이 있어 지역성이 강하다. 청남대(888), 장동(648), 세천(643), 옥천(605/604) 지점을 썼다.

이 두 관측망의 성격이 다르다는 걸 이해하는 데도 시간이 좀 걸렸다. ASOS는 국가 대표 통계용이라 신뢰도는 높지만 지점 수가 적고, AWS는 촘촘하게 깔려 있지만 방재 목적이라 관측 항목이 더 단순했다(AWS는 일 자료 기준으로 평균기온·일강수량·평균풍속 정도만 뽑을 수 있었고, ASOS에는 일사량과 지면온도까지 있었다).

시간별 자료의 컬럼 하나하나도 다 뜯어봤다. 기온·이슬점온도·지면온도·5cm/10cm/20cm/30cm 지중온도, 강수량·적설·습도·증기압, 풍속·풍향·현지기압·해면기압, 일조·일사·전운량·중하층운량·운형·최저운고·시정, 지면상태·현상번호까지.


남조류가 왜, 어떻게 자라는지부터 공부해야 했다

기상 변수를 고르기 전에 먼저 "남조류가 왜 대발생하는가"를 생물학적으로 이해해야 했다. 이 부분은 정말 논문과 많은 자료, 운영지침을 오가며 시간을 많이 썼다. 정리하면 4대 메커니즘으로 요약된다.

1. 온도 메커니즘: 남조류는 대표적인 고온성 생물이다. 기온이 수온을 결정하는 가장 큰 요인이고, 특히 25°C 이상 고온이 유지되는 기간이 핵심이다. 다만 물은 공기보다 늦게 데워지고 늦게 식기 때문에(수온 관성), 당일 기온보다 최근 7일간 누적된 기온과 지열이 더 정확한 신호였다.

2. 광합성 메커니즘: 조류는 광합성으로 증식하므로, 단순히 해가 떠 있던 시간(일조시간)보다 실제 수면에 도달한 태양 에너지 총량(일사량)이 훨씬 정확한 설명 변수였다.

3. 영양염류 유입 메커니즘: 비는 유역의 질소·인 같은 영양분을 댐으로 실어 나르는 '먹이 공급원'이다. 다만 폭우는 오히려 조류를 씻어내리는(세굴) 효과가 있어서, 강수량의 강도와 지속 시간을 함께 봐야 했다.

4. 수직 안정도(성층) 메커니즘: 풍속이 낮을수록(대략 2m/s 미만) 물이 위아래로 섞이지 않는 '성층 현상'이 생기고, 이때 부력을 조절할 수 있는 남조류가 표층으로 떠올라 대발생하기 좋은 환경이 된다.

여기서 더 들어가서, 종별로 특성이 다르다는 것도 알게 됐다. 이게 나중에 우리 프로젝트의 중요한 차별점이 됐다.

  • Microcystis: 국내에서 가장 흔한 녹조 주범. 간 독소(Microcystin) 생성. 고온(25°C 이상)과 강한 햇빛을 좋아하고, 스스로 부력을 조절해 표층으로 떠오르는 능력이 탁월하다.
  • Anabaena(Dolichospermum): 냄새 유발 물질을 만들고, 질소를 스스로 고정할 수 있어 질소가 부족해도 잘 자란다. 인 농도는 높은데 질소가 부족한 조건에서 우점 가능성이 커진다.
  • Oscillatoria: 다른 종보다 낮은 온도와 적은 빛에서도 견딘다. 초여름·늦가을에도 나타날 수 있어, 수온이 완전히 오르지 않은 시기의 증가는 이 종이 원인일 가능성이 있다.
  • Aphanizomenon: Microcystis가 힘을 못 쓰는 고온기가 아니라, 기온이 오르기 시작하는 초여름이나 찬바람이 부는 늦가을에 주로 번성한다. 계절성이 뚜렷해서 월(Month)이나 계절 변수가 중요한 힌트가 된다.

대청호는 다른 호수와 뭐가 다른가

대청호만의 특수성도 따로 파고들었다. 언뜻 "체류시간이 길면 녹조가 심하다"는 단순한 공식이 통할 것 같았지만, 실제로 찾아보니 그렇게 단순하지 않았다. 예를 들어 소양호는 체류시간이 긴데도 TSI(부영양화 지수) 기준으로 빈영양 호수로 분류된다는 신문 기사(중앙일보)를 발견했다. 즉 체류시간만으로는 설명이 안 되고, 질소·인 오염원의 유입량과 고온다습한 기후가 함께 맞물려야 한다는 걸 확인했다.

그리고 대청호 특유의 지형적 문제도 찾아냈다. 관련 논문(「대청호 상류유역의 오염원 현황과 수질관리 방안에 관한 연구: 안남천과 안내천을 중심으로」, 「소옥천 유역의 오염제어 대책에 따른 대청호 조류저감 효과 분석」)을 보면, 대청호는 본류보다 소옥천 같은 지류·만입부의 오염 기여도가 크다는 게 드러난다. 소옥천 유역 연구에서는 축산분뇨 에너지화와 표준시비량 적용이 가장 수질개선 효율이 높다는 시뮬레이션 결과(CE-QUAL-W2 모형)도 확인했다.

또한 대청호는 자연호가 아니라 길고 구불구불한 인공저수지라는 점도 중요했다. 이 구조 때문에 조류 발생이 계절 변수만으로 설명되지 않고, 방류 운영·체류시간 변화·지류 유입부의 국지적 오염에 크게 좌우된다는 사실을 알게 됐다. 그래서 우리는 자연호에서 쓰는 범용 모델을 그대로 가져오는 대신, 수리 변수(수위·방류량·유입량·체류시간)와 공간 분리(수역별 모델링)를 중심에 둔 대청호 전용 접근이 필요하다고 판단했다.


제공 데이터를 자동으로 갱신하는 파이프라인 만들기

수자원공사가 넘겨준 수질·수문 데이터는 정적인 엑셀 파일 형태였다. 이걸 한 번 받아서 끝내는 게 아니라, 같은 출처에서 최신 구간까지 자동으로 이어붙이고 재현 가능하게 관리하고 싶어서 공공데이터포털의 대청댐 수문 운영 정보 API부터 먼저 시도했다. 그리고 대청댐 수질정보·수문정보 공개 페이지를 직접 크롤링하는 쪽으로 방향을 틀었다.

개발자도구로 페이지의 고유 div-id를 확인하고, Selenium으로 연도별 구간을 순회하며 엑셀을 내려받는 자동화 스크립트(water_gate.py, water_quality.py)를 직접 짰다. 수문 데이터는 dam_select0, dam_select1 같은 select 엘리먼트를 자바스크립트로 조작해서 대청댐을 선택하고, 시작일·종료일을 넣은 뒤 fnObj.hydrExcelDown() 같은 페이지 내부 함수를 직접 호출하는 방식으로 다운로드를 자동화했다. 다운로드 중간에 예상치 못한 alert 창이 뜨는 경우도 있어서 재시도 로직도 넣어야 했다. 이렇게 만든 파이프라인 덕분에 수자원공사가 준 기준 데이터에, 우리가 직접 확보한 최신 기상 데이터를 결합해 하나의 최종 데이터셋으로 관리할 수 있었다.


결측치는 어떻게 처리했나

10개년 데이터를 통으로 쓰다 보니 결측 구간도 있었다. 2016년 1월부터 3월까지는 주요 수질 지표가 장기간 결측되어 있어서, 억지로 채우는 대신 그 구간 자체를 학습에서 제외했다. 일강수량(daily_rain)의 결측은 성격이 달랐는데, 관측소에서 비가 오지 않아 애초에 기록되지 않은 경우로 판단해서 일괄적으로 0으로 대체했다. 반면 평균·최저·최고기온과 평균풍속은 시계열 특성이 있는 변수라, 전후 날짜 값으로 선형보간(Linear Interpolation)해서 자연스러운 흐름을 유지했다. 이렇게 정리한 뒤 최종적으로 확보한 데이터 규모는 2016년 4월부터 2025년 12월까지, 6,304행 × 57컬럼, 결측치 0건, 중복 키 0건이었다.


불규칙한 채수 주기, 그리고 슬라이딩 윈도우

데이터를 다 모으고 나서도 진짜 문제는 그다음이었다. 수질 채수일이 월요일이었다가 목요일로 바뀌고, 주 1회였다가 2회로 늘어나는 식으로 불규칙했다. 처음엔 이게 그냥 현장 사정인 줄 알았는데, 나중에 「조류예측 및 수질관리협의회에 관한 규정」 제8조를 읽고서야 이유를 알았다. 조류예측 정보는 "주 2회(월요일과 목요일) 17시에 발표"하되, 유해남조류 세포수가 상수원구간 기준 10,000 세포/mL를 하루라도 초과하면 매 근무일마다 발표하도록 되어 있었다. 즉 우리를 힘들게 했던 불규칙성 자체가 이미 정책적으로 설계된 결과였던 것이다.

이 불규칙성을 다루기 위해 채택한 방법이 "이벤트 중심 샘플링(Event-based Sampling)"이다. 날짜(달력) 기준이 아니라 '채수 이벤트(정답지가 있는 날)'를 닻(Anchor)으로 삼고, 그 과거로 창문(Window)을 던져 데이터를 긁어오는 방식이다.

  • 단기 윈도우(T-3일): 비 온 직후의 희석 효과, 급격한 폭염 같은 조류의 즉각적인 반응을 포착
  • 장기 윈도우(T-7일~T-14일): 영양염류 축적, 물의 정체 상태 같은 댐의 기저 환경을 포착

이 방식의 핵심은, 채수 간격이 며칠이든 상관없이 모델은 항상 "결과가 나오기 직전 N일 동안 누적된 환경"이라는 일관된 패턴을 학습한다는 점이다. 그리고 학습할 때와 운영할 때의 논리가 다르다는 것도 중요한 설계 포인트였다. 학습 시에는 정답(실측 세포수)이 있는 채수일을 기준으로 과거 데이터를 묶어 공부하지만, 실제 운영 시에는 정답지가 없어도 된다. 매일매일 윈도우를 굴리며 예측을 수행할 수 있기 때문이다.

변수별 가공 방식도 성격에 따라 다르게 설계했다.

  • 기온: 평균과 최대값을 함께 본다. 7일 평균기온이 전반적인 더위를, 3일 최고기온의 평균이 폭염 강도를 나타낸다.
  • 일사량: 합계(누적)를 쓴다. 남조류 증식은 태양 에너지가 누적되어야 폭발하기 때문에 평균보다 합계가 생물학적으로 더 정확하다.
  • 강수량: 합계와 특정 시점 값(Lag)을 함께 쓴다. 3일 누적강수량과 T-7일 단일 강수량을 따로 변수화했다.
  • 풍속: 조건 만족 일수를 카운트한다. 풍속 자체의 평균은 의미가 희석되므로, "2m/s 이하가 며칠 지속되었는가"를 세는 방식이 훨씬 유의미했다.
  • 수위·저수율: 절대값보다 변동폭(Delta)이 중요하다. 오늘 수위에서 7일 전 수위를 뺀 값으로 물이 차오르는지 빠지는지를 봤다.
  • 유입량·방류량: 상호작용 변수로 만들었다. 체류시간(Retention Time) = 저수량 / 일평균 방류량. 이 값이 클수록 물이 오래 고여 있다는 뜻이고, 조류 예측에서 가장 강력한 변수 중 하나가 됐다.

수질 자료(채수 데이터)는 매일 있는 게 아니므로 윈도우로 묶을 수 없었다. 대신 "직전 채수일(T-1)의 상태"를 오늘(T)의 결과를 예측하는 힌트로 썼다. 탁도 증가율(T-2 대비 T-1의 탁도 급증)은 비가 와서 오염물이 들어왔다는 강력한 증거로 활용했고, pH도 흥미로운 변수였다. 낮에는 광합성이 활발해서 CO₂가 줄고 pH가 오르며, 밤에는 호흡 작용으로 반대가 된다. 이 동조 현상 때문에 pH 변화량 자체가 녹조 발생의 현재 증거로 쓰일 수 있었다.


정책 문서를 조문 단위로 읽다

발령기준모니터링 프로세스

「조류예측 및 수질관리협의회에 관한 규정」을 조문 하나하나 짚어가며 우리 모델과 어떻게 연결되는지 정리했다.

  • 제4조(조류예측 기간): "발표일로부터 7일간" → 우리 모델의 예측 시점(next_log_cells, 7일 후)을 정책 언어에 그대로 맞출 수 있는 근거였다.
  • 제5조(조류예측 항목): 수온, 유해남조류세포수, 기타 필요사항 → 우리는 수온을 주요 입력 변수로, 유해남조류세포수를 회귀·분류 타깃으로 정확히 대응시켰다.
  • 제6조(분석자료): 수치모델링 예측 결과, 기상·수질·유량·위성영상 등 관측자료 → 우리가 수질만 보지 않고 기상·댐 운영 데이터까지 통합한 이유가 여기 있었다.
  • 제7조(조류예측구간): 금강은 대청호부터 금강 하구언까지 → 대청호가 이미 법정 예측구간에 포함되어 있다는 걸 확인.
  • 제8조(조류예측 발표): 5월~10월 발표, 주 2회(월·목) 17시 발표 → 앞서 언급한 채수 불규칙성의 원인.
  • 제10조(사후평가): 매년 1월 사후평가 실시 → 우리 프로젝트의 baseline 대비 성능 개선 검증 로직과 대응시켰다.
  • 제15조(협의회 협의 사항): 단계별 대응조치, 관계기관 상호 의견조정, 비상연락체계 → 우리가 만든 "시나리오 기반 의사결정 지원 체계"가 실제로 연결될 수 있는 제도적 지점이었다.

「물환경보전법 시행령」도 함께 봤고, 2025년 정부 보도자료(「2025년 여름철 녹조 대응」)도 꼼꼼히 읽었다. 여기서 정부가 이미 영양염류 유입 최소화 → 녹조 신속 수거·제거 → 댐·보·하굿둑 연계 운영 → 취·정수 관리 강화라는 4단계 대응 체계를 갖추고 있다는 걸 확인했고, 우리 시나리오 설계를 이 4단계에 맞춰 재구성했다. 예를 들어 "산불 영향구간 38개소를 대상으로 pH·T-P 등 6개 항목을 집중 모니터링하고 측정주기를 월 1회에서 2회로 확대"한다는 문장에서, 정부가 이미 "사건 기반 수질 변화 흐름"(산불 → 강우 → 토사·영양염류 유입 → 수질 변화 → 녹조 위험)을 인식하고 있다는 것도 알게 됐다. 이건 우리의 강수 후 유입 시차 가설(H2)과 정확히 같은 논리 구조였다.

또한 AI 조류발생 예보가 이미 2024년 34개 지점에서 2025년 41개 지점으로 확대되고 있다는 사실도 찾아냈다. "기온·강수·일사량·수온을 분석해 일주일 후 조류발생을 예측"한다는 문장은, 우리가 하려는 것과 정확히 같은 방향이었다. 이 조사를 하면서 "우리가 완전히 새로운 걸 하는 게 아니라, 이미 진행 중인 정책 방향에 숟가락을 얹는 형태"라는 확신이 생겼고, 이게 오히려 발표에서 설득력을 높이는 포인트가 됐다.



무엇을 예측할지부터 정확히 정의하기

모델을 짜기 전에 의외로 오래 붙잡고 있던 질문이 "정확히 뭘 예측할 것인가"였다. 조류경보제의 행정 판단 기준은 결국 유해남조류 세포수이기 때문에, Chl-a나 수온 같은 간접 지표를 타깃으로 삼으면 모델이 아무리 정확해도 실제 의사결정과 바로 연결되지 않는다. 그래서 Microcystis·Anabaena·Oscillatoria·Aphanizomenon 4종의 세포수 합계, 즉 법정 경보 기준과 직접 맞닿아 있는 유해남조류_세포수를 최종 타깃으로 잡았다.

회귀 타깃은 현재 세포수가 아니라 next_log_cells, 즉 다음 채수 시점 세포수를 log10(cells + 1)로 변환한 값으로 정의했다. 현재 세포수를 맞히는 모델은 이미 관측된 상태를 재확인하는 수준에 그치지만, 우리 목적은 오늘까지의 정보로 다음 시점(약 7일 후)의 위험을 먼저 알려주는 것이었다. 로그 변환을 쓴 이유는 세포수가 평상시엔 낮다가 여름철 특정 시기에 수천~수만 단위로 튀는 치우친 분포를 갖기 때문인데, 이렇게 하면 0도 안전하게 처리하면서 급증 구간의 영향을 완화할 수 있고, 예측 후에는 다시 cells/mL 단위로 복원해 현장 기준과 비교할 수 있었다.

분류 타깃은 next_alert_binary, 다음 채수 시점 예측 세포수가 관심 기준인 1,000 cells/mL 이상인지를 나타내는 이진값으로 정의했다. 미발령·관심·경계·대발생 4단계를 한 번에 분류하는 다중분류 대신 이진분류로 좁힌 이유는, 경계·대발생 표본이 상대적으로 적어서 다중분류로 쪼개면 학습이 불안정해질 위험이 있었고, 무엇보다 실무에서 가장 먼저 필요한 질문이 "다음 채수 때 관심 이상으로 넘어갈 가능성이 있는가"였기 때문이다.

마지막으로 previous_exceeded(직전 채수가 기준을 넘었는지)를 예측 결과와 함께 보는 것도 중요한 설계였다. 조류경보제 자체가 한 번 넘었다고 바로 확정되는 게 아니라 2회 연속 초과를 발령 조건으로 삼기 때문에, 직전 실측이 기준을 넘었는지와 다음 시점 예측이 기준을 넘는지를 함께 봐야 operational_alert_candidate(운영상 발령 후보)를 제대로 판단할 수 있었다.


가설을 먼저 세우고, 데이터로 검증하기

이 모든 조사를 바탕으로 다섯 개의 검증 가능한 가설을 세웠다. 그냥 "녹조가 늘어날 것이다" 수준이 아니라, 조건과 수치를 구체적으로 명시했다.

가설내용근거 자료
H1 고수온·고pH 조건수온·pH 상승, 일조시간·Chl-a·Microcystis 증가가 함께 나타나면 표층 증식 위험이 커진다조류경보제 운영지침, Liu et al.(2011)
H2 강수 후 유입 시차집중강우 이후 3~14일 뒤 유입량·탁도·질소고정종 증가로 위험이 상승한다2025년 여름철 녹조 대응 보도자료, Deng et al.(2024)
H3 수역 간 선행 신호회남·추동·문의 중 한 수역의 급증이 다른 수역 위험의 선행 정보가 된다대청호 조류경보 보도자료, 조류예측 규정
H4 방류량 감소·체류시간 증가물이 오래 고일수록 위험이 커진다(특히 저풍속·고수온과 결합 시)Van Liere & Mur(1980), De Nobel et al.(1997)
H5 7일 리드타임7일 후 위험을 사전에 예측해 대응 준비에 쓸 수 있다조류예측 규정, Recknagel et al.(2025)

각 가설을 실제 데이터에서 Risk Ratio와 Fisher's exact test로 검증했다. 결과를 표로 정리하면 다음과 같다.

가설조건 충족 시 위험 발생률일반 기간 발생률Risk Ratiop-value판정
H165.7%14.0%4.69배2.79e-65지지
H238.4%13.0%2.96배3.13e-31지지
H361.4%8.6%7.16배1.36e-100가장 강하게 지지
H425.8%22.6%1.14배0.164부분 지지(보조 신호)
H5Recall 100%, Precision 90.7%--1.81e-56지지

H4가 통계적으로 유의하지 않게 나온 게 개인적으로 제일 흥미로웠다. "물이 고이면 녹조가 생긴다"는 직관은 워낙 당연해 보이는데, 막상 단독 요인으로는 유의성이 안 나왔다. 그래서 우리는 정체 조건을 독립 요인이 아니라 고수온·저풍속·종별 우점 변화와 결합될 때만 의미 있는 보조 신호로 재정의했다. 데이터가 우리 예상을 배신했을 때, 그걸 억지로 끼워 맞추지 않고 "Not Supported"로 정직하게 보고서에 적은 것 — 이게 이번 프로젝트에서 스스로 가장 뿌듯했던 부분이다.



모델링

이상치를 다루는 방식부터 다시 생각해야 했다

BeforeAfter

일반적인 데이터 분석이라면 극단값은 노이즈로 취급해서 제거하는 게 맞다. 그런데 우리 문제는 정반대였다. 세포수가 만 단위, 십만 단위로 튀는 구간이야말로 경보가 필요한 바로 그 순간이다. 이상치를 지우면 모델이 정작 맞혀야 할 걸 놓치게 된다.

그래서 타깃부터 next_log_cells = log10(다음 시점 세포수 + 1)로 로그 변환해서 왜도가 심한 분포를 완화했다. 회귀 후보 모델에는 이상치에 강한 HuberRegressor를 포함시켰는데, 이건 튜닝 과정도 나름 길었다. 처음엔 기본 설정으로 RMSE 0.7070이 나왔는데, epsilon=2.5, alpha=0.0, max_iter=3000, tol=0.00001, scaler=robust로 파라미터를 조정하니 RMSE가 0.6695까지 떨어졌다. 이후 Stacking Ensemble에 HuberRegressor를 추가로 포함시키자 최종 RMSE가 0.6554까지 개선됐다.

강수량 관련 컬럼(daily_rain, rain_3d_sum, rain_7d_sum, rain_14d_sum)은 평상시엔 0에 수렴하다가 태풍·집중호우 시 극단적 이상치를 갖는 왜도 심한 분포였다. 이런 컬럼엔 중앙값과 사분위수 범위(IQR)를 쓰는 RobustScaler를 적용했고, 반대로 기온·바람·일사량처럼 물리적 상하한이 비교적 일정한 변수엔 MinMaxScaler를 적용해서 특정 변수의 단위 크기가 학습을 왜곡하지 않도록 했다.


최종 모델 구조

최종적으로는 LightGBM, XGBoost, RandomForest, HistGradientBoosting, CatBoost, HuberRegressor를 베이스 모델로 하고 RidgeCV를 메타 모델로 쌓은 Stacking Ensemble 구조를 채택했다. 트리 기반 모델은 비선형 조건과 변수 간 상호작용을 잘 잡아내고, HuberRegressor는 이상치에 강한 안정적 방향성을 제공하며, RidgeCV는 이 예측들을 다시 안정적인 선형 결합으로 정리해 과적합을 완화하는 역할을 맡았다.

분류 모델도 같은 논리로 여러 모델의 확률 예측(predict_proba)을 LogisticRegression이 최종 종합하는 StackingClassifier를 썼다. 여기서 Logistic Regression은 단순 분류기가 아니라, 여러 모델이 계산한 위험 확률을 운영 관점에서 최종 정리하는 의사결정 레이어 역할이었다.

모델RMSE(log)RMSE(cells)MAE(log)
Stacking Ensemble0.655~0.66813,315~13,3160.477~0.4860.844~0.846
LightGBM0.67712,654.50.4840.836
RandomForest0.67914,073.20.5120.835
HistGradientBoosting0.68512,601.80.4960.832
XGBoost0.68713,398.10.5110.831
CatBoost0.69613,832.10.5320.826
HuberRegressor0.6695~0.70713,348~14,6150.478~0.4800.821~0.839
Persistence Baseline0.799~0.80014,604.10.476~0.4800.771~0.772

분류 모델(RandomForest 기준)은 Accuracy 95.6%, Precision 90.7%, Recall 100.0%, F1 0.951이 나왔다. 검증 데이터 기준 실제 관심 기준 이상 사례 137건을 하나도 놓치지 않았다(False Negative = 0). Binomial test 기준 p-value는 1.81e-56으로, 이 결과가 우연히 다수 클래스를 찍어서 나온 게 아니라는 것도 확인했다.

지점별 예측 오차(MAE, log 스케일)도 따로 확인했는데, 추동 0.447, 회남 0.547, 문의 0.438로 회남이 상대적으로 오차가 컸다. 상류에 위치한 회남이 강우 직후 변동성이 가장 크기 때문으로 해석했다.

SHAP으로 설명 가능성 확보하기

모델 성능만큼 신경 쓴 게 "왜 위험하다고 판단했는지"를 설명하는 것이었다. XGBoost, LightGBM, CatBoost, RandomForest 계열은 SHAP 기반 해석과 잘 연결됐다. 예를 들어 "강우 증가 → 영양염류 유입 증가 → 체류시간 증가 및 수온 상승 → 남조류 증식 → 경보 위험 증가"라는 환경 흐름을 feature contribution 형태로 설명할 수 있도록 설계했다. 관리자가 "위험하다/아니다"만 보는 게 아니라, "왜 위험한지"와 "어떤 대응이 필요한지"까지 함께 이해할 수 있게 만드는 게 목표였다.


예상 밖의 발견들

모델을 다 만들고 나서 데이터를 다시 들여다보다가, 애초에 의도하지 않았던 인사이트 두 개를 발견했다.

1. 연속 초과 확률이 88.1%였다. 직전 채수에서 관심 기준(1,000 cells/mL)을 넘긴 지점은, 다음 채수에서도 88.1%(318/361건) 확률로 다시 기준을 넘겼다. 반대로 직전에 기준 미달이었던 경우 다음 시점 초과 확률은 3.5%(43/1215건)에 불과했다. 즉, 조류경보제의 "2회 연속 초과" 발령 기준 자체가, 이미 통계적으로 상당히 예측 가능한 흐름을 그대로 기다리는 구조라는 뜻이었다. 우리는 이걸 근거로 "첫 초과 시점을 단순 관찰값이 아니라 조기 경보 신호로 활용하자"는 제안을 만들었다.

2. 종별 기여도와 출현 빈도가 정반대였다. 전체 세포수 총량 기준으로는 Microcystis가 84.9%(4,117,642)를 차지해 압도적이었다. 그런데 출현 빈도로만 보면 Aphanizomenon이 73.3%(683건)로 오히려 더 자주 나타났다(총량 기여도는 7.0%에 불과했는데도). Microcystis는 65.1%(607건) 빈도로 두 번째였다. 이건 "유해남조류 4종을 합산 관리하는" 현행 방식이 종별 생태 특성 차이를 가려버릴 수 있다는 뜻이었다. 우리는 이걸 "법정 기준의 4종 합산 관리는 유지하되, 예측 모델이 7일 후 예상한 우점종의 생태적 특성에 맞춰 현장 대응 시나리오를 다각화해야 한다"는 제안으로 연결했다.


시나리오 설계: 예측을 현장 언어로 바꾸기

예측값 하나만 던져주면 현장 담당자는 다시 매뉴얼, 채수 기준, 수문 상태, 기상 조건을 따로 확인해야 한다. 그래서 시나리오를 예측값과 현장 대응을 잇는 번역기로 설계했다. 기준은 네 가지 축이었다.

  1. 행정 경보 기준: 관심(1,000)·경계(10,000)·조류대발생(1,000,000) 기준에 직접 연결되는 "관심 발령 후보", "경계 발령 후보", "조류대발생 감시"
  2. 발생 메커니즘: 앞서 정리한 4대 메커니즘에 대응하는 "수온 20도 이상 계절 감시", "고온·고일사 성장 촉진", "강우 이후 영양염류 유입", "수체 정체·성층 위험"
  3. 공간 전파 구조: 회남의 선행 위험이 다른 수역에 영향을 줄 수 있다는 H3 가설을 반영한 "회남 선행 전파 관찰"
  4. 운영 단계: 아직 발령 후보는 아니지만 접근 중인 "관심 기준 접근", 하향 추세인 "하향·해제 관찰", 위험 신호가 없는 "일반 안정"

전체 기간에 대해 시나리오를 생성해보니 일반 안정이 823행으로 가장 많았고, 관심 발령 후보 271행, 관심 기준 접근 142행, 수온 20도 이상 계절 감시 71행, 경계 발령 후보 63행, 회남 선행 전파 관찰 8행 순이었다. 각 시나리오에는 실제 대응 초안도 함께 붙였는데, 예를 들어 "경계 발령 후보"에는 "주 2회 이상 채수 체계, 정수처리 강화, 취수 수심 조정, 물순환설비 가동, 조류 제거 장비 준비 여부를 우선 확인"이라는 식으로 정부 자료(2025년 녹조 대응 보도자료, 조류제거물질 사용지침)에 나온 실제 대응 수단을 그대로 연결했다.


LLM 에이전트까지 고민했던 이유

사실 이 프로젝트 초반 아이디어 회의에서는 더 큰 그림을 그리고 있었다. 출발점은 "기존 방식의 한계"에 대한 문제의식이었다. AI가 "7일 뒤 추동 수역 세포수 15,000cells/mL 예상"이라는 숫자만 던져주면, 실무자는 다시 매뉴얼을 찾아보고 현재 방류량을 확인한 뒤 직접 대응 방안을 고민해야 한다. 지금도 대응 체계가 완전히 자동화되지 못해서 과거 자료와 육안 확인에 의존하는 부분이 많다고 판단했다. 그래서 우리는 "AI가 수치 예측뿐 아니라 원인을 스스로 해석하고, 구체적인 관리 지시서까지 자동 생성하면 어떨까"라는 질문을 던졌다. 단순히 "예측하는 모델"이 아니라, 예측 결과를 스스로 해석하고 관리 지시서까지 자동 생성하는 자율형 에이전트를 만들면 어떨까 하는 논의였다.

정량 예측(회귀/분류) → SHAP 기반 원인 해석 → LLM이 이걸 자연어 관리 지시서로 변환하는 파이프라인이었다. 실제 최종 산출물에는 llm_publisher.py라는 스크립트로 이 개념을 일부 구현해뒀다. 예측 결과와 시나리오를 LLM 프롬프트 형태로 정리해서 payload, prompt, 샘플 CSV를 자동 생성하는 기능이다. 시간 관계상 이 부분을 완전히 실전 수준까지 다듬지는 못했지만, "AI가 판단 근거까지 설명하는 구조"를 지향했다는 점에서 팀 내부적으로는 의미 있는 시도였다고 생각한다.


B/C 분석: 숫자로 설득하기

기술적으로 그럴듯한 모델이라도, 결국 공공기관 담당자를 설득하려면 "그래서 이게 얼마나 이득인가"를 숫자로 보여줘야 했다. 「정수장 조류 대응 가이드라인」 63페이지에 나온 공식 비용 산정 기준을 그대로 가져왔다.

  • 실시간 자동분석시스템 비용: 약 1.5억 원/10년 (구입비 5천만원 + 운영비 1억원/10년)
  • 분말활성탄 절감액: 정수용량 1,000,000㎥/일 × 20mg/L × 90일 × 1,500천원/톤 × 20% 절감 = 약 5.4억 원/년
  • 오존 처리비 절감액: 1,000,000㎥/일 × 2.5원/㎥ × 90일 × 20% 절감 = 약 0.45억 원/년

여기에 예측 기반 조기대응(사전 탐지 18건 × 평균 4일 × 1일당 대응가치 50만원 = 3,600만원), 미탐 감소(6건 × 건당 500만원 = 3,000만원)를 편익에 더하고, 늘어난 오경보 비용(4건 × 건당 80만원 = -320만원)을 차감해서 최종 계산을 했다.

B/C = 총편익 64.78억 원 / 총비용 3.5억 원 ≈ 18.51

1원을 투입하면 약 18.51원의 편익이 발생할 수 있는 구조라는 계산이 나왔다. 다만 이건 확정된 실측 결과가 아니라 "이런 방식으로 정량화할 수 있다"는 프레임을 제시한 것일 뿐이라는 점을 보고서에 분명히 명시했다. 실제 대청댐 운영자료 없이 부풀린 숫자로 포장하고 싶지 않았고, 최종 B/C는 관계기관의 조류예찰·정수처리·방제장비·경보 단계별 운영비 자료를 연계해 재산정해야 한다는 단서를 달았다.


리스크도 먼저 고민했다

AI 예측이 잘못 쓰이면 오히려 해가 될 수 있다는 것도 처음부터 인지하고 있었다. 그래서 세 가지 리스크 관리 방안을 별도로 정리했다.

  1. 오해 방지: 예측 결과가 공식 경보나 수돗물 안전성 문제로 오해되지 않도록, 외부 안내 시에는 예측 위험도·실제 관측값·공식 경보 단계를 명확히 구분해서 제공한다.
  2. 권한 분리: 조류경보 발령과 행정 조치 권한은 기존 조류경보제 운영 절차에 그대로 유지한다. AI는 자동 발령이나 자동 조치를 하지 않고, 사전 예찰과 대응 준비를 보조하는 도구로 역할을 제한한다.
  3. 편향성 관리: 전체 정확도만 보면 특정 수역의 미탐이나 계절별 오경보를 놓칠 수 있어서, 지점별 재현율 편차·계절별 오경보율·경보 단계별 미탐률을 따로 점검한다.

발표, 그리고 본선까지

서류 심사를 통과하고 본선 발표 기회를 얻었다. 발표는 여섯 파트로 구성했다.

  1. 문제 정의 — 녹조 대응은 왜 AI 예측 단계로 진입해야 하는가
  2. 분석 목표와 핵심 가설(H1~H5)
  3. 데이터 융합과 Feature 설계
  4. AX 예측 모델링 프레임워크
  5. 검증 결과와 대응 시나리오
  6. 정책 활용성과 운영 리스크 관리

발표 자료 첫 장에 넣은 문제의식은 "경보보다 빠른 준비"였고, 마지막 장에 넣은 문장은 이거였다.

"AI가 경보를 대신 내리는 것이 아니라, 공공기관이 더 빠르고 근거 있게 준비하도록 돕는 것입니다."

우리 스스로도 이 예측 시스템이 만능이 아니라는 걸 인지하고 있고, 그 안에서 실질적으로 기여할 수 있는 지점이 어디인지를 명확히 하고 싶었다. 결과적으로 본선까지는 올라갔지만 최종 수상에는 들지 못했다. 다른 팀들의 결과물과 심사 흐름을 지켜보면서 아쉬운 지점도 있었지만, 그것과 별개로 이 프로젝트를 준비하며 배운 것들은 확실히 남았다.


본선 질의응답에서 배울점

"그래서 수질 자체와 녹조 발생의 상관관계는 어떻게 확인했나요?"

이 질문에는 제대로 답하지 못했다. 우리가 준비한 건 유해남조류 세포수를 타깃으로 놓고 기상·수문 조건(수온, 강수량, 유입량·방류량, 체류시간 proxy)과의 관계를 Risk Ratio와 Fisher's exact test로 검증한 가설들뿐이었다. 정작 심사위원이 물은 건 그 이전 단계, 즉 pH·DO·탁도·Chl-a 같은 수질 지표들 자체가 서로 어떻게 얽혀 있고, 그게 녹조 발생과 어떤 상관관계를 갖는지였다. 이 부분은 따로 분석해둔 자료가 없었다. 수질 항목 간의 관계를 정량적으로 파고든 근거도 준비되어 있지 않았다. 돌이켜보면 남조류 발생 메커니즘 공부에 밀려 정작 우리가 제공받은 수질 데이터 자체를 상관행렬이나 다중공선성 관점에서 제대로 들여다보지 않았던 게 원인이지 않을까 생각한다.

"회남·추동·문의는 위치도, 특성도 다른데, 그 차이를 모델이 정말 반영하고 있나요?"

이 질문에는 그나마 자신 있게 답할 수 있었다. 회남은 상류 유입부라 강수·유입량에 민감하고, 추동은 취수탑이 있는 정체 수역이라 수온·일조량에 민감하며, 문의는 댐 본체 근처라 방류량에 민감하다는 지점별 특성을 설명했다. 그리고 이걸 그냥 설명으로 끝낸 게 아니라 loc_encoded(지점 코드), loc_flow_order(흐름 순서), hoenam_pressure_for_downstream(회남 지점이 기준을 초과했을 때 하류 수역에 주는 압력 신호) 같은 파생 변수로 실제 모델에 반영했다는 것, 그리고 H3(수역 간 선행 신호) 가설이 Risk Ratio 7.16배로 가장 강하게 지지됐다는 결과까지 근거로 제시했다. 다만 심사위원 한 분이 "그러면 회남에서 감지된 신호가 정확히 며칠 뒤에 추동·문의에 도달하는지 지연 시간까지 정량적으로 특정했느냐"고 물었을 때는 ...할 말이 없었다. 우리는 "선행 신호가 있었던 기간"을 뭉뚱그려 정의했을 뿐, 회남에서 문의까지 물리적으로 며칠이 걸리는지 유속 기반으로 계산한 값은 없었다.

"지점이 세 곳인데 모델은 왜 하나인가요? 시계열 특성이 지점마다 다를 텐데요."

사실 초기 아이디어 회의 때는 회남·추동·문의를 완전히 독립된 세 개의 모델로 학습시키는 방안도 논의했었다. 지점마다 오염 발생 메커니즘 자체가 다르니, 하나의 모델에 지점을 욱여넣기보다 지점별로 가중치와 피처 중요도가 다른 세 개를 따로 학습시키는 게 이론적으로는 더 맞는 방향성이었다고 지금은 생각이든다. 그런데 실제로는 각 지점당 확보되는 채수 샘플 수가 전체 데이터를 3분의 1로 쪼개면 급격히 줄어드는 문제가 있었고, 결국 시간과 데이터 규모의 한계 속에서 loc_encoded와 지점 관련 파생 변수를 넣은 단일 통합 모델로 방향을 틀었다. 심사위원은 정확히 이 지점을 짚었다. "그럼 세 지점을 하나로 합쳐서 학습시켰을 때, 각 지점 고유의 계절적 패턴이나 자기상관 구조가 서로 다른데 단일 모델이 그 차이를 온전히 학습했다고 확신할 수 있느냐"는 질문이었다. 변명같지만.. 정확한 공공데이터가 없었는데..


돌아보며

결과는 본선 진출, 최종 수상은 못 했지만 많은것을 얻게해준 공모전이였다.

이번 대회를 준비하면서 가장 크게 느낀 건, 좋은 AI 프로젝트는 모델 성능이 전부가 아니라는 것이다. 우리 팀이 가장 많은 시간을 쓴 곳은 사실 모델을 하이퍼파라미터 튜닝하는 것이 아니라, 조류경보제 운영 매뉴얼과 관련 법령을 조문 단위로 읽으며 도메인 지식을 쌓고, 남조류 생물학 논문을 찾아 메커니즘을 이해하고, 대청호가 다른 호수와 어떻게 다른지 비교 연구를 뒤지는 과정이었다. AI 모델은 이 모든 조사의 결과물을 검증하는 단계에 불과하다.

특히 가설을 세우고 통계적으로 검증하는 단계가 가장 값졌다. H4처럼 예상과 다르게 기각에 가까운 결과가 나왔을 때, 그걸 억지로 끼워 맞추지 않고 "보조 신호"로 정직하게 재정의한 게 오히려 신뢰도를 높이는 방향이었다고 생각한다.

열두 개의 지정과제 중에서 굳이 수자원공사의 조류경보 문제를 고른 것도 돌이켜보면 잘한 선택이었다. 수자원공사가 대청댐 수질·수문 데이터를 10개년치나 통째로 있어 데이터적인 면에서는 수훨했고 그걸가지고 "왜 이 시기에 녹조가 늘어나는가"로 바꾸는 건 논문을 찾고, 기상 데이터를 보태고, 법령을 뒤지는 우리 몫이었다. 대청호 하나를 정말 깊게 파고드는 과정에서 법령 조문, 정부 보도자료, 국내외 논문까지 — 리서치의 폭과 깊이 모두에서 이전에 해본 어떤 프로젝트보다 재밌게 공부한 느낌이든다.

수상까지 이어지지는 못했지만, 다애님과 현준님과 함께 프로젝트를 준비한 시간 자체가 너무너무 값진 경험이였다. 일주일에 2~3회씩 꾸준히 회의를 진행하고, 새벽까지 함께 개발하고 자신이 찾은분을 공유하고, 프로젝트 이야기는 물론 사소한 일상 이야기까지 나누면서 자연스럽게 팀워크를 쌓을 수 있었다. 공모전을 준비하는 과정에서 힘든 순간도 있었지만, 돌이켜보면 좋은 경험으로 남은 기억이 훨씬 많다.
이후에도 우리 춘배팀은 여기서 멈추지 않았다. 함께 제4회 문화체육관광 인공지능·데이터 활용 공모전 개발 부문에도 도전했고 오늘일자로 결과가 나왔다. 기대만큼 만족스럽지는 않았지만, 이를 계기로 앞으로도 9월에 있을 해커톤을 함께하기로 했다. 무엇보다 공모전의 성과를 떠나 서로 배우고 성장할 수 있는 좋은 사람들을 만났다는 점이 이번 경험에서 가장 큰 의미였다고 생각한다.

고생하셨습니다 @다애,현준


참고 자료

프로젝트가 궁금하다면 -> GitHub

법령·정책

  • 「조류예측 및 수질관리협의회에 관한 규정」
  • 「물환경보전법 시행령」
  • 「정수장 조류 대응 가이드라인」(국립환경과학원, 2017)
  • 「조류제거물질 사용지침」
  • 기후에너지환경부, 「관계부처 협업으로 여름철 녹조발생에 체계적 대응」 보도자료
  • 기후에너지환경부, 「2025년 여름철 녹조 대응」 보도자료 (야적퇴비 관리, AI 조류발생 예보 지점 확대 34→41개 등)
  • 대한민국 정책브리핑, 「녹조 수질검사·정보공개 전면 개편」(2025)
  • 금강청, 「대청호 문의 수역 조류경보 관심 단계 발령」 보도자료

데이터

  • 한국수자원공사 대청댐 운영 수문정보, 수질·조류 관측자료
  • 기상청 종관기상관측(ASOS) / 방재기상관측(AWS) Open API
  • 공공데이터포털(data.go.kr)

논문

  • Liu et al., 2011, The effects of temperature and nutrient ratios on Microcystis blooms in Lake Taihu, China
  • De Nobel et al., 1997, Competition for phosphorus between Anabaena and Aphanizomenon
  • Van Liere & Mur, 1980, Occurrence of Oscillatoria agardhii
  • Recknagel et al., 2025, Early warning of harmful cyanobacteria blooms based on high frequency in situ monitoring and intelligible machine learning modelling: The case study of Lake Müggelsee (Germany)
  • 「대청호 상류유역의 오염원 현황과 수질관리 방안에 관한 연구: 안남천과 안내천을 중심으로」
  • 「소옥천 유역의 오염제어 대책에 따른 대청호 조류저감 효과 분석」
profile
發現(발현)

0개의 댓글