2021 ICT 멘토링 한이음 공모전 후기(A to Z) - 대상 수상

길다면 길고 짧다면 짧았던 한이음 공모전이 마무리되었다. 사실 포스터에는 공모전이 8/2 ~ 8/30 까지라 나와있지만 이는 접수기간이고 실질적으로 준비 및 평가, 전시까지의 기간은 대략 4/5 ~ 12/3로  약 8개월의 과정이라고 볼 수 있었다. 사실 8개월의 과정동안 매주 팀원들과 만나서 더 나은 서비스를 위해 고민하고 힘들게 준비하면서도 수상에 대한 큰 기대는 없었고 잘해봐야 은상이나 동상을 받겠다 생각했지만, 감사하게도 대상🏆(과학기술정보통신부장관상)이라는 큰 상을 받게 되었다. 아무튼 이렇게 마무리를 하고 회고 겸 한이음에 참가를 고려하는 다른 멘티들에게 도움이 되고자 프로젝트의 시작부터 마무리까지의 모든 과정들을 적어보려고 한다. 아무래도 이 프로젝트에서 얻게 된 가장 큰 경험은 서비스(MLops)의 end to end 경험이라고 생각한다. 분석에 필요한 데이터도 직접 일일이 다 구해야 되었고 그 raw한 데이터를 직접 처리하고 유의미한 데이터 또한 우리가 직접 만들어내야 했으며 사이트 구축, 제공하는 기능 셀계 및 제작, 인공지능 모델 구축 등 정말 말 그대로 무에서 유를 창조해야 되는 상황이었으며 이 모든 과정(데이터 수집부터 서비스 제작 및 배포)을 직접 다 경험할 수 있어서 굉장히 좋은 프로젝트였다고 생각한다. 이런 과정들을 하나도 빠짐없이 공유하려고 한다.

프로젝트 시작 (4월)

일단 이 프로젝트는 지인의 추천으로 시작하게 되었다. 아무래도 3학년인데 아직 외부 프로젝트 경험이라고는 하나도 없어서 경험이라도 해보자 라는 마음에 시작하게 되었다. 한이음 프로젝트는 특이한 점이 있다. 바로 프로젝트 당 1명의 멘토가 붙는다는 것이다. 그에 따라 한이음 참여 방법에는 두가지 방법이 있었다. 첫번째는 멘토가 주제를 올려서 해당 주제에 관심을 가지는 멘티들이 신청하여 프로젝트를 진행하는 것이고 두번째는 멘티가 주제를 올려서 멘토 및 멘티를 모집하는 경우이다. 우리는 첫번째 방법을 통해서 진행했다고 볼 수 있다. 사실 4월일때만 해도 컴퓨터비전(CV)에 관심이 많을 때라 개인적으로는 여러 개의 CV 프로젝트를 지원했었지만 별다른 소식이 없었고 프로젝트 신청 마감일에 같은 학교 동기들이 자연어처리(NLP)를 주제로 프로젝트를 해보자해서 지원하게 되었다. 사실 그때만 해도 자연어처리라고는 기본적인 흐름만 알고 직접 프로그래밍을 진행하거나 다루어본 적이 전혀 없어서 걱정되긴 했다. 그래도 이번년도 목표는 프로젝트를 하나라도 잘 마무리하여 경험을 쌓자는 마인드라서 바로 지원을 했던 것 같다. 그렇게 1명의 멘토와 나를 포함한 3명의 멘티가 하나의 팀을 이루게 되었다.

그렇게 프로젝트가 시작되었다. 사실 내가 예상한 이 프로젝트의 진행 구조는 멘토가 과제를 내어주고 그 과제를 해결해가며 하나의 프로젝트를 완성해나가는 구조였다. 하지만, 실제는 완전히 달랐다. 멘티가 자발적, 주도적으로 해나가며 그 과정에 있어서 멘토는 어려운 점에 대한 조언을 해준다든지 대체적인 흐름을 잡아준다든지 약간의 도움을 주는 느낌으로 진행되었다. (멘토마다 다르지만 대게 이런 방식으로 진행된다.) 그때 당시에 있어서 좀 실망스러웠던 부분이었지만 지금 생각하면 이보다 더 좋은 방식은 없었던 것 같다. 아마 멘토가 주도적으로 프로젝트를 진행했더라면 수상은 어려웠을 것이고 수상했더라도 지금보다 성취감이 크진 않았을 것 같다. 아무튼 이렇게 프로젝트를 시작하고 나서 첫 미팅 때의 결론은 자연어처리(NLP)에 익숙해지기 였다. 앞에서 말했듯이 사실 우리는 자연어처리를 제대로 해보지 않은 사실상 초짜였기에 기본적인 자연어처리에 대한 개념, 흐름도를 인지하는 것이 우선이었다. 그래서 아마 4월 한달동안은 자연어처리를 공부하는데에 매진한 것 같다.

자연어 처리 공부는 각자 알아서 진행했다. 멘티들끼리는 학교 동기이기도 하고 친해서 좀 각자 과제를 정해서 매주 해결하는 강제적인 분위기보다는 자율적인 분위기에서 알아서 공부하는 것이 더 좋을 거라 판단하여 각자 시간나는대로 공부를 진행했던 것 같다. 먼저 공통으로 ‘인프런’에서 IMDB 데이터를 통한 기본적인 NLP 실습을 진행했다. 이 강의를 들으면서 개인적으로 느낀 점은 ‘바닥부터, 기초부터 공부해야겠다’ 였다. 아무런 배경지식, 기본이론도 없는 상태에서 급하게 실습을 진행하니 머리 속에 들어오는 것도 없었고 마음만 급한 상태였던 것 같다. 그래서 나는 개별적으로 ‘위키독스’의 ‘딥 러닝을 이용한 자연어 처리 입문’을 통해 공부했다.

지금 생각해도 좋은 선택이었던 것 같다. 자연어 처리 입문에 필수 독서라고 자신있게 지인에게 추천할 수 있을 정도이다. 기초 이론부터 실습까지 진행해주며 설명까지 잘 되어 있어 자연어처리를 공부하는 데 있어서 굉장히 많은 도움이 되었다. 아무튼 이런식으로 자연어 처리에 입문하고 기초 지식부터 실습까지 대략 6월까지는 프로젝트를 진행하며 별도로 추가적인 공부를 진행했던 것 같다.

프로젝트 설계 및 진행(5-6월)

서비스 계획, 데이터 수집 및 검증

4월 한달동안은 NLP 개별 공부 이외에 사실 크게 프로젝트 관련하여 진행한 부분은 없었다. 어느정도 NLP공부를 진행하고 있는 도중 5월에는 좀 자세한 프로젝트 계획 및 우리가 하고자 하는 서비스가 무엇인지 그려나가는 것이 필요하다 생각되어 기존의 주제에 맞게 서비스 설계에 들어 갔던 것 같다. 일단 우리의 큰 주제는 ‘NLP를 이용한 사용자 경험 분석 및 사용자 맞춤형 추천 시스템’ 이었다. 말 그대로 사용자들이 쇼핑을 하면서 많은 시간과 고민 없이 원했던 상품에 대한 분석 결과(리뷰 분석)를 제공받고 추가로 사용자들에게 도움이 될만한 상품을 적절하게 추천해주는 서비스(쇼핑몰)이다.

이런 주제를 선택하게 된 계기는 사실 우리들의 경험에서 시작되었다. 쇼핑몰을 이용할 때의 경험을 토대로 생각해보면 일단 원하는 상품을 구매하기 위해서 리뷰가 좀 많은 상품에 들어가서 이 상품에 대한 평을 내린다. 하지만 역설적이게도 많은 리뷰들 중 많아야 10개 이상을 읽지 않고 이 상품에 대해 판단해 버린다. (시간은 시간대로 투자하고 고민은 고민대로 늘어났던 경험이었다.) 우리는 이러한 문제점들을 개선하고 싶었다. 상품에 대한 리뷰를 확인할 때, 많은 시간을 투자하지 않아도 분석된 결과를 통해 빠르고 효율적이게 상품에 대한 파악이 완료되게 하고 싶었다. 이렇게 주제를 정하고 우린 이런 큰 주제를 좀 세부적으로 들어가기 시작했다. 먼저 어떤 도메인에서 이 주제를 적용할 것인가를 생각해보았다. 아무래도 리뷰를 분석하고 추천하기에 적합한 도메인은 쇼핑몰이라고 생각이 들었고 쇼핑몰의 상품에 달려 있는 리뷰들을 분석하여 정보를 제공하고 분석해 놓은 다른 상품을 추천해주는 방향으로 가자고 결론을 지었다. 어떻게 보면 당연한 결정이기에 도메인 결정에는 큰 어려움이 없었다. 그 후 우리가 제공하고자 하는 예상 기능들에서 간략히 논의해 보았다. 이 때 당시 생각했던 기능들은 ‘리뷰요약’, ‘카테고리화’ 이다. 리뷰요약은 말 그대로 수 많은 리뷰들을 한 문장으로 요약해 주며 어떤 부분들이 중요문장이고 장단점은 어떤 것인지 문장에 하이라이트하는 기능(추후 XAI로 발전)이었고 카테고리화도 말 그대로 상품의 특징 및 평가를 단어들로 표현하는 카테고리화였다. 그 때 당시에는 사실 어떻게 구현할 건지에 대한 구체적인 계획없이 이런 기능들이 있으면 좋겠다고 생각하여 뱉은 아이디어들인데 이걸 구현하고 더 발전 시켰다는 것에 좀 자부심이 느껴지는 것 같다.

초기 기능 계획 예시 (왼쪽: 리뷰 요약, 오른쪽: 리뷰 하이라이트) 초기 기능 계획 예시 (왼쪽: 카테고리화, 오른쪽: 키워드화)

이 때 당시에 가장 큰 문제는 ‘데이터’였다. 감성분석(긍부정 분류)을 위해 모델이 필요했는데 이 모델을 학습하기 위해선 데이터가 필요했다. 물론 오픈데이터들도 꽤 있지만 우리가 원하는 도메인에 걸맞는 데이터는 없었기에 직접 구해야 하는 상황이 발생했다. 이 시기부터 데이터의 중요도를 좀 느꼈던 것 같다. 데이터를 구하기 위해서 여러 사이트를 찾아보았지만 기본적으로 리뷰 데이터를 제공하는 사이트는 없었고 직접 우리가 가져와야하는 구조였다. 이때 생각했던 것은 ‘Crawling’이었다. 하지만, 크롤링도 공식적으로 지원하는 사이트가 없었고 크롤링을 시도 해도 다 막혀서 직접 리뷰 데이터를 복사해서 가져오는 방법밖에 없었다. (추후에는 다시 crawling으로 해결..) 그래서 좀 더 편한 방법을 사용하기 위해 매크로를 통해 복사해 오도록 만들어보았었다. (지금 생각하면 왜 그렇게 무식하게 했는지 모르겠다ㅋㅋ) 아무튼 이런 방식을 통해 일주일동안 취침시간에 매크로를 돌리며 각자 10만개(총 30만개)의 데이터를 모았었다. 하지만 또 다른 문제가 있었다. 이 데이터들을 학습에 이용하려면 라벨링이 필요했으며 알다시피 리뷰 자체의 긍부정 비율은 심할정도로 불균형이다. (리뷰를 보통 나쁘게 보다는 좋게 쓰는 경향이 있음) 라벨링을 일일이 다 할 수는 없는 상태라 오픈소스로 제공되는 LSTM 긍부정 분류 모델을 통해 라벨링을 진행하고 불균형문제는 사실 리뷰데이터 특성상 문맥이 주는 중요도 때문에 Augmentation이 힘들어 데이터를 상대적으로 적은 부정 리뷰의 개수에 맞추었다. (과소표집)

리뷰 평가 불균형(부정적인 리뷰가 5%밖에 되지 않음, 출처: 11번가)

그 결과 직접 수집한 30만개의 데이터 중 학습에 이용할 수 있는 데이터는 3만개 밖에 되지 않았다. 이 순간 정말 하루도 빠짐없이 노력해서 수집한 데이터의 10분의1 밖에 쓰지 못한다는 사실에 좀 절망적이었던 것 같다. 아무튼 이러한 데이터로 train test 데이터로 나누고 우리가 간단하게 설계한 LSTM을 통해 평가해본 결과 90% 이상의 긍부정분류 정확도를 보여서 그나마 긍정적이게 마무리하며 쇼핑몰에서 직접 가져온 데이터를 통해 학습을 진행하고 해당 모델을 통해 여러 리뷰 데이터의 긍부정 분류를 진행해도 된다고 판단했다 (데이터 검증). 이때까진 우리가 제대로 된 서비스를 구체적으로 구상하지 않고 일단 우리가 상품군을 정하고 그 정해진 상품에 대해서만 분석결과 및 상품추천을 해주는 방향으로 설정했었다. 즉, 사용자가 원하는 상품에 대한 분석결과 및 추천에 대해서는 고려하지 않았다. 이는 추후에 크롤링이 가능해져서 구현하기로 결정했던 것 같다. 이때까지만 해도 우리 서비스는 사용자와 상호작용하는 서비스라기 보다는 그냥 ‘우리가 원하는 상품들만을 분석했다~’ 의 일방적 제공의 서비스로 매력도 경쟁력도 없는 서비스였던 것 같다. 이렇게 서비스 및 기능 계획, 데이터 수집, 데이터 검증까지 거친 후 학교일정에 따른 중간고사 기간이 되어 6월 한달동안은 거의 진행하지 못했던 것으로 기억한다.

프로젝트 중간점검 대비 및 공모전 준비(7-9월)

계획된 기능 구현 및 개발

사실 본격적인 프로젝트 준비는 중간고사가 끝난 이후 7월부터 진행됐다고 생각한다. 먼저 우리는 지금까지 계획했던 기능들에 대해서 구현하기 시작했다.

먼저, ‘리뷰 하이라이트’ 기능에 대해서 토론하고 구현하기 시작했다. 우리가 처음 생각했던 리뷰 하이라이트는 리뷰에서의 중요 문장, 장단점을 표시하는 기능이라고 계획을 세웠지만, 이와 관련된 기능이 XAI(설명가능한 인공지능)라는 것을 알아내고 XAI를 쇼핑몰 리뷰라는 도메인에서 구현하는 것에 집중했다. 아무래도 우리는 리뷰를 긍부정으로 분류하는 것에 초점을 맞추었고 분류했을 때의 그 분류 근거가 무엇인지리뷰 자체에 하이라이팅을 통해 표현하고 싶었기에 이런식으로 진행했던 것 같다.

XAI, 리뷰 하이라이팅 예시

이와 같이 리뷰에서 어떤 단어 및 문장으로 인해 부정 혹은 긍정 으로 분류가 되었는지 리뷰 자체에서 보여주고자 했다. 이를 기존에는 LSTM으로 구현하고자 했지만, 문맥을 이해하는 모습을 보이는듯 했으나 스스로 서로의 단어들의 균형을 맞추고자 즉, 값을 보정하고자 의미없는 단어의 값들이 튀는 단점을 확인하고, 비록 단순하여 문맥의 흐름을 파악하지는 않고 단어들만의 특성을 고려하여 안정적인 값을 보여주는 DNN을 선택하게 되었다. (실시간으로 데이터를 받아와 분석하는 측면에서도 경량화에 이득이기에 선택한 부분도 있음) 이는 Mecab을 통해 형태소 분리를 진행한 후 각각의 형태소가 긍정 문장, 부정 문장에서 나온 비율을 통해 임베딩을 진행한 후 학습 과정에서의 각 Input layer마다 Output layer에 미치는 영향 값을 계산해서 각각의 형태소를 수치로 표현하도록 했다. 그 후 실험적으로 임계값을 설정한 후 임계값을 벗어나는 형태소를 시각적으로 표현하여 구현하였다. 물론 이 시기에 만들어 둔 DNN은 완전히 초기 버전으로 이후에도 도메인에 맞는 모델을 위해 한 수십번은 개선했던 것이 기억난다. (개선 과정은 10-11월 달에 진행, 추후에 설명)

다음은 ‘키워드 추출’이다. 우리는 키워드 추출을 통해 구매자가 선택한 중요 특성이 아닌, 사용자의 경험(리뷰)을 토대로 설정된 상품의 주요 특징들을 제공하고 싶었다. 키워드 추출같은 경우 다양한 오픈 소스들이 있었다. 이들 중 대표적으로 토픽모델링(lda)를 사용해 보았지만 아무래도 문서에 최적화된 기술이기에 우리 도메인에 맞지 않아 결과가 좋지 않았다. 그래서 우리는 직접 키워드 추출 알고리즘을 개발해 보기로 했다. 키워드 추출은 ‘명사 필터링’, ‘최빈 명사 추출’, ‘명사 중요도 판단’ 으로 총 3가지로 진행된다. Mecab 라이브러리를 통해 형태소를 분석하여 명사인 단어들만을 고려(상품의 특성을 보통 명사이므로)하고 그 단어들을 리뷰에서 많이 언급된 순으로 정렬한 뒤 그 단어가 주어로 사용되는 지를 판단하는 등 여러가지 판단 기준을 세워 중요한 단어들의 순위를 매겨 키워드를 설정하게 되었다. 이 알고리즘을 개발하는 과정은 모든 것을 경험적으로 판단해야 했고 리뷰라는 특정 도메인에 딱 맞게 개발해야 된다는 이유 때문에 생각보다 어려웠고 꽤 오래 걸렸던 것으로 기억한다. 추후에는 이 키워드를 최종 목표인 긍부정 수치로 만족도를 표현하였다. (ex, 배송 96%, 사이즈 67%, 신축성 30%, … )

키워드 추출 예시

그 다음으로는 ‘리뷰요약’ 기능이다. 사실 ‘문장요약’은 자연어처리에 있어서 굉장히 핫한 토픽이라고 할 수 있다. 문장요약은 ‘추출적요약’, ‘추상적요약’ 두가지로 구분할 수 있다. 이들 중 우리는 좀 더 혁신적으로 추상적요약을 통해 리뷰 요약을 구현하려 하였다. 문서 요약에서 사용되는 seq2seq+attention을 이용하려 하였지만 추상적 요약은 말 그대로 새로운 문장을 생성해내는 것이기에 상당히 많은 학습데이터를 요구하였고, 기존에 공개되어 있는 데이터같은 경우 여러 뭉치의 리뷰를 요약하는 것이 아닌 하나의 문서를 요약하는데 초점을 맞춘 데이터였기에 우리가 가지고 있는 리뷰 데이터에는 적합하지 않았다. 그래서 직접 새로운 알고리즘과 인공지능 모델을 만들어 여러 테스트를 진행했다. 가장 기본적으로 진행한 것은 LSTM을 통해 기존의 리뷰들의 흐름을 파악하고 이 모든 리뷰들의 흐름을 요약해서 문장을 추출하는 쪽으로 진행을 해보았다. 하지만 이는 흐름을 잘 파악하지 못하고 계속해서 이상한 리뷰만을 추출해내서 LSTM을 n-gram형식의 1D CNN구조로 변경하여 진행하였다. 결과는 만족스러웠다. 하지만 결론적으로 말하자면 이는 문장 생성이 아닌 추출 쪽에 가까웠다. 우리가 짠 모델은 사실 리뷰들의 전체적인 의미와 흐름을 파악한다기 보다는 각 리뷰에서의 자주나오는 순서 및 단어들만 학습하여 그 다음으로 나올 가장 그럴싸한 단어들을 이어서 하나의 문장으로 추출해주는 것밖에 하지 못한 것이다. 결국 추상적 요약에는 한계가 있다고 판단하고 우린 추출적 요약으로 기능을 구현하자고 결정하였다.  추출적 요약 또한 이미 구현된 많은 오픈소스들(ex, TextRank)이 있었다. 하지만 이들은 대부분 문서요약으로 하나의 큰 토픽을 바탕으로 이어지는 문장들에 대한 요약으로 우리 도메인에는 맞지 않은 기능들이었다. 그래서 직접 TextRank라는 오픈 소스를 참고하여 개발했다. 이는 모든 단어들의 의미를 고려하기 위해 word2vec으로 임베딩을 진행한 후 그 임베딩 수치들의 cosine similarity를 측정하여 계산해냈다. 이 과정에서는 ‘평균’ 이라는 측정 기준이 존재하는 데 이를 여러가지에 걸쳐 표현하기에 좀 어려움이 있었던 것 같다. 단어들의 임베딩값의 ‘평균’을 통해 문장의 임베딩 값을 표현하였고 그 문장들의 임베딩값들의 ‘평균’을 통해 기준 문장을 설정했다. 그 다음으로 이 기준 문장과 가장 유사한 문장을 해당 키워드의 대표 리뷰 (요약된 리뷰)로 설정한 것이다.

‘배송’ 이라는 키워드의 대표 리뷰

이 또한 추후 웹으로 표현하는 데에 있어서 더 효율적으로 정보를 제공하기 위해 수많은 개선 과정을 거쳤다.

마지막으로는 ‘상품추천’이다. 해당 상품을 분석해준 후 그 분석 결과를 통해 상품을 추천해주는 것, 결론적으로 우리가 제공하고자 하는 서비스의 도착지라고 할 수 있다. 사실 상품 추천을 사용자의 로그를 통해 얻어온 정보를 통해 해주는 경우가 많은 데 우리는 이러한 데이터를 직접 받아올 수 있는 상황이 아니라 좀 다른 시점인 컨텐츠 기반 상품 추천을 구현해 보았다. 키워드 추출을 통해 나온 키워드 중 사용자가 원하는 키워드를 선택하면 해당 키워드를 기준으로 상품을 추천해준다. 이는 키워드 만족도를 통해 평균 만족도가 높은 순으로 상품을 추천하도록 구현하였다.

상품 추천 예시

이 이외에도 굉장히 세부적으로 다양한 기능들이 있었지만, 우리의 주요 기능들에 대해서만 세부적으로 언급하고 넘어가려 한다.

이렇게 7-9월은 우리가 생각해둔 기능들을 구현하는데에 온전히 시간을 보낸 것 같다. 아무래도 이 시기가 방학이기도 하고 시간적으로 좀 여유가 있어서 추가으로 NLP를 공부하며 구현에 집중할 수 있었던 것 같다. 사실 이 시기만 해도 우리의 기능은 거의 완성이라고 생각했었다. 하지만 실제로 웹을 구현하고 사용자들에게 서비스를 제공한다는 측면에서의 우리 기능은 상당히 부족했다. 그래서 아무래도 웹을 구현하며 기능들의 성능이나 접근성등을 고려하여 많은 개선 과정을 거쳤던 것 같다.

프로젝트 공모전 평가 및 최종(10-11)

웹 구축 및 기능 개선

앞서 말한대로 사실 공모전 접수(9월) 이전까지만 해도 우리는 사용자가 상호작용할 수 있는 서비스가 아니었다. 하지만 공모전 접수 때 우리의 서비스는 일방적 제공이 아닌 사용자가 원하는 분석을 제공하는 서비스로 바뀌었다. 그 중심에는 바로 ‘Crawling’이 있었다. 이 부분 같은 경우 웹 제작하는 과정에 있어서 개선된 부분이므로 이 파트에 적게 되었다. 앞에서 언급한 것처럼 프로젝트 시작 시에는 크롤링에 대해서 여러 시도를 거쳤지만 성공하지 못했고 그 상태에서 계속 프로젝트를 진행하게 되었다. 하지만 공모전 접수 직전에 우리의 서비스가 너무나 경쟁력 없고 효율적이지 못해 사용자와 상호작용할 수 있도록 크롤링을 추가해야 된다는 것을 필연적으로 느꼈다. 그래서 우리는 다시 크롤링을 시도하게 되었다. 필수로 해야 된다는 마음가짐 때문이지는 몰라도 결국 하루정도를 온전히 투자해서 방법을 찾아 내었다. 역시 ‘하면 된다, 안하면 안한거다.’ 라는 말이 괜히 있는 것이 아니었다. 아무튼 이렇게 크롤링을 성공한 후 우리는 사용자가 URL을 입력하면 그 URL을 통해 상품정보와 리뷰 데이터를 실시간으로 가져올 수 있도록 설정했다. 이게 아마 우리가 수상에 한발짝 더 가까워진 계기가 아닌가 생각한다. 크롤링을 성공한 후 장점은 이뿐만이 아니었다. 이제 우리도 직접 매크로를 통해 복사 붙여넣기식 형식의 데이터 수집이 아닌, 크롤링을 통해 더 빨리 더 많은 리뷰 데이터를 자동으로 수집할 수 있게 되었다. 이를 통해 우리는 기존의 모델을 학습시키기 위한 500만개의 리뷰데이터를 추가적으로 얻을 수 있었다. (하지만 데이터 불균형으로 인해 실질적으로 사용한 리뷰데이터는 약 50만개이다.) 아무튼 이렇게 크롤링을 성공하고 대략적인 서비스의 흐름을 생각해 놓은 후 웹 구축에 나섰다. 사실 이 프로젝트에서 가장 큰 문제점 중 하나가 웹 구축이었다. 팀원 모두가 인공지능쪽을 전공으로 하고 있어 웹이나 앱 이런 쪽으로는 한번도 경험이 없었기에 약간의 막막함이 존재했기 때문이다. 이는 한이음에서 제공하는 블랜디드 강의를 통해서 해결했다. 블랜디드 강의는 스파르타 코딩클럽에서의 강의들이었는데, 정말 많은 도움이 되었었다. (백엔드 쪽 뿐만 아닌 부가적인 공부에도 도움이 되었음)

아무래도 이 모든 것을 팀원들이 동시에 진행하기에는 시간이 부족하여 프론트엔드, 백엔드, 클라우드 이렇게 3파트로 나누어서 진행했다. 나는 주로 백엔드를 맡아 진행했다. 처음에는 Flask를 간단히 배워 진행했지만, 간단한 웹 구축에는 Django가 더 편해 Django를 이용했다. 강의가 생각보다 실무적으로 필요한 요소들만 골라 알려주다 보니 생각보다 쉽게 구축을 할 수 있었다. 이렇게 한달 간 공부 및 실습을 진행하며 차근차근 웹을 구축해 나갔던 것 같다.

하지만 웹을 점점 구축하다 보니 확연히 드러나는 2가지 문제점이 있었다. 첫번째는 ‘속도’이다. 아무래도 실시간으로 데이터를 크롤링해오고 분석하다 보니 사용자가 URL을 입력하고 분석결과를 받는 데 까지는 이때까지(최적화 전)만 해도 1분이 넘게 걸렸다. 이는 접근성 측면에서 굉장히 불편할 수 밖에 없는 요소이다. 원하는 것을 얻는데 까지 1분이상이 걸린다는 것은 서비스 측면에서는 말도 안되는 것이었다. 결국 우리는 크롤링, 분석 두가지 모두 속도 개선 및 최적화가 필요했다. 먼저 크롤링은 병렬처리를 통해서 해결을 했다. 결론적으로 크롤링 즉, 데이터를 긁어오는 시간은 40초에서 3초 내외로 줄였다. 결론만 보면 굉장히 쉬워 보이지만 사실 난 이 과정이 가장 힘들었던 과정이었다고 생각이 든다. 그 이유는 바로 그 어디에서도 장고에서 크롤링 시 병렬처리를 하는 방법이 기재되어 있지 않다는 것이다. 항상 처음 접하는 기술(?), 구현 등은 구글링을 통해 해결해 왔는데, 이는 아무리 찾아봐도 자료가 없었다. 그래서 정말 힘들었던 기억이 있다. 이는 세부적인 문제에서 큰 문제를 풀어 나가는 과정을 통해 해결했었다. 세부적으로 먼저 장고에서 병렬처리를 어떻게 해야될지, 또 장고에서 크롤링은 어떤 방식을 했었는지, 함수의 적용은 어떤과정을 통해서 해결해야되는지 등 한 5가지로 문제를 세분화하고 차근차근 해결하다보니 ‘장고에서 병렬처리로 크롤링하기’라는 큰 문제는 자동으로 해결되어 있었다. 아마 이 부분이 프로젝트에서 얻은 가장 큰 경험이지 않을까 생각한다. (+ ‘하면 된다, 안되면 안한거다!’)

그 다음으로는 분석부분의 최적화에 들어갔다. 분석 부분은 또 머신러닝부분과 알고리즘 부분으로 볼 수 있었는데, 사실 머신러닝 부분은 이미 실시간에서의 결과를 산출하는 것을 고려하여 DNN이란 가벼운 모델을 선택했기에 크게 수정할 부분은 없었고, 알고리즘에서의 최적화가 가장 중요해 보였다. 여기선 문장분리가 가장 문제였다. 문장분리는 우리 기능에 모두 사용될 정도로 핵심이었는데 이는 기존의 오픈소스로 제공하는 KSS를 사용했었다. 하지만 KSS딥러닝 기반으로 되어 있다보니 가동시간이 너무나 오래걸렸다. 그래서 우리는 이를 우리가 직접 문장분리기를 개발하여 사용하게 되었다. 아마 이 부분이 분석파트에서 속도를 크게 줄인 큰 요인이 아닐까 생각한다. 이외에는 우리가 생각보다 코드를 잘 짠 것인지, 속도를 개선하기 위해 수정할 부분이 크게 없었고 사용하지 않는 변수나 효율성을 좀 높이는 수준에서 최적화가 마무가 되었다. 결론적으로 로컬에서 사용자가 URL을 입력하고 해당 상품의 정보 및 리뷰 분석을 받는데 까지는 1분 -> 15초내외로 크게 줄이게 되었다. (아무래도 크롤링이 느린 속도의 가장 큰 요소였던 것 같다.) 추가적으로 서비스를 위해 클라우드 및 서버가 필요했는데, 이는 AWS EC2를 이용하였다. 서비비용같은 경우는 한이음에서 프로젝트 당 120만원 정도 지원을 해주는 데 이를 통해 해결하였다.

이제 최적화까지는 마무리했다. 하지만 여기서 또 문제가 있었다. 기존에 계획하고 구현해 놓았던 기능들을 웹에 적용하고 보니 너무나 부족한 점들이 많았다. 각각의 기능들이 주는 효과들을 체감할 수 없었으며, 시각적으로 와 닿지 않는 점 등 단점들이 눈에 너무나도 많이 보였다. 그래서 우리는 또 기능들을 개선해 나갔다. 여기서는 사실 기능들의 성능을 개선하기 보다는 기능들의 요소요소를 사용자 입장에서 효율적으로 개선해 나갔다고 하는 게 맞는 것 같다. 먼저 키워드 추출과 리뷰 요약을 연결지으며 정보를 제공하였다. 기존에는 그저 키워드를 보여주고 이에 해당하는 대표리뷰를 보여주는 방식으로 진행을 했었지만 여기에 사용자가 좀 더 효과적으로 상품을 이해할 수 있도록 각 키워드의 만족도를 표현해주고 그 만족도에 따른 대표 리뷰를 선정하였다. 예를 들면 배송이 90%의 만족도라면 90%에서 15%의 범위 안에 있는 리뷰들만을 고려하여 대표리뷰를 선정한 것이다. 이렇게 함으로써 좀 더 사용자에게 효과적으로 정보 전달이 될 뿐더러 기능 자체의 성능은 덤으로 올라갔다. 다음은 상품 추천이다. 이는 사실 웹적인 요소를 수정했다. 기존에 상품추천은 현재 대다수의 쇼핑몰의 상품추천과 마찬가지로 이 상품을 왜 추천해주었는지 근거를 제시해 주지않고 그냥 추천해 주었다. 이는 추천 받는 사용자의 입장에서 효율적인 쇼핑을 제공하지 못한다고 판단되어 우리는 근거를 제시해보자고 결정했다. 사용자가 선택한 키워드의 만족도를 표시해주며 상품 추천에 있어서 어떤 키워드가 더 반영이 잘 되어있는지를 보여줌으로써 사용자의 이해도를 높이고자 노력했다. 이렇게 직접 우리 기능들을 웹에 적용함으로써 사용자의 입장으로 보니 단점들이 수두룩 했고 10월중순까지는 이들을 개선하는 데에 시간을 대부분 사용한 것 같다.

이렇게 어느정도의 서비스를 구축해 놓고 우린 공모전 최종평가를 위해 거의 2주간 현재까지 구현한 기능들에 대해서 성능을 개선하고자 노력을 했다. 가장 중요하게 성능을 올리고자한 대상은 ‘리뷰 하이라이팅(XAI)’이었다. 아무래도 문맥을 고려하지 않고 단어만을 고려한 DNN모델이기에 완벽하지 않은 성능을 보였기에 개선이 필수였다. 우린 마무리까지의 이 2주동안 굉장히 많은 고민과 노력을 했던 것 같다. 다양한 임베딩 방법을 적용하고 임계값을 계속해서 수정하기도 해보고 데이터를 바꿔보기도 했지만 결론적으로 가장 좋은 성능을 낸 방법은 추가적인 필터 알고리즘을 적용한 것이었다. 앞서 말한 것처럼 DNN에서의 XAI의 문제점은 문맥을 고려하지 않고 단어만을 고려한다는 점이다. 우린 이 단점을 먼저 보완하고자 했다. 그래서 결과적으로 나온 수치들을 tri-gram으로 묶어 해당 값들의 max값과 평균을 취해 문맥을 고려하며 해당 단어들을 이어주고 값을 안정화 시켰다. 이 필터링을 통해 굉장한 성능향상을 얻게 되었다. 물론 XAI 분야 자체가 정확한 수치로써 성능차이를 보일 수 없다는 점이 아쉽지만, 우리가 직접 확인했을 때 해당 리뷰의 분류 근거를 확실히 보여주었다. 이렇게 성능 향상까지 마무리한 후 우린 최종평가를 받았다. 사실 최종평가에서는 우리의 서비스를 소개하는 발표를 진행했었는데, 발표는 잘 마무리되었지만, 그때까지만 해도 우린 좋은 상을 기대하고 있지는 않았다. 하지만 발표를 마무리하고 나와서 우리 모두가 후회는 없다고 생각했다. 매주 만나면서 토의하고 고민하고 노력했으며 끝까지 최선을 다했다고 생각했기 때문이다. 그렇게 우리는 후회없이 결과만을 기다렸었다.

[최종 결과 웹사이트 캡쳐본]

키워드 추출, 만족도 평가 및 대표 리뷰

리뷰 긍부정 분류 및 리뷰 하이라이팅(XAI), 키워드화

키워드 선택 및 상품 추천

리뷰 선택 시 확인할 수 있는 리뷰 상세 분석 페이지, 해당 리뷰의 키워드 만족도와 자세한 XAI 수치 및 유사리뷰 확인 가능

TREND 분석

프로젝트 결과 발표 및 엑스포(12)

평가 후 얼마 지나지 않아 결과가 나왔다. 사실 우리에게 있어서 이 결과가 나오기까지의 매일매일이 긴장의 순간이었다. ‘아 은상은 받지 않을까..? 아니다, 다른 팀들보니깐 우리보다 잘했더라.. 동상까지만 바라자, 아니지 우리도 노력하고 완성도 있게 잘 만들었잖아. 은상은 받겠지’ 그 4-6일동안 이 생각의 반복이였다. 그리고 결과가 나왔다.

결과 발표

정말 이 결과 발표 순간은 아직도 생생한 것 같으면서도 아직도 꿈만 같다. 정말 발표 후 한 2시간 동안은 꿈을 꾸고 있는 듯 했다. 우리는 계속 ‘우리가 대상이라고..??!’를 반복하며 즐겼던 것 같다. ㅋㅋㅋ

결과 발표 후 간단한 준비 후 킨텍스에서 전시회(엑스포)에 참여하게 되었다. 엑스포에서는 시상식과 작품설명이 진행되었다. 해당 엑스포는 링크를 통해 다시볼 수 있다.

이렇게 우리의 길다면 길고 짧다면 짧은 8개월은 마무리 되었다.

Team Talk_with