우선 저번 글에 간단하게 말했지만 이 프로젝트(대회)의 목적과 배경부터 다시 짚고 넘어가도록 하겠다.
1. 대회 소개
우선 데이콘에서 공개한 대회의 배경과 목적은 다음과 같다.
[배경]
최근 기후변화로 인해 홍수 등의 자연재해가 지속적으로 발생함에 따라, 홍수 피해를 최소화하여 국민의 생명과 안전을 지키는 댐의 역할은 매우 중요해지고 있음.
팔당댐은 한국수력원자력(한수원)이 관리, 운영 중인 댐으로, 서울 및 수도권의 홍수 방어에 있어 최후의 보루 역할을 하고 있음.
팔당댐의 홍수 안전운영에 따른 서울시내 한강 주요 지점(잠수교 등)의 수위를 예측함으로써, 홍수재해로 인한 피해를 미연에 방지하고 최소화할 수 있을 것으로 기대됨.
[목표]
팔당댐 방류에 따른 서울시내 한강 주요 다리 수위예측
출처:https://dacon.io/competitions/official/235949/overview/description
위의 작성된 그대로, 홍수 등의 자연재해를 대비하기 위한 댐의 운영을 보다 정확하게 하기 위하여 한강의 주요 지점들의 수위를 예측함에 따라 그 수위에 맞게 운영을 더 잘해보자. 이런 목표인 것 같다.
결과적으로 대회의 정확한 주제를 정리해 보면 다음과 같다.
평가 대상 기간: 2022.06.01~2022.07.18
목적: 한강에 위치한 잠수교,한강대교,행주대교,청담대교의 수위를 10분 전에 예측.
평가지수: RMSE / R_Squared_Score
이 대회의 특이한점?은 대회는 7월 25일부터 진행됐기 때문에 test data인 6.1~7.18의 정답은 사실상 이미 관측되었고 수집 가능 하다는 점이었다. 이에 이번 대회는 data leakage 문제를 매우 조심하면서 해결해야 하는 문제였다.
그런데 나는 어차피 대회기간이 끝난 후 진행하였기에 데이콘에서 제공하는 데이터기간과 다른 것을 사용해서 프로젝트를 진행하고자 했다.
나는 프로젝트의 주제를 다음과 같이 설정하였다.
2013년~2022년의 데이터를 학습하여 2023년 한강의 4개 다리의 수위를 예측하고자 함
이제 본격적으로 데이터 수집을 진행해 볼 것이다.
2. 데이터 수집
우선 어떤 데이터가 제공되는지 확인해 보자.
데이콘에서 대회 시작시 원래 제공되는 데이터는 다음과 같다.
[팔당댐] 현재수위, 유입량, 저수량, 공용량, 총 방류량
[청담대교, 한강대교, 행주대교, 잠수교] 수위, 유량
[강화대교 조위]
[대곡교,진관교,송정동] 강수량
위의 데이터들이 column에 들어있으며, ymdhm이라는 관측시점을 나타내는 column까지 총 17개의 column이 기본적으로 포함되어 있다.
다음과 같은 이유로 나는 데이콘에서 제공되는 데이터를 사용하지 않고, 직접 데이터를 수집하여 프로젝트를 진행하였다.
우선 데이콘에서 지금은 데이터제공이 중단되었을 뿐 아니라, 나는 내 코드를 다른 사람들이 쉽게 사용할 수 있도록, 재현할 수 있도록 하고 싶었고 이 대회뿐 아니라 개인 프로젝트도 동일한 데이터로 진행할 예정이었기 때문이다.
코드는 모두 Github에서 확인 가능하기 때문에 중간중간 설명하고 주의할 것만 설명하고 넘어가고 어떻게 코드를 실행하는지 등만 작성하겠다.
2-1 Collect_data.py
우선 데이터 수집을 담당하는 파일은 code 폴더 안에 있는 `Collecet_data.py`이다.
데이터는 바다누리해양정보서비스(강화대교 조위), 한강홍수통제소(그 외)에서 api를 이용하여 수집하였다.
코드의 뼈대는 데이콘의 코드공유의 Redix6 님의 코드를 뼈대로 삼았다.
다만 여기다가 좀 더 사용자가 원하는 데이터를 쉽게 추가하고, 다운로드할 수 있도록 설정하였다.
2-1-1. api key 발급 및 설정
우선 한강홍수통제소와 바다누리해양정보서비스 에서 간단한 절차를 거쳐 api키를 발급받는다.
이후 code 폴더 안에 `. env`라는 파일을 생성 후에 다음과 같이 api 키들을 등록해 둔다.
(api키를 " " 로 감싸지 말고 그대로 붙여 넣어야 한다.-> `load_dotenv`함수를 통해 api를 불러올 것이다)
2-1-2. 수집할 데이터 선택
다음으로 code 폴더 안에 있는 `data_source.txt`안에 자신이 수집하고자 하는 데이터를 양식에 맞게 작성해 준다.
(반드시 양식을 지켜야 하며, 이름과 숫자 같은 경우는 한강홍수통제소에 적힌 이름, 고유코드들을 입력하면 된다.)
2-1-3. 실행
이제 세팅은 끝났으므로, `Collect_data.py`를 실행시켜 준다.
그럼 어떤 데이터(bridge, dam, rf, tide)를 수집할지 고르고 시작일, 종료일을 고르면 데이터가 수집된다.
api를 이용하여 수집하기 때문에 시간이 조금 걸린다.
데이터는 전부 월별로 수집되며 한강홍수통제소에서 수집되는 데이터들은 모두 10분 간격(데이콘과 동일)하며 바다누리해양정보서비스에서 수집되는 강화대교 조위의 경우 1분 단위의 데이터기 때문에 수집되는 과정에서 10분 단위로 변환해 준다. 수집이 완료되면 data폴더가 생기고 다음과 같은 구조를 띄고 있을 것이다.
2-2 Prepare_data.py
다음으로 code 폴더 안에 있는 `Prepare_data`를 실행할 차례이다.
위에서 확인했듯이, 데이터가 전부 연도별로 수집되어 있고, 각기 다른 폴더에 저장되도록 구성하였다.
우리가 좀 더 편리하게 다루기 위해서는 이 데이터들을 모두 하나로 합쳐야 한다. 이 과정을 진행해 주는 것이 Prepare_data이다.
우선 이 파일은 90%짜리 완성 코드이다. (사실 내 성격이 이래서 그런 거지 이 정도면 충분한 거 같긴 하다.)
무슨 말이냐 하면 앞의 `Collect_data.py`는 사용자가 `data_source.txt`만 바꿔주면 따로 코드르 수정할 것이 없이 데이터를 수집할 수 있었는데, `Prepare_data.py`의 경우 기본 세팅대로 안 할 경우 코드를 수정해줘야 한다. (사실 매우 쉽지만 너무 귀찮다.. )
무슨 말이냐 하면 우선 Prepare_data에서는 2가지 작업을 수행한다. 첫 번째는 데이터 병합, 두 번째는 수위->해발고도 변환이다. 첫 번째는 이해가 될 테고 두 번째는 무엇이냐.
이전에 데이터를 직접 수집하고 데이콘에서 제공해 주던 데이터와 비교했더니 수위값들이 모두 달라서 이상했었다.
출처가 다른 것인지 아니면 뭔가 잘못한 것인지 생각했었는데 데이콘에서 해답을 얻을 수 있었다.
데이콘에서 사실 `수위`라고 했던 것은 실제로 말하면 `수위`가 아닌 `해발표고`이다.
위 사진에서 보면 행주대교의 한강 바닥 높이가 80이다. 이때 `수위`가 180mm라 하면, `해발표고`는 180+80=260mm가 된다. 정확한 정의를 찾아보면, "평균 해수면으로부터 출발하여 표시한 높이"를 의미한다. (우리나라의 경우 표고(평균해수면수위) 기준을 인천에 두고 그 지점을 0이라 한다.
수위(수위관측소의 수위표 중 0m 기준 하천수위)+ 각 수위관측소의 0점 표고(수위관측소 수위표 0m의 해발표고)
=해발표고(해당 하천수위를 해발표고로 환산한 수위) - 출처: https://www.nanumtip.com/qa/123744/
아무튼 각설하고 즉 우리가 예측하는 것은 해발표고이고, api를 이용하여 수집한 데이터는 수위 데이터이기 때문에 수위에서 해발표고로 변환을 해줘야 한다. 변환은 간단하다. 각 대교마다 한 시점의 해발표고와 수위를 구해 그 차이를 알아내고 그 차이를 수집한 데이터에 추가해 주면 된다. 아래가 코드에서 해당 부분이다.
def preprocessing(source, data_storage):
# 수위값을 해발표고 값으로 변환
# 한강홍수통제소에서 수위<->해발표고의 차이를 비교하여 개별 튜닝해야 함.
if (source == 'bridge'):
calc = {"jamsu": -6.8, "cheongdam": 174.7, "haengju": 80.3,
"hangang": 207, "gwangin": 528, "paldang": 557.0,
"jungnang": 917,"jeollyuri":-10}
for i in data_storage:
data_storage[i]['wl'] = data_storage[i]['wl'].replace(' ', '0')
data_storage[i]['wl'] = data_storage[i]['wl'].astype('float')
data_storage[i]['wl'] = data_storage[i]['wl']*100 + calc[i]
data_storage[i].columns = ['ymdhm', 'wl_'+i, 'fw_'+i]
elif (source == 'rf'):
for i in data_storage:
data_storage[i].columns = ['ymdhm', 'rf_'+i]
return data_storage
그래서 만약 내가 기본제공되는 `data_source.txt`에 없는 데이터를 수집하였다면 한강홍수통제소에서 그 차이를 확인한 다음 코드들을 수정해줘야 한다.
요약: 추가적인 데이터를 받았거나 기본 데이터를 제외했다면 `Prepare_data.py`에서는 각종 코드를 수정해줘야 함.
기본적으로 [잠수교, 청담대교, 행주대교, 한강대교, 광진교, 팔당대교, 중랑교, 전류리]를 모두 건드리게 되어있어 제외하는 경우에도 수정해줘야 한다.
이 파일도 그냥 실행하면 나오는 대로 선택하면 전처리가 모두 완료되고 data 폴더 안에 `full_data.csv`가 생성된다.
3. 데이터 확인
모든 데이터 수집 및 기본 전처리를 마쳤다면 아래와 같이 생성된 `full_data.csv`를 확인할 수 있다.
위에서도 말했지만 나는 데이콘과 동일한 기간을 사용하지 않고 아래와 같은 기간으로 프로젝트를 진행하였다.
데이콘: Train: 2012.01.01~2022.05.31 Test:2022.06.01~2022.07.18
나: Train:2013.01.01~2022.12.31 / Test: 2023.01.01~2023.09.31
이제 데이터 수집을 마쳤으니, 다음 글에서는 EDA와 데이터 전처리를 진행하도록 할 것이다.
'프로젝트 > 수위 예측' 카테고리의 다른 글
선행시간에 따른 잠수교 수위 예측 (0) | 2024.01.10 |
---|---|
한강 수위 예측 - 모델링 및 평가 (0) | 2023.12.15 |
한강 수위 예측 - 데이터 EDA, 전처리, Feature engineering (1) | 2023.12.14 |
한강 수위 예측 - 프로젝트 시작 (0) | 2023.12.13 |