JUINTINATION
ETRI 2024 동계 연구연수생 - 2주차 본문
2주차 후기
나름 2주차라고 약간 익숙해지기 시작했다. 오전에 전날에 끝내지 못한 코드 리뷰를 마무리할 때쯤이면 입사 동기와 옆 부서 동기 이렇게 셋이서 사내 메신저 단톡방에 올라온 일주일 식단 표를 보며 메뉴를 고민하다가 같이 점심을 먹으러 간다. 점심을 먹고나면 카페에 들러 오후에 마실 커피를 사고 다른 건물을 구경하러 가거나 산책을 하다 돌아와 일을 마저 진행하다 퇴근하는 일상을 반복중이다.
원래 나는 걷는 것을 극도로 싫어하지만 밥을 먹은 후에 산책을 하면 소화도 잘 되는 것 같고 아주 약간의 운동 효과도 느껴져서 요즘은 셋이서 산책하면서 수다를 떠는 것이 즐겁다. 물론 혼자 하라고 하면 재미없다고 안 할 것 같긴 하다.
코드 리뷰
구현한 모델의 loss값이 높게 나와서 고민이었다고 1주차 후기 글 말미에 적어두었었다. 수학과를 나온 입사 동기는 손실된 데이터는 어떻게 복구할 수 있는지, 그리고 데이터의 이상치를 어떻게 지울 수 있는지에 대해 고민이었고 나는 모델에 어떤 문제가 있을 것이라고 생각하고 구글링을 하면서 코드를 몇 번이고 읽고 있었다. 물론 나도 데이터 분석에 대한 의견을 하나도 제시하지 않은 것은 아니다.
사실 박사님이 올려주신 샘플 코드가 있긴 했는데 코드 해석이 쉽지 않았고 돌리기도 전에 오류가 있다고 나와있어서 제대로 읽어볼 생각을 하지 못했었다. 그러나 급할수록 돌아가라는 말이 있지 않은가, 하루 날 잡고 리뷰해 보자는 각오와 함께 코드 리뷰를 시작했다. 차근차근히 읽어보며 기존의 내 코드의 부족한 디테일적인 부분을 채우고 중간중간 데이터를 시각화하여 분석하는 부분을 유심히 살펴보았다. 지금까지 왜 데이터를 분석해볼 생각을 못 했을까? 어째서 막연히 사람들이 주로 구매하는 상품은 계절이나 날짜에 영향이 있다고만 생각했을까? 물론 그러한 부분이 없진 않겠지만 데이터가 나타내는 것은 그렇지 않았다.
어떤 부분이 영향이 가장 큰지는 아직 알아내지 못하기도 했고 이 내용을 이렇게 블로그에 적어도 되는지는 사실 잘 모르겠다. 어쨌든 나와 내 동기는 데이터를 가지고 어떤 상품이 갖는 점수, 즉 영화로 따지면 리뷰 별점 같은 피처를 만들기 시작했다.
엄청난 발견?
우리는 어떻게 상품 구매 데이터가 갖는 피처에 대한 가중치를 정할지 고민 중이었다. "이 피처는 느낌상 중요하다고 생각이 드니까 1에 가깝게, 이 피처는 비교적 덜 중요하다고 생각이 드니까 0에 가깝게 설정해야지" 와 같이 직관적으로 가중치를 설정하였다. 그리고 모델에 넣고 돌린 결과를 보고 나도 모르게 소리를 지를 뻔했다. 이유는 정확도가 약 0.8, 손실값은 0에 아주 가깝게 나왔기 때문이다.
"머신러닝및실습(2) 과제를 할 때도 정확도가 이렇게 잘 나오지는 않았는데.."라는 생각과 함께 이렇게 쉽게 끝날 일이었을까 싶었다. 하지만 바로 직전에 돌려본 모델의 점수는 손실값은 매우 낮게 나왔지만 정확도가 음수가 나왔기 때문에 일단 박사님께 질문을 드렸다.
"박사님, 저 코드 한 번만 봐주실 수 있으실까요? 제가 정확도가 이 정도 나왔는데.."
작성한 코드에 대해 설명드렸다. 어떤 피처에 대한 상품 추천 점수를 이렇게 이렇게 해서 했습니다!
"아 혹시 점수 계산할 때 함수 안에서 스케일러를 쓰셨나요?"
점수 계산 함수
우리는 각 데이터 행에 대한 점수를 구하기 위해 선형 함수를 사용했다. 그 함수 안에서 input_data에 대해 MinMaxScaler를 각각 적용해서 0~1 사이의 값으로 맞춘 후에 가중치를 곱한 값을 더해서 점수를 계산했었다. 이 방식을 사용하면 점수 분포가 다른 방식보다 비교적 고르게 분포되었고 이는 정확도 향상에 도움이 된 것으로 생각하고 있다. 하지만 이 방식의 문제점은 모델이 해당 행에 대한 점수를 예측하여 pred_score를 반환했을 때 이는 사실 pred_scaled_score이며 이를 가지고 원래의 pred_socre값으로 원상복구할 수 없다는 것이다.쉽게 설명하면 우리는 점수를 가중치 a 리스트, input_data x 리스트가 있을 때 a1*x1 + a2*x2 + ... + an*xn = y를 가지고 score를 계산한다. 하지만 x에 어떤 스케일러를 적용하게 되면 a1*scaled_x1 + a2*scaled_x2 + ... + an*scaled_xn = scaled_y가 된다. 이 때 모델이 반환하는 값은 pred_scaled_y가 되고 우리는 이 값과 모든 a 리스트의 값들을 알 수 있지만 pred_scaled_x 리스트의 값을 알 수 없기 때문에 pred_x 값을 당연히 알 수 없다. 따라서 pred_y의 값 또한 알 수 없다.이와 같은 문제가 있다는 사실을 인지하고 곧바로 MinMaxScaler를 점수 계산 함수에서 제외하고 점수를 계산하고 모델을 돌려봤더니 성능은 처참하기만 했다. 점수의 최댓값과 최솟값의 차이가 너무 커서 로그 함수를 적용한 후에 진행해도 마찬가지였다. 또한 우리가 설정했던 각 피처들의 가중치는 오로지 우리의 직관으로만 설정했기 때문에 왜 이렇게 설정했는지에 대한 논리가 부족하다는 문제가 있었고 이전 모델에서 정확도가 음수가 나온 것은 모델이 전부 비슷한 값으로 점수를 예측했기 때문이다.위의 문제점들을 어떻게 해결할까 고민중이었는데 다른 박사님으로부터 메일을 하나 수신하게 된다.
과제 중간 발표
이틀 뒤에 발표를 진행할 예정이니 미리 준비하라는 내용의 메일을 받고 부랴부랴 다음날부터 ppt를 준비했다. 학과 선전부장을 하면서 ppt는 지겹도록 많이 만들었던 경험을 살려 주어진 양식을 사용해서 ppt를 만들기 시작했다.데이터는 어떻게 전처리하였고(이 부분은 더 기여도가 높은 입사 동기가 발표하기로 했다.) 모델은 어떻게 만들었고 어떤 문제가 있어서 어떻게 트러블슈팅했는지(이 부분은 내가 발표했다.) 적어가며 지금까지의 내용을 모두 적었다.
나는 내가 발표는 잘 하는 편이라고 생각한다. 학교에서 과제로 수행했던 어떤 팀 프로젝트라도 모든 파트의 모든 부분에 전부 참여했고 모든 내용을 알고 있었기 때문에 질문에 대한 두려움이 없었기 때문이라고 생각한다.
하지만 이번 발표는 개인적으로 "이놈이 이 돈을 받고 여기서 일을 할 자격이 있는가" 테스트를 받을 겸 진행하는 과제 중간 발표라는 생각이 들었다. 그래서 더 긴장이 돼서 대본을 보며, 큰 테이블에 앉아서 ppt를 직접 넘겨가며 내 파트에 대한 발표를 진행했음에도 말을 좀 절었던 것 같다. 그래도 박사님들이 지금까지 학교에서의 발표 경험과 다르게 내 발표에 집중해주시고 기다려주시고 중요하다고 생각되는 핵심 부분에 대해 조언해주시고 마지막엔 잘 했다고 칭찬까지 해주셔서 너무 감사했고 덕분에 무사히 발표를 마칠 수 있었다고 생각이 들었다. 이 자리를 빌어서 다시 한 번 더 감사하다고 말씀드리고 싶다.
basic_model
발표까지 무사히 마친 우리는 그 날 받은 피드백 내용을 어떻게 적용할지 얘기하다가 일단 기본이 되는 모델을 만들자는 결론에 도달했다. 데이터를 분석하는 기본 모델, 전처리하는 기본 모델, 이런 데이터들을 집어넣고 결과를 반환하는 기본 모델 등을 만들어 코드를 통일해보자는 취지라고 생각한다. 사실 지금까지 모델 연구를 위해 작성한 코드가 엄청 많았고 코드들 제목을 djk_1st.ipynb, djk_test_12.ipynb와 같이 내용을 담는 라벨링을 하지 않았어서 코드를 찾기도 힘들었는데 이렇게 하나로 통일하면 좋을 것 같다는 생각이 들었다.
처음으로 만든 기본 모델은 지금까지 만들었던 코드와 내용은 전혀 다르지 않지만 코드를 깔끔하게 다듬은 모델, 그 다음으로 만든 모델은 train_test_split 메서드를 사용하지 않고 학습 데이터와 테스트 데이터를 최근 6개월을 기준으로 나눈 모델, 그 다음으로 만든 모델은 최근 날짜를 기준으로 0.2 만큼을 테스트 데이터로 나눈 모델이었다. 그 다음으로 만든 기본 모델들은 데이터 분석을 통해 얻은 특징을 기반으로 해당 특징이 의미가 있는지 알아보기 위해 데이터를 여러 개로 찢어 각각의 성능을 테스트하는 모델들이다.
내 코드들을 깃허브에 올려도 되는지 눈치 보느라 여쭤보지 못했는데 만약에 올려도 된다는 허락을 받으면 코드와 함께 왜 이렇게 생각했는지 적어보도록 하겠다. 물론 데이터는 공개할 수 없을 것이 분명하지만..
아무튼 동기가 만든 기본 모델은 당연하게도 데이터 전처리 기본 모델이었고 나는 이 코드를 리뷰해보고 코드를 더 가독성 좋게 메서드별로 하나의 역할만 갖도록 수정하고 이름을 바꾸고 전처리에 시간이 매우 오래 걸렸기 때문에 전처리가 모두 끝난 데이터를 csv 파일로 뽑을 수 있도록 하는 코드를 추가하는 작업을 했다. 그러는 중 금요일 오후에 동기가 점수 계산에 쓰일 새로운 스케일러를 발견하게 되는데..
boxcox
boxcox를 나는 쉽게 설명하자면 분포를 정규분포표에 맞게 스케일링해주는 라이브러리로 이해했다. 실제로 점수를 계산한 이후에 해당 스케일링을 진행하게 되면 scaled_score의 분포가 정규분포표 모양으로 가운데가 우뚝 솟은 모양이 된다. 물론 위에서와 마찬가지로 점수의 최댓값과 최솟값의 차이가 너무 커서 boxcox를 적용하기 전에 로그 함수를 적용하긴 했다. 그러나 점수를 계산한 이후에 스케일링을 진행하는 것이므로 위에서 언급했던 pred_scaled_y에 대해 역스케일링을 진행하여 pred_y를 얻을 수 없다는 문제점도 간단한 함수를 통해 해결된다. 동기가 기본 모델로 돌려본 결과 정확도가 0.5 정도가 나왔다고 하는데 다음주에 실제로 돌려보며 테스트 해봐야겠다.
결론
2주차 후기 결론이다. 아침에 일찍 일어나는 것만 빼면 ETRI 생활은 점점 익숙해져가고 있으며 금요일 퇴근 직전에 잠깐 확인해 본 boxcox에 의해 개인적으로 정확도가 적게 나오는 문제라고 생각했던 점수 분포에 대한 문제점은 어느 정도 해결된 것 같으니 정확도가 낮게 나오는 다른 문제점이 있는지에 대해 생각해 볼 길이 열렸다는 희망이 보이기 시작했다.
에트리 관련 업무, 운동 및 다이어트, 정처기 준비, 개인 공부 모두 정진, 또 정진!!
아 맞다 식당 음식 사진 찍는거 또 까먹었네
'ETRI(한국전자통신연구원)' 카테고리의 다른 글
ETRI 2024 동계 연구연수생 - 6주차 (1) | 2024.02.11 |
---|---|
ETRI 2024 동계 연구연수생 - 5주차 (1) | 2024.02.04 |
ETRI 2024 동계 연구연수생 - 4주차 (2) | 2024.01.28 |
ETRI 2024 동계 연구연수생 - 3주차 (0) | 2024.01.21 |
ETRI 2024 동계 연구연수생 - 1주차 (5) | 2024.01.07 |