본문 바로가기

회고

AI 부트캠프 3달 차 : 웹페이지를 만들어 배포하다

🚀 Intro

3달차에는 conda, pipenv, 도커 등으로 가상환경을 만들고, Git으로 원격 레파지토리에서 팀 단위로 협업할 수 있는 방법,
SQL(sqlite, Postgresql)과 NoSQL(MongoDB)로 데이터베이스를 구상하고 이를 클라우드 환경에서 관리하는 방법,
파이썬 언어로 Flask로 웹앱을 만들고 데이터베이스와 연결하여, heroku를 통해 배포하는 과정을 배웠다.

정말 빡센 과정이었다...! 하지만 웹서비스를 기획하고 만드는 건 생각보다 내 적성에 맞는다는 걸 깨달은 달이기도 했다.


📊 데이터셋 선정

다양한 데이터셋을 다뤄보는 게 포트폴리오에 좋을 것 같아서
2달 차에 다룬 영화 데이터 말고 다른 데이터를 다뤄보고 싶었으나 촉박한 프로젝트의 일정상,
영화 데이터를 이용해 머신러닝 기반으로 영화를 추천해보는 페이지
를 만들기로 했다.

동기분들 중에서도 영화 추천 알고리즘을 주제로 한 분들이 꽤 많으셨다..!

 

🤔 사이트 기획

스코페 2021 코딩테스트에 나온 왓챠 문제 알고리즘에 착안해,

  • 유저별 장르 선호도 정보 입력
  • 유저가 영화를 봤는지, 관심 있는데 아직 안 봤는지,
    아예 안 본 건지를 구분하여 관심 있는데 아직 안 본 영화를 추천
  • 노출 위치는 아래 사진과 같이
    추천 순위가 높은 영화가 윗줄+왼쪽에 오게 구현하고 싶었다.

대략 아래 사진과 같은데,

왓챠의 탐색하기 버튼을 누르면 나오는 것처럼
장르별 / 영화 키워드별 / 국가별로 영화를 분류하고, 해당 키워드를 누르면 영화가 추천되도록 하고 싶었다.

 

프로젝트 첫날에 만들어 본 화면 설계

 

하지만 그러려면 유저 정보가 필요했는데... 이건 섹션 3에서 배운 내용보다 더 나아간 거라,
일단 영화 자체 데이터(장르, 배우, 수상내역, 키워드 등)로 다른 영화와의 유사도를 측정, 이걸 바탕으로 영화를 추천하는 방식을 택했다.

(하지만 동기분들 프로젝트를 보니 회원가입 기능을 만들고,
유저별 선호 데이터를 따로 테이블을 만들어 받은 분들이 많아서 반성
했다. 배운 것만 하려고 하지 말자!)

(하지만 회원가입 기능을 안 만들었기에 영화 기반 추천 서비스에 더 집중할 수 있었던 듯싶긴 하다 ^^,,, 일단 할 수 있는 것부터 차근차근 하는 것도 나쁘지 않지...)

 


🍃 데이터베이스 선택

 

나는 몽고디비에 관심이 많았기에 데이터베이스를 몽고디비 클라우드 환경으로 구성하고 싶었다.
3달 차의 수업은 대부분 sql 기반으로, flask로 웹앱을 만드는 걸 배울 때도 sqlite + flask-sqlalchemy 를 사용해 배웠다.

 

하지만 이번 프로젝트에서는 sqlite가 파일 데이터베이스라 개발할 때만 사용함하고, 로컬 환경에 종속되기 때문에 다른 데이터베이스 사용을 권장했는데, Postgresql은 뭔가 정감이 안 갔다... ㅋㅋㅋㅋㅋㅋ

 

1년 전 기획했던 프로젝트에서 사용한 스택인 몽고디비를 사용해보고 싶었는데,

몽고디비로 flask 앱을 만들 때는 아예 사용하는 ORM 패키지가 flask-mongoengine으로 달라지고
쿼리 방식도 달라진다.

db.inventory.find( { status: "A", qty: { $lt: 30 } } )

몽고디비는 쿼리를 이렇게 딕셔너리 형식으로 해서 살짝 겁먹었는데,

 

flask-mongoengine의 쿼리는 저거보다는 좀 쉽다.

searchbyid = Movie.objects(imdbID=imdbid)
#Movie는 몽고디비의 테이블

이런 식으로 할 수 있다.

 

그리고 몽고디비는 데이터가 고정되지 않은 NoSQL 방식이라 딕셔너리 형태의 데이터를 스키마(테이블에 들어갈 데이터 형식)을 지정하지 않고 넣을 수 있지만, 이를 ORM방식(사용하는 프로그래밍 언어로 데이터베이스에 쿼리를 날릴 수 있도록 하는 것, sqlalchemy와 flask-mongoengine 등의 패키지)으로 사용하려면 스키마를 만들어주어야 한다. 그리고 이때 테이블 구성을 잘해야 에러가 나지 않는다. 이에 대한 글은 https://aimb.tistory.com/176 에 기재해놨다.

Flask App 만들기

 

몽고디비로 flask app 어떻게 만들지 했는데,

https://dev.to/paurakhsharma/flask-rest-api-part-1-using-mongodb-with-flask-3g7d

이 사이트에 찬찬히 몽고디비를 사용해서 Flask App을 만드는 방식이 파트 7까지 있다.
파트 2까지만 봐도 기초 수준으로 앱을 만들 수 있다.
(파트 3 이후부터는 REST API 형식으로 코드를 짜고, 회원가입 기능, 보안 관련 기능을 추가하고 pytest를 만든다.)

 

그렇게 만든 사이트는 다음과 같다.

 

👩‍🎤 메인

📽️ 영화 검색

영화의 키워드, IMDb id, 영화의 영문 제목으로 영화를 검색하면

영화이름과 연도, 해당 정보가 카드 형식으로 나온다.

 

🎬 영화 추천

영화 추천은 어떻게 할까... 했는데

섹션 2에서 시도해보려다 겁먹은 캐글 고수의 영화 추천 알고리즘을 보면서 모델을 만들었다.

https://www.kaggle.com/ibtesama/getting-started-with-a-movie-recommendation-system

 

영화의 키워드, 장르, 배우, 감독, 수상 실적 텍스트를 합쳐 하나의 칼럼으로 만들고

 

sklearn의 CountVectorizer로 해당 텍스트를 단어별로 분석해 등장여부, 출현빈도를 벡터화한다.
(저렇게 단어별로 인덱스값을 만들고, 등장 여부와 빈도를 세로 행렬로 만든다.)

그다음 cosine_similarity 방식으로 영화별 유사도를 측정, 가장 유사한 영화를 추천하는 알고리즘이다.

 

이를 바탕으로 제작한 추천 화면은 다음과 같다.

 

입력한 영화는 가로로 긴 카드고,

추천 영화는 세로 형식으로 긴 카드다.

 

통일하는 게 미관상 좋을 거 같았지만 가로세로 카드 다 만들어보고 싶었다...!

 

사실 저 카드 형식은 프로젝트 마지막 날 오전에 구현했다.


 

⌛일정 관리

 

이번 프로젝트 진행 시에는 저렇게 매일 Task Card를 만들어
오늘 해야 할 일의 리스트를 적고 해결하면 [v] 표시를 했다.

 

4일 차까지 몽고db를 통한 삽질의 연속이어서 4일 차까지는 Postman을 써서 url로 http 메소드 기능을 넣고,
페이지 기능 구현은 5일 차에야 시작했다.

이만하면 됐나? 싶어도 이것도 더 하면 좋을 거 같은데, 이 기능 넣으면 좋을 거 같은데 싶어

6일 차 아침까지 사이트를 좀 더 보기 편하게 만들려고 했다.

 

그리고 그 결과로 좀 더 👨‍💻유저 친화적인 페이지가 된 거 같아서 뿌듯하다.

 

처음에는 머신 러닝 모델 기반으로 추천된 영화가 페이지에 텍스트로만 떠도 기쁨의 환호성을 질렀는데,

 

 

계속 붙잡고 노력하다 보니 텍스트 형식으로 받아온 영화 타이틀로
어떻게 다시 데이터베이스에 쿼리를 날려 포스터와 연도 정보를 가져올까?
를 고민하고

유저들이 흠... 이 영화 이만하면 괜찮은데? 볼까? 라는 생각이 들 수 있도록
정보를 줄 수 있을지 고민하고, 방법을 찾게 되었다.

자세한 구현 방법은 따로 포스팅하겠다.

 

🔍 검색의 힘

모르는 것은 웬만하면 영어로 구글링하면 스택 오버플로우에 나왔는데, Flask로 몽고디비를 사용하는 경우는 pymongo, flask-mongoalchemy, flask-mongoengine의 3가지 경우의 코드가 약간씩 달라서 혼란스러운 경우가 많았다.

flask-mongoalchemy와 flask-mongoengine의 차이

그러다 보니 삽질을 많이 했는데...

정작 나도 이 블로그로 삽질의 결과 알아낸 것들을 한글로 쓰고 있으니,
다음에는 꼭 막히는 부분에서는 한글로 검색도 같이해야겠다 싶다.

 

📤 배포

배포의 경우, 동기분들이 굉장히 많은 오류를 겪고 힘들어하시면서 팁을 알려주셨는데,
그 덕분의 거인의 어깨에 올라 처음부터 heroku에서 지원하는 파이썬 버전(3.8.8)으로 가상환경을 만들어
별다른 오류 없이 배포할 수 있었다.

프로젝트 마감일 전날 밤 10시? 11시에야 배포를 시작하며 할 수 있을까... 싶었는데

 

[AI웹 프로젝트] Heroku에 Flask 배포

6단계만에 Flask App HEROKU에 배포하기

 

두 블로그의 힘으로 30분 만에 배포를 성공할 수 있었다...! 끼야호...!

하지만 페이지를 수정하고 다시 배포하다 보니 처음으로 오류를 겪었는데,

 

왜인지 app:app이 app:apps로 수정되어 있어 오류가 일어났다.

 

코딩은 오타와의 싸움이라더니...!

 

🕸️ 도메인

포비피엠 바에서 선망하는 개발자분을 만나 얘기를 나누다가, 그분이 F-Rated를 아시냐고,
같이 프로젝트를 할 의향이 있냐고 물어보셨었다. 나는 2020 버터나이프크루에 지원하며(떨어졌다),
2019년 버터나이프 크루 프로젝트였던 F를 찾아서 를 눈여겨봤던 터라 좋다고 했지만,

정작 그분과는 뉴스레터 작성을 같이 하게 되었다... ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

지금에야 하는 깨알 홍보...

 

IT알못도 IT에 한 걸음 한 걸음씩 다가갈 수 있도록, 매주 화요일에 찾아가는 1 STEP 뉴스레터

구독해주세요...!

 

무튼 나는 그 후 며칠 안 지나서 f-rated.com 도메인을 샀었다.

일단 만들고 싶은 서비스가 생기면 도메인부터 산다..ㅋㅋㅋㅋ

 

호스팅 케이알이 제일 싸길래 거기서 샀는데,
헤로쿠에서 제공하는 기본 도메인은 https 방식이라 호스팅 케이알에서 바로 연결이 안 된다.

 

이것도 몇 번 찾아보다가 적용이 안되서, 그냥 헤로쿠 기본 도메인으로 적용하고 낼까 했는데,
도메인도 사뒀는데 일단 해보자 싶어서 계속 검색어를 바꿔 찾아봤다. 이번엔 한국어로 검색 ㅋㅋ

https://m.blog.naver.com/kbs4674/221446015988

그리고 다음 블로그를 참고해서 도메인 연결을 했다. 사이트가 좀 페이지를 바꿔서 헷갈릴 법도 한데...!
시간이 되면 별도로 헤로쿠 도메인을 연결하는 방법을 포스팅하겠다.

 

그래서 나온 결과물은 www.f-rated.com 에서 확인하실 수 있습니다...!

 

 

✍️ 회고

데이터를 노가다 방식으로 추가하기보다, 유저가 IMDb 영화 id만 입력해도 API에서 정보를 받아와 데이터베이스에 저장하고, 사이트에서 바로 보여질 수 있도록 하기 위해 파이썬 함수를 열심히 짰다.

아직 클래스 상속도 정복 못 한 나지만, 자동화를 하기 위해 기능 설계 시 개별 파일보다는 함수를 적극적으로 활용하고, 수업 내용에서는 제대로 이해하지 못했던 Postman의 사용 방식도 부딪혀보면서 익히고,

Postman에서 더 나아가 직접 사이트에서 데이터를 넘기고 구현하는 방식
유저 친화적으로 만드는 방법을 고민하면서 많이 성장한 듯하다.

 

삽질을 많이 하다 보니 원하는 기능이 구현될 때마다 너무너무 기뻐서 환호성을 질렀는데,
하다 보니 개발이 나랑 잘 맞는 것 같다는 생각도 들었다. (아직 아는 것은 티끌만 하지만....)

데이터 분석할 때는 느껴보지 못한 쾌감이라 신기하다.

하지만 딥러닝까지 배우고, 앞으로 남은 과정을 배우면 머신 러닝과 AI를 배운 입장에서 얻는 이점이 있을 것이기에,
쭉 마지막까지 달리면서 💻개발도 커리어 중 하나로 염두에 두려고 한다.


 

⏲️ 시간 관리

1달 차 후기에도 언급한 내용인데,

부트캠프를 시작하면 부트캠프 외에 사적인 건 다 끊는 게 정신건강에 좋다... ^^....

 

나는 매주 애니 더빙 번역을 하고, 격주로 뉴스레터 작성을 하는데,

각각 주마다 12시간 정도의 시간이 걸린다. (글 빨리 쓰고 싶은데 못써...흑흑...)

애니 더빙은 순 작업 시간만 계산했을 때 12시간이라, 주말을 꼬박 투자해야 겨우겨우 납기를 할 수 있었다.

애니 더빙 1-2주 차에는 주말에 복습도 제대로 못 했는데,
이번 달 수업 내용이 결코 만만하지 않았기 때문에 수업 내용을 못 따라가니 위기감이 느껴졌다.

마감이 매주 월요일 아침 9시여서, 월요일 아침 5시에 일어나 번역을 마무리하고 납기하고,

그 후로 못한 공부를 마무리했다. (강제 미라클모닝...)

이번 주말에도 일당 4시간씩 작업을 한 후, 남는 시간은 모조리 프로젝트에 썼다.

(순 작업 시간은 4시간인데... 10시부터 앉아서 시작해도 5-6시에 번역을 끝낼 수 있는 시간의 매직....)

무튼 그래서 막 부트캠프를 시작했거나, 앞으로 관심이 있는 사람이라면, 다시 한번 말한다.

부트캠프 외에 모든 것은 끊고 부트캠프를 시작하자...^^...

이번 더빙은 7편을 매주 납기하기로 계약이 된 거라 울며 겨자 먹기로 프로젝트 기간에도 했는데,
앞으로 프로젝트 기간에는 절대.... 절대 일 안 할 거다......


 

 

🗄️ API의 중요성 (데이터베이스 소스의 중요성)

2달 차에는 데이터베이스를 찾다가 기껏 전처리에 몇 시간을 소모해도 나온 결과물이 뭔가 부족한 데이터셋이라,
계속 아쉬움에 데이터를 찾아 헤멨었는데 api와 크롤링에 답이 있었다...

열심히 구글링을 해서 애초에 최대한 많은 정보를 주는 api를 찾고,
부족한 점은 다른 패키지나 소스를 찾아서 충당하니 데이터셋으로 고민할 일이 별로 없었다.

 

나는 다음의 두 소스를 사용했다.

Rapid Api - Movie Database (IMDB Alternative) (일 1000건 사용 가능)

IMDbPY (사용 제한 없었던 것 같음)

 

사실 MongoDB에서 제공하는 샘플 영화 데이터가 저 api 소스와 같은데, 좀 더 전처리가 된 버전이다.
(데이터 타입이 전처리가 되어 잘 구분되어 있다.)

그 데이터가 탐나서 전처리를 해보겠다고 시간을 들여봤는데... 결과적으론 전처리 1도 안 해도 됐었다.

내가 사용할 머신러닝 모델은 텍스트 기반이었기 때문...!

무작정 전처리를 하려고 생각하지 말고, 사용할 모델에 필요한 데이터만 전처리해서 시간을 아끼자.


 

🤜 앞으로

더 다양한 데이터셋을 다뤄보고 싶어졌다.

자바스크립트를 다뤄봤으면 요새 핫한 TypeScript도 써보는 게 좋다는데, 다음에 웹앱 만들 일 있으면
타입스크립트를 써봐야겠다.

 

1-3달의 프로젝트 시, 매번 다 프리미어로 무음 구간, 말 꼬이는 부분을 편집해서 편집 시간만 한 시간씩 걸렸는데
너무 발표 영상에서 완벽하려고 하지 말자. 발음 꼬여도 괜찮다. 나중의 프로젝트 발표 영상은 편집을 최소화할 것..!

 

많은 동기분들이 로그인 기능을 구현해 유저 정보를 받아오셨다.

내가 생각하고 구현을 포기한 걸 해내시는 동기분들 너무 대단하다.
나는 안 배운 거라고 만들 생각도 안 했었는데, 미리 한계짓지 말고 부딪혀 봐야겠다.