Back to Posts

녹조를 미리 예측할 수 없을까?

Posted in Data Mining Image Source | 한겨례

들어가며

이 프로젝트는 나의 첫 데이터마이닝 프로젝트였다. 당시 지구과학이 전공이었던 나는, 데이터마이닝 기법을 적용되지 않은 지구과학에 적용해보는 것이 매우 흥미로울 것이라 생각했다. 많고 많은 지구과학과 관련된 소재 중, 녹조를 고른 것은 녹조로 인한 문제가 심각하고, 따라서 발생을 예측한다면 큰 도움이 될 소재라고 생각했기 때문이다. 혹여나 녹조 예측과 관련한 연구가 활발히 진행되고 있는지 살펴보니 데이터마이닝 기법 중 하나인 SVM(Support Vector Machine)을 이용해서 통영의 적조를 예측하려는 논문 한 편 정도만 발견할 수 있었다1.

녹조 예측을 프로젝트의 주제로 삼은 또 하나의 이유는 프로젝트를 진행할 수 있는 데이터가 존재하기 때문이었다. 통상 데이터마이닝 프로젝트를 진행하면서 흔하게 겪는 문제는 아이디어는 있는데, 데이터가 없는 경우다. 운이 좋게도 나의 경우에는 내가 하고 싶었던 나의 전공이라는 범주 안에 데이터가 있었지만, 종종 아이디어에 맞는 데이터를 찾는게 아니라 데이터에 맞는 아이디어를 찾아 프로젝트를 진행하는 경우도 있다. 본 프로젝트에서 사용한 데이터는 환경부, 수자원관리공단, 기상청과 같은 공공기관에서 제공하는 것으로 다른 데이터들에 비해 구하기 쉬우며 다양한 변수와 활용하여 진행하였다.

녹조(Green Tide)

우리가 흔히 녹조라고 부르는 현상은 일반적으로 플랑크톤이라고 부르는, 조류가 과다번식해서 물이 청남색 혹은 녹색을 띠는 경우를 말한다. 국내의 경우 남조류2가 녹조를 일으키는 것으로 알려져있으며, 그 중에서도 독소를 생성하는 유해 남조류가 과잉되는 경우, 녹조의 위험성은 매우 커진다.

녹조가 발생했을 때 생기는 일차적인 문제는 수중 생태계가 파괴되는 것이다. 조류가 과다 번식하면 물 속에 녹아 있는 산소의 양이 급격히 줄고, 조류들이 수면에서 햇빛을 막아 강에 사는 다른 생물들에게 악영향을 끼치고, 심각한 경우 집단 폐사에 이르게 한다. 이러한 녹조를 대응에 소요되는 비용은 연간 40억 여원3에 이르고 있다.

인간에게 있어 녹조가 골칫거리인 또다른 이유는 식수원을 오염시킨다는 것에 있다. 이는 녹조가 인간이 마시는 물 중 하나인 강에서 발생하기 때문이다. 녹조가 발생한 강물은 기본적인 정수과정에 더해 추가적인 정수과정을 필요로 한다

그렇다면 도대체 왜 녹조가 발생하기 전에 이를 미리 막을수 없는 것일까? 일단 조류가 과다번식하는 이유를 잘 알지 못한다. 조류가 번식하는데 영향을 미치는 요인으로는 높은 수온, 영양염류의 공급, 풍부한 일사량, 느린 유속 등이 있다는 사실은 알려져있지만, 이들이 어떻게 복합적으로 작용하여 조류의 번식을 촉진시키는지는 불분명하다.

거기다 (이유는 잘 모르지만) 조류의 양을 측정하는 주기가 매우 긴 것도 문제다. 4대강의 조류 측정 정보를 제공하는 물환경시스템에 따르면, 현재의 조류 측정 주기는 1주일이다. 조류가 2~3일 안에 대량 번식할 수 있음을 감안하면 이 정도의 측정 주기로는 녹조의 원인에 대한 연구는 물론이고, 녹조의 발생 경과도 제대로 파악하지 못하는 실정이다.

조류 예보제

이런 열악한 상황에도 불구하고, 환경부에서는 조류 예보제라는 나름의 예보 체계를 갖추고 있다. 이 체계는 조류가 가지고 있는 엽록소인 클로로필 a(Chl-a)의 농도와 남조류의 개수밀도를 기준으로 구분된다.

단계 클로로필 a 농도(mg/m2) 남조류 개수밀도 (세포수/mL)
조류 주의보 15 이상 500 이상
조류 경보 25 이상 5000 이상
조류 대발생 100 이상 106 이상

프로젝트의 목표

앞서 살펴본 조류에 대한 내용을 토대로 해서, 이 프로젝트에서 궁극적으로 해결하고자하는 문제는 녹조 발생 3일전에 녹조를 미리 예측하는 것이다. 다시 말해서, 조류 발생에 영향을 미치는 변수를 가지고 3일 후에 조류가 발생할 것인지 발생하지 않을 것인지를 예측하는 것이다. 3일이라는 기간을 정한 것은 녹조를 예방할 수 있는 대표적인 방법인 보 방류를 결정하는데에 이 정도의 기간이 적절하다고 판단했기 때문이다.

데이터

조류 데이터

먼저 물환경정보시스템에서 제공하는 2012년 10월에서 2015년 11월까지 약 3년 간의 조류 수질관측소 데이터를 모았다. 금강의 대표적인 보인 세종보, 공주보, 백제보의 641개의 데이터가 모아졌다. 기간에 비해 데이터의 수가 적은 것은 조류 측정을 1주일에 한 번밖에 하고 있지 않기 때문이었다. 이 데이터의 Chl-a와 남조류 수를 가지고 위의 예보 기준에 맞춰서 분류해보면 다음과 같이 나누어 진다.

단계 데이터 개수
정상 509
조류 주의보 95
조류 경보 37

예측 변수 데이터

조류의 발생을 예측하기 위해서, 조류의 발생과 연관 있는 요인들에 대한 데이터가 필요한데 이 데이터들은 다른 공공기관에서 데이터를 제공하고 있다.

이것이 이 프로젝트의 특징이라고 할 수 있는데, 여러 공공기관에서 제공하는 데이터를 매쉬업(mash-up)했다는 것이다. 공공기관에서 제공하는 데이터의 형식(…)을 생각해보면, 2개도 아니고 4개 기관의 데이터를 시간을 기준으로 합치는 전처리는 정말 장난이 아니었다.

전처리를 하면서 겪었던 또 하나의 난관은 정확히 해당 보에서 측정한 예측 변수 데이터가 없다는 점이었다. 아래와 같이 각 보에서 가장 가까운 측정 지점의 데이터를 가져다쓸 수 밖에 없었다.

data-place 데이터를 수집한 장소를 나타낸 그림. 여기서 ‘조류 수질측정소’는 물환경정보시스템의 데이터 수집 지점이며, ‘자동 수질측정소’는 실시간 수질정보시스템의 데이터 수집 지점을 나타낸다. 주황색 보로 표시된 지점들이 WAMIS 데이터를 수집한 지점들이다. 위의 세 데이터는 동일한 지점의 데이터는 아니지만, 비교적 데이터 간의 거리가 가깝다. 그러나 기상청 데이터의 경우, 가장 가까운 장소가 대전으로 끝이다. 데이터의 신뢰성 문제가 있기는 하지만, 조류 발생에 중요한 요인을들에 대한 정보를 많이 가지고 있기 때문에 일단은 사용해보기로 했다.

변수를 정리해보면 다음과 같다.

약자 변수명 출처
chl-a 클로로필 a 농도(mg/m2) 물환경정보시스템
bacteria 남조류 세포수 (세포수/mL) 물환경정보시스템
temp-1 1일 전 수온(oC) 실시간 수질정보시스템
temp-2 2일 전 수온(oC) 실시간 수질정보시스템
pH-1 1일 전 pH 실시간 수질정보시스템
pH-2 2일 전 pH 실시간 수질정보시스템
EC-1 1일 전 전기전도도(μS/cm) 실시간 수질정보시스템
EC-2 2일 전 전기전도도(μS/cm) 실시간 수질정보시스템
DO-1 1일 전 용존산소량(mg/L) 실시간 수질정보시스템
DO-2 1일 전 용존산소량(mg/L) 실시간 수질정보시스템
TN-1 1일 전 총 질산(mg/L) 실시간 수질정보시스템
TN-2 1일 전 총 질산(mg/L) 실시간 수질정보시스템
TP-1 1일 전 총 인(mg/L) 실시간 수질정보시스템
TP-2 1일 전 총 인(mg/L) 실시간 수질정보시스템
inflow-1 1일 전 유입량(106m3) WAMIS
inflow-2 2일 전 유입량(106m3) WAMIS
inflow-3 3일 전 유입량(106m3) WAMIS
outflow-1 1일 전 방출량(106m3) WAMIS
outflow-2 2일 전 방출량(106m3) WAMIS
outflow-3 3일 전 방출량(106m3) WAMIS
rain-1 1일 전 강수량(mm) 기상청
rain-2 2일 전 강수량(mm) 기상청
rain-3 3일 전 강수량(mm) 기상청
sun-1 1일 전 일조량(MJ/m2) 기상청
sun-2 2일 전 일조량(MJ/m2) 기상청
sun-3 3일 전 일조량(MJ/m2) 기상청
mean-wind-1 1일 전 평균풍속(m/s) 기상청
mean-wind-2 2일 전 평균풍속(m/s) 기상청
mean-wind-3 3일 전 평균풍속(m/s) 기상청
max-dir-1 1일 전 최대풍속 풍향 기상청
max-dir-2 2일 전 최대풍속 풍향 기상청
max-dir-3 3일 전 최대풍속 풍향 기상청

데이터 전처리

데이터 결측치 처리

센서를 통해서 측정하는 실시간 수질 정보시스템 데이터의 경우에는 결측치가 상당히 많았다. 일반적으로 센서 데이터를 보면 짧은 주기로 많이 얻을 수 있는 장점은 있지만, 그만큼 (관리가 소홀한지) 결측치도 많은 경향을 보였다.

위 데이터의 경우 결측치가 너무 많아서 버려야할 데이터가 (640 여개 중에) 150개 내외 정도 여서 그것들은 아예 빼버렸다. 그 후에도 한 두개의 변수들에 결측치가 있는 데이터가 꽤 있었다. 그렇지만 이마저도 버리면 데이터의 손실이 너무 클 것이라고 판단해서 결측치를 채우는 방법을 선택했다. 결측치를 채우는 방법은 평균을 쓰는 방법이 일반적이지만 이 방법은 데이터의 특성을 잘 나타내어주지 못하기 때문에 다른 방법을 찾았다.

이 프로젝트에서 사용하는 변수는 1일전 강수량, 2일전 강수량과 같이 같은 것을 측정했지만 시간의 흐름에 따라 보는 것들이 있다는 점이 특징이다. 이것을 이용해서 비교적 합리적으로 결측치를 추론하는 방법을 사용했는데, 그것은 결측치가 없는 데이터들에서 1일전과 2일전의 값을 각각 x, y 좌표로 하는 그래프를 그린 뒤, 회귀 직선을 뽑아내는 것이었다.

결측처리 1일 전, 2일 전 수온 변수의 결측치가 없는 데이터를 x축에 1일 전 수온, y축에 2일 전 수온으로 하는 그래프에 나타낸 그래프. 그래프에서 구한 직선을 가지고 1일 전 혹은 2일 전의 수온값이 하나가 빠져있는 데이터의 결측을 추정하는데 사용하였다.

위와 과정을 pH, EC, DO, TN, TP에 대해서도 진행하였으며, R-Square가 높게 나와 이 회귀직선을 이용해서 결측치들을 채워도 꽤 정확할 것이라는 신뢰성을 얻을 수 있었다.

변수 처리

결측치 처리 이외에도 몇 가지 변수를 변경하거나 추가했다. 먼저 풍속 변수에 대한 보정을 진행했는데 위의 변수 목록을 살펴보면 알 수 있듯이, 풍속과 풍향이 별개의 변수로 들어가 있다. 녹조가 강물의 유속(혹은 유량)에 관계가 있음을 감안한다면 강물이 흐르는 방향의 바람만이 녹조에 영향을 줄것이라고 추론해볼 수 있다. 이를 고려해주기 위하여 각 보에서 강물이 흐르는 방향의 각도 계산하고, 풍속과 풍향 데이터를 이용하여 이 방향에 해당하는 바람 성분만을 계산하였다. 이렇게 계산한 변수는 하류 방향 풍속 이라는 변수로 추가하였다.

이와 별개로 강수량과 일조량의 경우, 변수로 넣은 3일치의 데이터를 합한 새로운 변수를 만들어, 각각 강수량 합, 일조량 합의 변수로 추가했다. 이는 단순히 하루뿐만이 아니라, 수 일간 누적된 강수량과 일조량이 녹조와 상관이 있을 것이라 판단했기 때문이다.

이 과정을 거쳐 새롭게 추가된 변수는 다음과 같다.

약자 변수명 출처
wind_real-1 1일 전 하류 방향 풍속 (m/s) 기상청
wind_real-2 2일 전 하류 방향 풍속 (m/s) 기상청
wind_real-3 3일 전 하류 방향 풍속 (m/s) 기상청
rain-sum 강수량 합 (mm) 기상청
sun-sum 일조량 합 (MJ/m2) 기상청

데이터 라벨링

앞서 조류 데이터를 살펴보면 조류가 발생한 경우가 발생하지 않은 경우에 비해 매우 적은 것을 알 수 있다. 이러한 클래스 불균형(class imbalance) 문제를 해결하는 일반적인 방법은 과샘플링(over-sampling)이 있다. 이 프로젝트를 진행할 때는 거기까지 해보진 못했고, 조류 주의보, 조류 경보 상황을 하나의 집단으로 합쳐서 조류가 발생한 경우의 데이터 수를 최대한 늘려보았다.

따라서 데이터셋이 다음과 같이 조정되었다.

단계 데이터 개수
조류 미발생 327
조류 발생 91

앞서 결측치의 문제로 641개에서 223개의 데이터를 제거하여 총 418개의 데이터를 분석에 사용하였다

데이터 분석

이 프로젝트를 진행하던 당시 할 줄 아는 프로그래밍 언어가 없어서, 수업에서 조금 다루어 본 R을 사용해서 분석을 진행했다.

데이터는 무작위로 7:3으로 뽑아서 training set, test set으로 나누어서 사용했다.

분류(Classification)

이 문제는 기본적으로 분류의 문제이다. 즉 예측 변수 값을 통해 구하고자하는 변수가 조류가 발생한 것인지 그렇지 않은 것인지를 에측하는 것이기 때문이다. 따라서 위의 변수 목록에서 Chl-a와 bacteria를 제외하고 나머지 변수들을 가지고 ‘조류 발생 여부’4라는 변수를 예측하는 것으로 문제를 접근했다.

사용한 데이터마이닝 기법은 크게 3가지로, Decision Tree, Weighted k-nn, Artificial Neural Network를 사용했다. (분석에 사용한 코드 중, 내가 수행한 weight-knn과 Artificial Neural Network에 대한 코드는 깃헙에 올려두었다.)

Decision Tree

Decision Tree(DT)는 가장 순수한5 집합을 만들 수 있는 변수의 기준을 찾아서 양분해나가는 방식의 데이터마이닝 기법이다. 예를 들어, ‘강수량 5mm’를 기준으로 데이터를 나누면, 다른 어떤 기준보다도 한쪽에는 조류 발생 데이터가 최대로 들어가고, 다른 한쪽에 조류 미발생 데이터가 최대로 들어간다면 그 기준이 노드(node)가 되며, 거기서 데이터가 나누어진다. 그리고 이 과정을 계속해서 반복해나가는 것이다. 이 방법이 나무에 비유되는 이유는, 노드를 기준으로 데이터가 나누어져가는 것이 마치 나무의 가지가 뻗어나가는 것과 비슷하기 때문이다.

이 방법의 가장 큰 장점은 데이터마이닝을 수행했을 때 어떤 변수가 중요한지를 한눈에 알아볼 수 있다는 점6이다. 여기서 뽑혀나오는 중요 변수들은 별도의 변수 선택 프로세스가 없는 데이터마이닝 알고리즘에서 변수를 고르는데 중요하게 사용되며 본 프로젝트에서도 이를 이용하였다.

이 프로젝트에서는 기본적인 DT를 조금 발전시킨 4가지 기법을 사용하였다.

  • CART : DT의 과적합을 방지하기 위해 training set의 오분류율(error), test set의 오분류율을 가지고 모델의 심도(depth)를 조절하는 알고리즘. ‘가지치기(pruning)’의 대표적인 방법. R에서는 tree 패키지를 통해 DT를 생성하고, CART를 적용할 수 있다.
  • Random Forest(RF) : 여러 개의 DT를 만들고, 주어진 데이터의 클래스를 DT들이 배정하는 다수의 클래스로 결정하는 방식으로 대표적인 앙상블(Ensemble) 기법이다. R에서는 randomForest 패키지에서 이 기법을 제공하며, 본 프로젝트에서는 100개의 DT를 생성해서 사용하였다.
  • Bagging : training set을 계속 랜덤하게 뽑고 완전히 성장시켜 DT를 여러개 만들고, 그 DT들의 변수를 평균한 하나의 DT를 만드는 앙상블 기법. R에서는 adabag 패키지에서 이 기능을 제공 하고 있다. 본 프로젝트에서는 반복 횟수를 100번으로 지정하여 사용하였다.
  • Boosting : 무작위 선택보다 성능이 조금 더 좋은 training set에서 샘플을 뽑아 모델을 학습시킨 후 성능을 평가하는 과정을 반복하는데, 매 단계에서 모델을 생성하기 위해 샘플을 뽑을 때 바로 직전 단계의 모델에서 예측이 틀린 샘플을 더 많이 뽑아서 학습을 시키는 방법이다. 이 기능은 앞서 bagging과 마찬가지로 adabag 패키지에서 제공한다. 본 프로젝트에서는 계산 반복 횟수를 바꾸어 보면서 오분류율이 가장 낮았던 50번 반복한 모델을 이용하였다.

Weighted k-nn

일반적으로 k-nn은 분류를 하고 싶은 하나의 데이터와 거리적으로 가장 가까이에 있는 k개의 데이터의 클래스를 보고, 다수의 클래스에 해당 샘플을 배정하는 방법이다.

Weighted k-nn은 이를 조금 더 발전시킨 방법으로서 가장 가까운 k개의 샘플을 이용하는 것은 같지만, 거리가 가까운 샘플에 대해 가중치를 더 주고, 거리가 먼 샘플은 가중치를 덜 주는 방식이다(보다 자세한 내용은 이 프로젝트에서 사용한 패키지의 기반이 된 논문을 참고). R에서는 kknn이라는 패키지를 제공하고 있다.

k-nn을 사용할 때 가장 중요한 것은 어떠한 변수를 사용할까 하는 것이다. 모든 변수를 사용하게 되면 과적합의 문제가 발생하기 때문에 결과를 예측하는데에 영향력이 큰 몇개의 변수만을 추출했다. 문제는 k-nn 자체는 좋은 변수를 찾을 수 있는 방법이 없다는 것이다. 따라서 다른 데이터마이닝 기법에서 유의하게 나온 변수들의 집합을 이용하는 방법을 사용했다.

변수 집합은 다음의 4가지를 사용하였다.

  • CART의 변수 중요도 상위 4개 변수 : temp-1, temp-2, inflow-1, height-1
  • Bagging의 변수 중요도 상위 4개 변수 : temp-1, temp-2, inflow-1, sun-1
  • Logistic의 변수 유의성 상위 6개 변수 : temp-2, outflow-1, height-3, pH-1, sun-1, sun-sum
  • Random Forest의 변수 상위 4개 변수 :temp-1, temp-2, TN-2, TP-1

각각의 변수 집합을 가지고 총 4 종류의 weighted k-nn을 수행하였으며, 각각의 경우마다 k를 30까지 변화시키면서 오분류율을 측정하여 가장 오분류율이 적은 k^(가장 오분류율이 적은 k가 여러 개이면 과적합을 방지하기 위해 가장 적은 k를 사용하였다)를 사용하였다.

Artificial Neural Network

Artificial Neural Network(ANN)는 딥러닝의 가장 기본적인 형태이다. 입력층의 각 노드가 변수 하나를 나타내고 중간의 은닉층 노드들에서, 이전 층 노드들의 가중치에 따라 logistic 함수를 계산하는 과정이 진행되며, 최종적으로 나오는 출력층의 노드들은 각 클래스에 속할 확률을 나타내게 된다. R에서는 neuralnet 패키지에서 이 기법을 제공하고 있다.

ANN의 경우, 변수의 의미가 중요하지 않기 때문에 주성분분석(PCA)를 통해 분산은 최대화하면서 필요한 변수의 개수를 줄이는 방향으로 추가적인 전처리를 진행했다. 이를 통해 분산의 80%를 설명할 수 있는 9개의 주성분을 입력층의 노드로 설정했다.

이후 은닉층의 수와 노드를 바꾸어가며 모델을 학습시켰는데, 모델간 성능 비교를 위해 사용한 모델은 1개의 은닉층에 각각 3, 4, 5개의 노드를 지정한 경우와 2개의 은닉층에 각각 4개, 2개의 노드를 정한 경우로 총 4가지이다.

ANN을 학습하는데 사용한 최적화 알고리즘은 가중치를 고려한 resilient back-progpagation (rprop+)이다.

회귀(Reregssion)

분류 이외의 또다른 접근법으로는 Chl-a와 남조류의 양을 예측해서 그것이 조류 예보제의 기준에서 조류가 발생한 경우(조류 주의보 이상)인가를 판단하는 방법이 있을 수 있다. 이는 일반적인 회귀분석에 해당하는 방법이다.

Weighted k-nn

앞서 분류에서의 wknn이 조류 발생 여부를 예측하고자 했다면, 회귀에서의 wknn은 해당 데이터 주변의 k개의 Chl-a와 남조류의 양을 평균하여 그 값을 예측되는 값으로 삼는다. 기본적인 알고리즘의 형태는 앞서 분류의 wknn과 동일하며, 변수 집합 또한 위와 동일하다.

다만, 모델의 에측이 끝난후 조류 주의보의 기준을 중심으로 조류 미발생과 발생을 나누어주는 작업이 추가로 진행되었다는 점만 다르다.

분석 결과

training set으로 위의 모델을 구축한 다음 test set으로 모델의 성능을 시험하였다. 이 때 모델 간의 성능을 비교할 수 있는 척도는 오분류율(error)로 을 기준으로 했다. 즉, 미발생한 경우를 발생했다고 분류하거나 발생한 경우를 미발생한 경우로 분류한 경우가 전체에서 얼마나 되는지를 비율로 나타내었으며 적을수록 좋은 모델이다.

한편 본 프로젝트와 같은 클래스 불균형 문제는 비용이 큰 클래스에 대한 에측을 더 정확하게 하는 것이 중요하다. 녹조의 경우에는 미발생한 경우를 발생이라고 예측하는 것보다 발생한 경우를 미발생으로 예측하는 것으로 인한 비용이 분명 더 클 것이다. 따라서 녹조의 발생을 잘 예측하는지 평가하는 지표로 조류발생 오분류율를 또다른 척도로 삼았다. 이는 모델이 조류발생으로 예측한 데이터 중 실제로는 미발생으로 한 데이터의 비율을 나타내는 것이며, 오분류율과 마찬자기로 적을수록 좋은 모델이다.

분류(Classification)

Decision Tree

모델 오분류율 조류발생 오분류율
DT(CART) 0.147 0.378
RF 0.118 0.385
Bagging 0.125 0.356
Boosting 0.077 0.326

DT 중 가장 좋은 성능을 나타낸 방법은 Boosting이다. 전체 오분류율의 경우 0.077로, 백분율로 환산하면 7.7%의 오분류율이다. 조류발생 오분류율도 boosting이 가장 낮았으나 전체 오분류율보다는 많이 높은 편이다.

DT의 형태는 다음과 같다.

DT

나머지 모델의 경우 앙상블 모델이기 때문에 모델의 형태를 위와 같이 표시할 수는 없지만, 변수의 중요도를 뽑을 수는 있다.

각 앙상블 모델과 변수의 중요도 그래프는 다음과 같다.

모델 그래프
RF RF
Bagging Bag
Boosting boosting

공통적으로 중요하게 나오는 변수는 수온임을 알 수 있다.

Weighted k-nn

모델 오분류율 조류발생 오분류율
wknn(CART-4) 0.120 0.504
wknn(Bag-4) 0.114 0.341
wknn(Log-6) 0.147 0.504
wknn(RF-4) 0.131 0.378

wknn에서는 전체 오분류율이 좋은 모델과 조류발생 오분류율이 높은 모델이 달랐는데, 전체 오분류율이 낮은 모델은 Random Forest에서 중요도가 높았던 4개의 변수를 사용해서 돌린 경우이고, 조류발생 오분류율이 낮은 모델은 Bagging의 4개 변수를 사용한 경우다. 평균적으로 DT를 사용한 경우보다 오분류율이 높은 편이다.

wknn의 k에 따른 오분류율과 그에 따라 선택된 k는 다음과 같다.

모델 k 그래프
wknn(CART-4) 10 wknn-cart
wknn(Bag-4) 14 wknn-bag
wknn(Log-6) 14 wknn-log
wknn(RF-6) 26 wknn-rf

Aritificial Neural Network

모델 오분류율 조류발생 오분류율
ANN-3 0.240 0.318
ANN-4 0.259 0.207
ANN-5 0.229 0.293
ANN-4-2 0.348 0.215

ANN 모델의 특징은 전체 오분류율은 높지만 조류발생 오분류율이 다른 두 모델에 비해 낮다는 점이다. 가장 낮은 전체 오분류율을 가진 5개 노드의 은닉층을 가진 ANN은 앞의 두 기법들에 비해 2~3배 높은 오분류율을 가진다. 반면 4개 노드의 은닉층을 가진 ANN은 다른 기법들에 비해 조류발생 오분류율이 약 15% 정도 낮았다.

각 ANN의 모델은 다음과 같다.

모델 그래프
ANN-3 ann-3
ANN-4 ann-4
ANN-5 ann-5
ANN-4-2 ann-4-2

회귀(Regression) : Weighted k-nn

모델 오분류율 조류발생 오분류율
wknn(CART-4) 0.197 0.119
wknn(Bag-4) 0.222 0.111
wknn(Log-6) 0.251 0.089
wknn(RF-4) 0.250 0.163

wknn으로 chl-a와 남조류의 양을 각각 예측한 다음, 조류 주의보의 기준을 데이터를 조류 발생으로 계산했을 때의 오분류율의 가장 큰 특징은 조류발생 오분류율이 분류 모델들에 비해 현저히 낮다는 점이다. 전체 오분류율이 높기는 하지만, 조류 발생을 잘 예측 하는 것의 비용을 고려했을 때 10%가 안되는 조류발생 오분류율을 가지고 있는 로지스틱 상위 6개 변수의 wknn은 현업에서 큰 도움을 줄 수 있을 것이라고 생각이 들었다.

여기서 선택된 k와 RMSE는 다음과 같다.

모델 Chl-a k Chl-a RMSE bacteria k bacteria RMSE
wknn(CART-4) 13 25.301 12 8761.047
wknn(Bag-4) 30 27.998 30 9685.847
wknn(CART-4) 13 22.278 10 9404.507
wknn(CART-4) 16 28.104 24 9908.204

결론

예측 성능

분석에 이용한 모델들의 전체 오분류율과 조류발생 오분류율을 그래프로 나타내면 다음과 같다.

error-graph

전체 오분류율로 보면, 조류 발생을 예측하는 성능은 최대 92%에 달하고, 조류발생 오분류율로 봤을 때도 최대 91%에 달하는 예측 성능을 보였다.

조류 예방 비용과 처리 비용을 잘 고려하여 모델을 선택한다면 조류를 미리 예방하는데 위의 모델이 큰 역할을 수행할 수 있을 것이라고 생각한다.

중요 변수

분석을 하면서 데이터로 부터 얻은 인사이트는 예측에 있어 여러 요인들 중에서도 수온이 가장 중요하다는 사실이다. 그리고 다음으로는 유입량으로 나타났다. 이를 통해 조류 번식의 요인 중에서 수온이 녹조를 발생시키는데 결정적이라는 사실을 유추해볼 수 있다.

제언

이 프로젝트를 진행하면서 예측 성능이 좋은 모델을 개발하고 중요한 변수를 추출할 수 있어 배운 것이 많았지만, 그만큼 아쉬운 것도 많았다.

먼저 데이터의 품질 문제이다. 조류를 예측하기 위해서는 조류를 측정하는 지점의 각종 예측 변수를 얻어야하는데 현재의 측정 시스템에서는 수km 떨어진 곳의 데이터를 사용할 수밖에 없는 구조다. 수십 m 차이로도 수질이 달라지는 강에서는 이러한 측정 장소의 차이는 데이터에 큰 오차를 줄 수 있다. 전반적인 데이터 측정 시스템의 개선이 필요하다고 생각하는 이유이다.

둘째로조류의 심각성에 비해서 조류 측정주기가 너무 길다는 점이다. 녹조 예측뿐만 아니라 근본적인 조류 연구를 위해서라도 1주일에 1회를 측정하고 있는 현재의 주기보다는 주기가 더 짧아질 필요가 있다.

마지막으로 예측 시점에 대한 것이다. 이번 프로젝트에서는 최대 3일 전, 최소 1일 전의 데이터를 사용하였는데 과연 이 정도의 시간이 조류 발생을 예방하기 위한 의사결정을 내리기에 충분한 시간인가는 의문이다. 앞으로 다시 이 프로젝트를 보완한다면 최대 1주일 전의 데이터를 활용해서 예측해보고 싶다.


1. 데이터마이닝의 관점이외에는 수리물리모델을 이용해서 조류와 관련된 엽록소인 클로로필-a를 에측하는 EFDC라는 모델이 있다.
2. 여담이지만 아이러니하게도 남조류는 조류가 아니라 박테리아이다.
3. 환경부, 2013
4. 이 변수를 class 변수로 잡아서 조류 미발생은 1, 조류 발생은 2로 라벨링하였다.
5. 여기서 말하는 순수하다는 것은 어떤 기준을 따라서 집단을 나누었을 때 두 집단이 각각 하나의 클래스로만 존재하는 경우를 말한다. 말그대로 집단이 ‘순수’한 경우이다. 이를 측정하는 측도로 지니계수나 엔트로피를 주로 사용한다.
6. 이 때문에 현업에서는 한 번은 꼭 사용해보는 알고리즘이다.

Dongmin Shin

Word Embedding, Reducing Discrimination on ML, NLP