Fast api로 머신러닝 기반 웹사이트 만들고 배포하기
- Link
- https://aimb.tistory.com/21225
고양이 사료 추천 시스템 만들기 : 여러 아이템 기반 추천(Item-item collaborative filtering)을 만들면서
웹사이트를 만드는 데는 Python + Fast API,
DB는 MongoDB,
배포는 heroku로 진행하였다.
Fast API를 사용한 이유는 다음과 같다.
- 성능이 뛰어나고 빠르다
- 배우기 쉽다
- 코드작업이 빠르다
- 에러가 적다
MongoDB는 다음의 이유로,
- json 형태로 데이터를 쉽게 넣을 수 있다
- 데이터의 확장이 용이하다(열 추가)
Heroku는 촉박한 프로젝트 일정 상, 배포가 빠르다는 이유로 선택하였으나 다음 프로젝트는 꼭 AWS로 배포를 해보고 싶다.
Fastapi는 다음의 간단한 코드로도 웹 화면을 만들고 띄울 수 있다.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
그리고 JinJa2나 Boostrap을 활용하여 웹사이트를 꾸밀 수 있다.

처음에 고양이 정보를 등록하는 페이지. 버튼과 폼, 링크가 들어간 텍스트를 사용했다.
고양이 정보를 등록하면, 해당 고양이가 평가한 사료가 사료 평가 데이터베이스에 저장된다.
평가는 아래의 페이지에서 할 수 있다.

별점은 폼 형식으로 쉽게 고를 수 있게 만들었다. Fast API에서 사료 이름을 form으로 어떻게 받아올까 하다가, 아예 사료 이름을 form 형식으로 넣어버리니 쉽게 받아올 수 있었다. 미관상은 좀 떨어져서 추후 개선 예정.
데이터는 한국어로 된 고양이/강아지 사료 데이터를 구하기 힘들어, 강이지/고양이 사료 판매 쇼핑몰에서 Beautifulsoup으로 크롤링했다. 상업적 목적으로 사용하지 않을 것임을 다시 한번 밝힙니다...

평가를 하면 고양이 리스트에서 조회가 가능하다. "입맛 확인하러 가기"를 누르면 해당 고양이에게 추천된 사료가 뜬다.

고양이별로 추천된 사료. 추천 방식은 고양이 사료 추천 시스템 만들기 : 여러 아이템 기반 추천(Item-item collaborative filtering) 에 자세히 기재했다.
Fast API 를 사용하며 느낀 바는 다음과 같다.
- 성능과 시간 면에서는 flask와 큰 차이를 느끼지 못했으며, 오히려 pymongo를 사용하였기 때문에 db와 쿼리 시 문법에 for문이 들어가 시간복잡도가 증가하는 경향이 있었다.
@app.get("/catinfo", response_class=HTMLResponse)
async def recommend_food(request: Request, cat_id: int=1.0):
catlist = []
cats = cat_col.find()
for cat in cats:
reviewlist = []
catreviewcount = rating_col.find({'cat_id':cat['cat_id']})
for crw in catreviewcount:
reviewlist.append(crw)
catlist.append((cat, len(reviewlist)))
return templates.TemplateResponse("catinfo.html", {"request": request, "cats":catlist})
여러 항목을 조회할 시, for문을 써서 리스트에 넣어줘야 pymongo에서 데이터가 조회가 된다.
- 찾을 수 있는 샘플 코드도 flask보다 덜 RESTful한 경우가 많았다.
(main 파일에 거의 모든 코드가 다 들어있는 경우가 생각보다 많았다)
- 에러가 적은지도 체감상 크게 느끼지 못했다. 로그인 기능을 구현하는데 어려움을 겪었고, 프로젝트 기간 내에 이미 만들어진 웹사이트 위에 로그인 기능을 넣는 것이 되지 않았다. 꼭 리팩토링 기간에 다시 해봐야겠다.
- 최근 핫한 최신의 스택이라고 무조건 답이 아니라는 것도 알게 되었다. 하지만 직접 부딪히며 오류와 문제를 해결해본 좋은 경험이 되었다.
2달 전과 달라진 점(flask로 처음 웹사이트를 만들어 배포해볼 당시)
- 검색 구현을 db에 있는 이름 단위가 아닌, 키워드 단위로 구현할 수 있게 되었다.
Mongodb에서 특정한 문자열 검색해서 결과물 리턴하기
- BeautifulSoup을 사용한 크롤링을 그래도 DB를 구축할 만큼은 할 수 있게 되었다. 그리고 크롤링한 걸 바로 DB에 넣는 것도 할 수 있게 되었다. 이전에는 API를 사용해 받아온 json 파일을 바로 DB에 넣었었다.
파이썬으로 AWS Dynamodb 쉽게 연결하고 데이터 넣기
- 아이템-아이템 기반 협업 필터링에서 선호도 정보를 추가하는 방법을 고안하고, 적용해보았다. 참고 코드를 복붙하는 것 외에 내가 생각한 방법으로 추천 시스템을 만들었다는 점이 뿌듯하다. 아직 추천 성능은 많이 개선해야 하지만...!