Post

Oh my Stack 프로젝트 설명, 2023년 상반기 회고록

지난 30일 동안 데이터 엔지니어로써 참여했던 프로젝트 ‘Oh my Stack’를 설명하고 회고해보려고 한다.

프로젝트에 관련된 모든 소스는 다음 링크에서 볼 수 있다.

https://github.com/jewoodev/Oh_My_Stack

1. Oh my Stack를 기획한 이유

이 프로젝트의 필요성, 기획 이유에 대한 이야기는 ‘취업난’에서부터 시작된다. 약 1997년부터 취업난 이야기는 항상 있어왔지만 올해에 파악되는 ‘취업난’은 여느 해와는 다르다.

img01

Youtube 뉴스

Youtube에 업로드되는 뉴스에서 전과는 다른 현재 상황의 심각성을 보도하고 있는데, 현재 6개월동안 고립, 은둔 생활을 이어온 청년 층이 13만명에 가까워졌으며 그들 중 이런 생활을 5년 이상 이어온 사람들이 41.2% 나 되는 것을 말하고 있다. 그리고 길어지는 생활고 속에 새로운 문화가 생겨났다. 10원 줍기와 무지출 챌린지이다. 무지출 챌린지는 참여하고 싶은 사람은 누구든 오픈 채팅방에서 입장해 함께 하는데, 한 달에 사용한 비용을 인증하고, 돈을 쓴 경우 쓴소리를 해주는 문화이다. 이런 문화가 유행되어지고 있다.

img02

발취문 - 연합뉴스TV 기사, 취업난에 그냥 쉰 ‘청년백수’ 50만명…역대 최대

img03

발취문 - 주간한국 기사, 취업난인데 구인난… 심화되는 ‘일자리 양극화’

이런 취업난의 고통에 허덕이는 청년들과는 다르게 기업은 구인난에 허덕이고 있다. 심지어 코로나 19 이전에 비해 2배 이상 증가했다. 우리는 ‘Oh my Stack’를 통해 이러한 기업과 청년 양측의 어려움을 풀어내어 현 사회에 보탬이 되고자 프로젝트를 시작했다.

2. 데이터 파이프라인

2.1 데이터 소스

‘사용자’에게 알맞은 ‘기업’을 찾을 수 있도록 돕는 서비스를 구현하기 위해서 채용 공고 데이터가 필요했고, 그 데이터로 구현된 AI 모델이 필요했다. 채용 공고 데이터 중에서도 IT 계열이, 그 중에서 정량적 데이터와 정성적 데이터가 풍부한 데이터가 많아 사용자 폭을 IT 계열 취직 희망자로 설정하고 해당 계열 데이터를 데이터 소스로 결정했다. 데이터 파이프라인은 데이터 소스에서 스크래핑하는 것에서부터 시작된다.

2.2 Scraping

img04

스크래핑 작업은 하루에 8번 작동되며, 수집되는 타겟 사이트는 모두 동적 페이지로 되어 있어 Selenium이 사용되었다. 스크래핑을 포함한 ‘Oh my Stack’의 데이터 파이프라인은 Apache Airflow을 기반으로 구축하고 관리된다.

스크래핑 작업을 자동화하면서 중요시했던 점은

  • (이 작업이 파이프라인에서 가장 많은 시간이 소모되는 작업이기 때문에)여기서부터 시작되는 Workflow의 runtime이 최신 정보를 반영한다고 이야기 할 수 있을 만큼 짧은지
  • 타겟 사이트의 데이터가 우리가 필요로 하는 데이터를 갖고 있는지, 부족한 것이 있다면 그걸 drop 할지 하지 않을지를 정하는 기준은 어떻게 정할 것인지

이다. 위에 대한 고민들로 몇 개의 사이트에서 스크래핑을 할지, 어느 사이트에서 스크래핑을 할지, 중요한 데이터와 덜 중요한 데이터의 우선 순위는 어떻게 둘지 정했다.

그렇게 수집된 데이터는 DataLake(S3)에 날짜, 시간별로 묶여서 적재된다. 이 과정에서 적재된 데이터는 추후에 백업이 필요할 때 사용된다.

image-20240202222735105

모든 데이터는 S3에 먼저 저장된다.

image-20240202222812040

2.3 전처리

DataLake에 스크래핑된 데이터가 적재되면 바로 다음 작업이 시작된다.

  1. 다른 표현법으로 적힌 데이터들을 일원화하고 정규화한 후 필요한 데이터를 추가적으로 수집해 프로덕션 데이터베이스에 로드하고
  2. 거기서 모델에 학습시키기에 적합하도록 다수의 객체가 담긴 레코드를 하나의 객체만이 담기도록 나눈 후 필요하지 않은 컬럼은 덜어내고 DataLake에 저장한다.

전처리를 하는 동안 사용되는 Tool은 Pandas 단독으로 결정지어졌다. 앞선 고민들을 통해 선택된 데이터 소스에서 한 번에 수집되는 Record의 수가 3000~4000개 정도인데, 이 정도 크기에 Spark를 사용하는 것은 비용 낭비라고 판된 되었기 때문이다.

2.4 프로덕션 데이터

img05

전처리를 거쳐 두가지 데이터가 업데이트되는데, 처음 처리되는 것이 프로덕션 데이터이다. 프로덕션 데이터가 업데이트되기 전에 처리되는 전처리 과정을 살펴보자.

  • ‘지저분한 데이터 정리’

    • 표현 정리
      ‘Scraping’ 을 통 수집된 데이터는 여러 사이트에서 수집된 것이기 때문에 같은 뜻을 가진 단어도 다르게 표기되어있다. 예를 들어 ‘경력’이 기술될 때 한 곳에서는 ‘신입 이상’이라고 되어있지만 다른 곳에서는 ‘경력 무관’이라고 적혀 있곤 하다. 이러한 표현들을 일원화한다.

    • 주소 정리
      각 주소 값들이 Kakao Map API에서 위경도 값을 추출할 수 있으려면 ‘,’를 기준으로 데이터를 잘라내고 몇 개는 따로 value를 알맞게 바꾸는 등의 작업이 필요했다.

    • 위경도 값 수집
      추후에 AI 추천 과정에서 사용자의 거주지와의 거리를 선호사항 값으로 다루기 위해 각 공고 데이터에 기재된 위치 값을 수집한다. 이를 위해 Kakao Map API를 사용한다.

    • 같은 기업, 다른 지점
      같은 기업이지만 다른 지점의 위치에서 일하게 되는 경우도 존재했다. 그렇기 때문에 수집된 위경도 값으로 같은 기업이지만 다른 지역인 데이터가 있다면 서로 다른 지역으로 나누어 다른 컬럼에 값을 저장한다. 예시로, ‘하이닉스 대전’, ‘하이닉스 서울’ 처럼 저장된다.

  • ‘정규화’
    ‘지저분한 데이터 정리’를 통해 깨끗해진 테이블을 정규화한다. 필요에 따라 역정규화를 통해 테이블 갯수를 줄이고 사용되는 비용을 최적화한다.

그 후에 Production database의 이전 데이터는 제거되고 새로운 데이터가 load된다.

2.5 AI feature data

06

Production database가 업데이트 되고나면 그 다음으로 새로운 데이터를 AI feature 값으로 사용 될 수 있도록 대소문자를 일원화하거나 여러 개의 값을 갖고 있는 데이터를 분리하는 과정을 갖는다.

그리고 이 데이터를 전부터 쌓여있던 incremental data에 추가하고 Data Lake에 저장한다.

2.6 분석계 아키텍처 플로우

analysis_archit.drawio.png

DataLake에 전처리가 끝난 데이터가 올라가는 시점에 AWS Glue는 새로운 데이터가 생성되는 이벤트를 기점으로 Crawler 를 작동시킨다.

glue_crawler

크롤링된 데이터에는 Athena에서 서버리스로 Presto 기반의 쿼리를 날릴 수 있다. 쿼리가 수용하는 데이터의 규모가 페타바이트 단위이기 때문에 분석 작업에 적합하고, 사용법 또한 SQL를 사용할 수만 있다면 바로 사용할 수 있어 분석계가 사용하기 편리하다.

image-20240325154421782

Athena에서 쿼리를 날려 얻은 결과이다. 오른쪽 끝에 보이는 데이터는 기술 스택인데, 모델링과 분석을 할 수 있도록 하나의 데이터가 기술 스택이 쪼개져서 여러 행으로 전개되어있는 것을 확인할 수 있다. 이렇게 데이터를 불러와서 특정 기술 스택, 게시 날짜, 지리적 위치에 따라 채용 트렌드의 변화 추이를 분석할 수 있게 데이터가 모델링되어있다.

3. Other works

  • 스크래핑 중에 로그인 자동화를 하는 것에 고생을 했었는데 넌센스 퀴즈를 풀 듯이 해결해내버렸다. CAPTCHA에 걸리지 않도록 하는 것이었는데, 그런 해결 과정으로 마무리했던 게 색달랐다.
  • 공고 데이터나 유저의 기술 스택에서 ‘기술 스택 이미지’ 이름에 태깅할 수 있도록 이미지 이름을 변환하는 일.
  • 팀원이 필요로 하는 데이터 수집, 파이프라인 수정
  • 데이터베이스 관리(계정, 권한, 스키마 등)
  • 깃 관리(커밋 프로세스 감독)

4. 아쉬웠던 점

  1. Spark를 사용하지 못했다.
    데이터 크기가 작아서 Spark를 사용한다면 아주 비용 비효율적이게 되버리기 때문에 사용하지 않았다. EMR을 활용해서 EC2에 띄운 Airflow에서 Job을 던져주는 Batch Job을 돌려볼 수 있었다면 좋았을텐데 아쉬움이 남는다..
  2. 기획
    발표 당시 피드백을 받았던 것이기도 한 기획에서의 아쉬움, 이미 많은 사이트에서 해당 기능들을 어느정도 제공하고 있는데 차별화가 된다는 부분이 보이지 않는다는 점이다. 원래는 유저의 집 위치에서 기업까지 출퇴근 강도 점수를 매겨서 더 알맞은 기업을 추천하는 시스템을 구상했지만 구현하지 못했다는 것에서, 더 세밀하게 기획 또는 다양한 시도가 필요했을 것 같다고 생각이 들었다.

5. 마치며

이번 해가 밝고 스스로를 성장시키는데 가장 많이 기여한 요소라고 생각한다. 앞선 프로젝트는 모두 미니 프로젝트였는데 데이터 엔지니어가 아닌 ‘데이터 엔지니어와 협업하는 포지션’에서 4개의 프로젝트를 경험하며 그들과 어떻게 소통할 수 있을지 내 시야를 넓히며 더 잘 달려나갈 수 있도록 연료를 공급하는 과정이었다고 여기고 있다.

앞서 진행했었던 미니 프로젝트들은 아래와 같다.

  • 음악 상담사: 사용자와 채팅으로 상담하며 사용자의 감정에 맞는 음악으로 위로하고 공감하는 챗봇
  • 저출산 원인 예측기: 저출산의 원인이 되는 요인들의 수치를 변경하면서 어떤 정책을 내었을 때 저출산 문제를 효과적으로 개선할 수 있는지 알 수 있게 하는 ML Modeling
  • 고령층 교통안전 시각화: 노인 보호구역과 노인 교통사고 지점을 시각화하여 그들을 어떻게 잘 보호할 수 있는지에 대한 개선방안을 제시

  • 공항 가이드 웹사이트: 공항이 익숙하지 않은 이용자들에게 비행기 탑승 시간에 늦지 않도록 ‘공항에서 추가적으로 30분 이상의 시간이 소모되야 하는 터미널인지’ 등을 가이드 하는 웹사이트

그로 인해 웹 개발과 데이터 과학 부분을 맡은 팀원 분들과 협업하며 필요할 때마다 데이터를 수집하거나 파이프라인을 수정하는데 있어서 각 포지션에 대한 이해가 있으니 팀이 더 잘 굴러갈 수 있게 소통할 수 있는 힘이 생겼다는 걸 느낄 수 있었다.

This post is licensed under CC BY 4.0 by the author.