대회 개요
엘리스 플랫폼에서 군인들을 대상으로 진행하는 국방 AI 미니경진대회가 열렸다. 캐글, 데이콘처럼 문제 상황을 주고 AI 모델을 이용해 더 정확히 예측할 수록 높은 점수를 받는 대회이다.

주제는 시계열 회귀 (Time-Series Regression) - 공정 프로세스 최종 품질값 예측이었다. 시계열 데이터는 처음 다뤄봤고, 시간의 흐름이 추가되기에 그냥 회귀분석과는 다르게 접근해야겠다고 생각했다.
초 단위로 끊어진 데이터에서 앞으로의 데이터를 예측(10000초의 연속적인 데이터가 있고 앞으로 2000초의 데이터를 예측)하는 것이 일반적인 시계열 예측대회의 구성이다. 근데 이 대회는 특이하게도 앞으로 몇 초가 아니라 중간중간 비는 데이터를 Submission Data에 넣어 예측하도록 구성했다. 일반적인 시계열 대회와 다르다는 것을 깨달았다.
접근 방법 1
먼저 전처리를 진행했다. raw_df는 85개의 input과 30개의 output으로 이루어지고, submission_df는 85개의 input과 NaN 값을 갖는 30개의 output으로 이루어져있다. 일단 85개의 input을 모두 사용하지 않을 예정이다. 그래도 문제에서 권하는 필요없는 input column을 제거하는 코드를 작성했다. column_names에 Setpoint가 들어있다면 그 column을 drop한다. 그러면 raw_df와 submission_df는 55개의 input을 갖게 된다.
# Setpoint를 가진 column 제거
including_Setpoint = []
column_names = list(raw_df.columns)
for i in range(len(column_names)):
if "Setpoint" in column_names[i]:
including_Setpoint.append(i)
raw_df.drop(raw_df.columns[including_Setpoint], axis=1, inplace=True)
submission_df.drop(submission_df.columns[including_Setpoint], axis=1, inplace=True)
다음으로 raw_df와 submission_df를 합쳤다. 보통 AI 대회에서는 상상하지 못할 일이다. 합친 후 index 오름차순으로 (시간 순으로) 정렬했다. 총 11000행의 데이터가 나왔고, output열은 드문드문 비어있게 된다. 즉, 예측해야 할 output의 가장 가까운 이전시간 output와 다음시간 output은 높은 확률로 1초 전 데이터, 1초 후 데이터라는 것이다.
result = pd.concat([raw_df, submission_df])
result = result.sort_index(ascending=True)
tag1 = []
for i in range(len(result.columns)):
if result.columns[i].find('Stage1')==-1 and result.columns[i].find('Stage2')==-1:
tag1.append(i)
result.drop(result.columns[tag1], axis=1, inplace=True)
result
접근 방법 2
행마다 탐색하며 output이 NaN으로 찍혀있다면, 투포인터 마냥 그 행에서 위, 아래로 가면서 output 데이터가 있는 행을 찾는다. 찾았다면 각각 toput1, toput2에 저장하고, 행 번호는 l, r에 저장한다. 못 찾았다면 toput1, toput2는 -1이다.
toput1, toput2 중 적어도 하나는 -1이 아니므로, 둘 중 하나가 -1이라면 -1이 아닌 데이터로 예측한다. 만약 둘 다 구했다면, 내분점을 구하면 된다. 내분점은 아래와 같은 공식으로 구했다.
pnt = 0
for i in range(result.shape[0]):
if np.isnan(result.iloc[i,0]):
for j in range(result.shape[1]):
toput1 = -1
toput2 = -1
toput = 0
top = 0
l = 0
r = 0
for k in range(i-1,-1,-1):
if not np.isnan(result.iloc[k,0]):
toput1 = result.iloc[k,j]
l = k
break
for k in range(i+1,result.shape[0]):
if not np.isnan(result.iloc[k,0]):
toput2 = result.iloc[k,j]
r = k
break
if toput1==-1:
toput=toput2
elif toput2==-1:
toput=toput1
else:
# 내분점 구하는 공식
if toput1 < toput2:
toput = toput1 + (toput2-toput1)*(i-l)/(r-l)
else:
toput = toput2 + (toput1-toput2)*(r-i)/(r-l)
if j < 15:
stage1_sub_pred[pnt][j] = toput
else:
stage2_sub_pred[pnt][j-15] = toput
pnt+=1
stage1_sub_pred
대회 결과

2등으로 마무리하며 갤럭시탭 S8+ 키보드에디션 512gb (약 180만원)을 받게 되었다. 이후에 input 데이터를 활용하고자 n차 차분과 lasso 모델을 활용했는데, 위 예측보다 좋은 점수를 받지 못해 결국 모델을 사용하지 않고 제출했다. 이런 방식은 보통의 시계열 예측에서는 쓸 수 없기에, 어떻게 보면 잔머리를 써서 높은 성적을 받은 것이다. 그래도 시계열 데이터에 대한 관심을 갖고 공부도 하게 되어 좋은 시간이었다.
'후기' 카테고리의 다른 글
2022 LG CNS 코드몬스터 최종합격 후기 (0) | 2023.03.25 |
---|---|
2023 성균관대학교 프로그래밍 경진대회 후기 (0) | 2023.03.06 |
2022 SKKU 프로그래밍 대회 in 소프트의 밤 후기 (1) | 2023.01.12 |
2022 군장병 코딩경진대회 후기 (국방오픈소스아카데미 주최) (0) | 2022.09.11 |
2022 2회차 쇼미더코드 후기 (0) | 2022.07.04 |