5월 6일, 내가 수강하던 부트캠프인 프로그래머스의 인공지능 데브코스가 끝났다. 작년 12월부터 장장 5개월 간의 프로그램이었다. 네이버의 부스트캠프나 KT의 에이블 스쿨과 동기간에 모집이라 고민하고 있었으나 프로그래머스가 먼저 합격 발표를 하기도 했고 다른 부트캠프에 도전하려면 이 합격을 취소하고 도전해야 하는 것이어서 그러자면 계획이 불안정해지는지라 그냥 프로그래머스를 믿고 프로그래머스 인공지능 데브코스에 참여했다. 이런 장기간의 교육을 무료로 듣게 해준다니 우리나라엔 정말 좋은 제도가 있네 싶었다. 아무튼 이 글은 부트캠프를 수강한 계기와 후기, 그리고 느낀점들을 정리해보기 위해 작성하는 글이다. 프로그래머스 데브코스에 관심있거나 다른 인공지능 부트캠프를 수강할 사람들이 알아두면 좋을 점도 정리해봤다.

나는 왜 부트캠프를 수강했는가?

부트캠프를 수강하게 된 가장 큰 원인은 대학원 졸업 후 취업에 실패한 것이다. 2021년 하반기 취업에 실패하고 2022년 상반기까지 기다려야 했는데 그 기간동안 뭐라도 해야할 것 같았다. 그때 마침 네이버 부스트 캠프를 발견하고 부트캠프 수강을 결심했다. 결론적으론 프로그래머스의 부트캠프에 참여하게 되긴 했지만...

그 외에도 다른 이유도 있었다. 2021년 상반기엔 데이터 분석 직무를 위주로 구직했는데 2022년 부터는 AI 직무에 도전해보고 싶었다. 데이터 분석 직무는 워낙 경쟁률이 높기도 했고 AI 직무에 비해 평균적으로 처우도 낮은 편이다. AI 엔지니어가 더 미래가 밝아보이기도 했다. 좀 더 전문직의 느낌이라고 해야하나. 공백기간에 부트캠프를 수강하는 김에 AI 엔지니어로 내 진로를 발전시킬 수 있다면 좋겠다고 생각했다.

프로그래머스 인공지능 데브코스 후기

나는 프로그래머스 인공지능 데브코스를 수강하기 위해 한 번의 코딩테스트와 한 번의 면접을 거쳤다. 너무 오래전의 일이라 확실히 기억은 안나지만 코딩테스트는 내 기준 쉬운 문제와 어려운 문제가 모두 있었고 나는 어려운 문제를 풀진 못했지만 통과했다. 면접은 이제까지 학습 경험이나 앞으로 공부할 계획, 의지 같은 것들을 보려고 한 것 같았다. 결과적으로는 합격했다. 들어가기 빡빡하다거나 요구치가 높다고 생각되진 않았다. 프로그래머스 인공지능 데브코스를 고민하는 사람들이 있다면 그냥 한 번 도전해보는 것을 추천한다.

교육과정은 동영상 강의, 라이브 특강, 주기적으로 모여서 팀 활동, 개별 스터디, 파이널 프로젝트 등으로 구성되었다. 아무래도 코로나의 영향으로 오프라인 강의는 없었고 모두 온라인에서 이뤄졌다. 온라인으로 배우면 집중도가 떨어지는 성격이라 좀 아쉬웠다. 수업내용의 난이도는 중하 ~ 중중 수준이다. 아예 인공지능을 처음 접하는 사람이라도 교육과정을 잘 따라온다면 수강할 수 있을 것이라고 생각한다. 그래도 몇몇 수업은 좀 어려워서 여러 번 강의를 봐야했다. 프로그램 내에서 자율적인 팀 활동을 권장하니까 스터디 모으기도 쉬워서 더 배우고 싶은 것이 있어서 스터디를 만들고 싶다면 맘대로 만들 수도 있을 것이다. 교재비도 지원을 해줘서 원하는 교재가 있다면 바로 볼 수 있었다.

부트캠프에 대해서 총평을 하자면 프로그램 자체는 좋으나 내가 바랬던 방향과는 조금 거리가 있었던 것 같다. 초심자를 타겟으로 만들어진 프로그램 같았고 새롭게 알게 된 지식도 많긴 했지만 기본을 좀 충실히 다졌다는 느낌이지 AI 엔지니어 취준생으로써 준비가 되었다는 느낌은 잘 모르겠다. 물론 기업마다 AI 엔지니어 신입사원에게 바라는 역량의 차이가 있긴 하겠지만 이 프로그램의 교육 내용으로만 취업을 하는 것은 무리다.

좀 더 상세하게 이 부트캠프의 장단점을 설명하겠다. 우선 이 부트캠프의 장점은 자유로운 분위기와 학습에 대한 지원이 풍부하다는 점인 것 같다. 요즘 유튜브 광고에서 부트 캠프 광고들이 종종 나오는데 하나같이 자기들은 엄청 빡세게 훈련을 시키며 하루종일 공부를 하게 되고 열몇개의 프로젝트를 하게 되며 등등으로 광고를 하던데 프로그래머스 데브코스는 그런 분위기는 아니다. 강의를 수강하는 것도 하루 안에 자유로운 시간에 듣기만 하면 되고 과제도 부담스럽지는 않다. 몇몇 강의는 분량이 좀 많긴한데 조금 힘든 정도? 그래서 남은 시간에 내가 원하는 공부를 할 수 있다는 장점이 있다. 특별히 바빴던 시기는 파이널 프로젝트를 진행할 때 정도밖에 없는 것 같다. 학습 지원도 정말 적극적이라고 느낀게 교재를 비롯한 학습에 대해 필요한 모든 자원을 무료로 지원해주신다. 교재는 물론 줌이나 노션같은 플랫폼, 구글 코랩 프로같은 비용도 지원해주시고 따로 공부하고 싶은 것이 있다면 소모임도 만들어주신다. 각 팀별로 전담 멘토가 있는데 멘토 분들도 질문하면 적극적으로 도와주셨다.

단점은 솔직히 취업 준비에 최적화된 것 같은 프로그램은 아니라는 점이다. 특히 나처럼 빨리 취업하고 싶은 사람한테는 교육 내용이 큰 도움이 되지는 않을 것 같다. 왜냐면 내가 이 부트캠프를 수강하면서 느낀 것이 취업에 중요한 것은 무슨 강의를 듣느냐보다는 스스로 관심분야를 공부하면서 자신을 발전시켜 나가는 것이다. 프로그래머스 데브코스는 스스로 공부하는 법을 깨닫게 해주고 공부하는 것을 지원해주시기는 하지만 관심없는 분야도 강의를 꼭 들어야하고 라이브 강의, 주말 팀활동 같은 것들에 모두 참여해야하니까 개별적인 공부에 집중하기가 좀 힘들었다. 강의가 수학, 통계, 파이썬, 머신러닝, 데이터 엔지니어링, 비전, 자연어처리, 추천시스템 등등... 너무 많은 영역을 5달의 강의로 모두 커버하려고 하다보니 더 깊게 공부하고 싶은 영역이 있는데 강의 진도상으로는 다른 영역의 강의를 들어야한다던가 하는 부분이 좀 아쉬웠다. 강의가 선택과 집중이 가능해서 관심있는 분야를 선택해서 들을 수 있거나 아니면 아예 전체적인 부분을 직접 경험하면서 느낄 수 있게 실전적인 프로젝트 위주로 돌아갔다면 더 좋았을 것 같다. 네이버 부스트캠프 같은 경우는 비전, 자연어 처리, 추천시스템 중에 하나를 정해서 반을 나누고 공부하던데 그런 방식도 괜찮을 것 같다.

물론 아예 도움이 되지 않은 것은 아니다. 멘토님들, 강사님들이 질문에 잘 대답해주셔서 내가 모르는 부분이 뭔지 더 공부해야 할 부분이 뭔지 잘 이해할 수 있었고, 다양한 분야에 대해서 공부하면서 데이터 사이언스 전반에 대한 이해도도 높아졌으며, 데이터 수집부터 모델 배포까지 모두 경험할 수 있었던 파이널 프로젝트를 통해 앞으로 프로젝트를 어떻게 수행해야할지에 대해 알게 되었다. 그리고 모델링 이외의 영역에도 관심을 갖게 되었는데 특히 백엔드 개발이나 MLops 영역에 관심이 많아 졌다. 부트캠프만으로 취업을 하는 것은 무리지만 취업을 할 수 있도록 공부 방향을 잡는 데에는 도움이 되었다.

부트캠프를 수강하면서 느낀점

내 생각에 비전공자가 데이터 사이언스 분야로 취업하는 데 가장 큰 걸림돌은 혼자서 공부할 때 일정 이상으로 성장하는 것이 쉽지 않다는 것이다. 처음 공부를 시작할때는 교재나 오픈 된 강의같은 것으로 공부하게 될 것이다. 그것이 비전공자들에게 익숙한 학습법이기 때문이다. 근데 이런 것들은 보통 두가지 문제점이 있디. 첫번째는 이런 교보재들이 항상 데이터 분석, 데이터 전처리, 모델링같은 것들에 집중하고 있다는 점이다. 실제로 AI가 서비스로 되기까지의 과정 중에 분석, 전처리, 모델링은 아주 작은 영역만을 차지한다. 데이터 추출, 적재, 데이터 관리, 모델 서빙, 서빙된 모델에 대한 관리, 최적화 등등의 많은 절차들이 있으며 AI 엔지니어가 되기 위해서 이 모든 과정에 대해 전문적이어야 하는 것은 아니지만, 적어도 이 파이프라인에 어떤 일들이 일어나는지, 어떤 기술들이 필요한지 정도는 "아는척"할 수 있는 수준만이라도 이해하고 있어야 면접관분들이 긍정적으로 보시는 것 같다. 두번째 문제점은 대부분이 최신기술을 반영하지 않는다는 점이다. 물론 데이터 사이언스 분야는 기술이 매우 빠른 속도로 발전하고 있기 때문에 이를 모두 반영하는 것은 불가능하니 따로 찾아서 공부해야하는 것은 당연하긴하다. 논문을 찾아보고 IT 기업들의 기술 블로그를 뒤져보고 여러 깃허브의 코드들을 참고해야한다. 비전공자, 특히 문과 출신들은 책을 읽고 공부하고 다 공부하고나면 더 높은 난이도의 책을 사서 공부하고 같은 과정으로 배우는 것에 익숙할텐데 이런 방법으로는 절대로 데이터 사이언스에 대해 깊게 공부할 수 없을 것이다. 수동적인 공부만 하다간 여름에도 집합 공부 겨울에도 집합 공부, 계속 똑같은 것만 공부하게 될 것이다.결국엔 언젠가 혼자 찾아서 공부해야할 순간이 온다.

이것이 부트캠프를 수강하면서 배운 가장 중요한 것이다. 나는 부트캠프 이전에는 수동적인 공부만 했다. 교재를 보고 강의를 듣고 다른 사람의 예제를 보고... 위에도 설명했듯이 이런 방법에는 한계가 있다. 취업을 하기 위해선 프로젝트 같은 것으로 내 실력을 증명해야한다. 근데 난 프로젝트에 필요한 데이터들을 어떻게 구하지? 내가 만든 모델을 어떻게 보여주지? 깃허브에 파이썬 코드를 올리면 그게 프로젝트인가? 남의 예제를 따라한 프로젝트에 내가 뭘 어필해야 하는거지? 이 프로젝트를 어떻게 더 정교하게 발전시키지? 등등등... 진짜 수 많은 질문에 부딪혔다. 그리고 나는 부트캠프를 수강하면서 하나의 가르침을 얻은 것이다. "인터넷에 많으니까 너가 알아서 찾아서 공부해!"

물론 이런 말은 부트캠프를 수강하기 전에도 정말 많이 들었던 말이다. 근데 차이는 부트캠프 수강 전에는 이런 말을 듣기만 했고 수강 후에는 이것을 실제로 실천했다는 점이다... 이제까지 혼자 공부해본 경험이 없었으니 애초에 알아서 공부하는 방법을 몰랐다. 근데 막상 무작정 시도해보니 감을 잡을 수 있었고 정말 세상에 공짜로 공개된 지식이 많구나 라는 것을 느꼈다.

앞으로 부트캠프를 수강할 사람들에게 말해주고 싶은 것은 1. 내가 취직하고 싶은 직무의 업무를 파악하고, 2. 알아야하는 기술과 실무 내용에 대해 파악하고 3. 내가 모르는 부분을 찾아서 집중적으로 공부하고 4. 배운 것을 프로젝트에 적용하면서 너가 아는 것을 남들에게 증명하는 과정으로 공부해보라는 것이다. 진짜 부트캠프에서 시키는대로 강의듣고 프로젝트 하라니까 프로젝트하고 과제하라니까 과제하고 이런식으로는 실력이 늘 수가 없고 결국에 면접에서 실력없고 이해도 낮은거 뽀록나서 면접 떨어진다. 근데 알아서 찾아서 공부하면 자기가 모르는 부분, 아는 부분에 대해 이해도가 높아지고 자연스럽게 업무의 흐름에 대해서 알게 되며 면접에서 모르는 질문에도 어떤식으로 대답해야할지 감이 온다. 문제는 내가 이거를 부트캠프 끝나갈 쯤에 깨달았다. 부트캠프의 장점은 학습에 많은 지원을 해준다는 점이니까 이를 이용해서 스스로 찾아서 공부하는 습관을 들여보라. 내가 아직 취업도 못했고 이 분야에 전문가도 아니긴하지만 적어도 이런 공부방법으로 공부해서 손해볼 일은 없다고 생각한다.

 

 

'Others' 카테고리의 다른 글

[자아성찰] 열등감? 가면 증후군?  (0) 2022.06.10
약 7개월의 구직... 중간점검...  (1) 2022.04.03

Introduction to flat files

Data Frame

  • pandas - 2차원의 구조 (행, 열)

Flat Files

  • 간단하고 만들기 쉬움
  • 색상이나 볼드체 서식이 없는 일반 텍스트
  • 한 라인마다 하나의 행을 의미
  • delimiter로 필드가 구분됨
  • 일반적으로 delimiter는 콤마,( csv)
  • pandas는 delimiter와 상관없이 모든 플랫 파일을 불러올 수 있다.
import pandas as pd

tax_data = pd.read_csv('us-tax-data-2016.csv')
tax_data.head(5)

Loading other flat files

  • delimiter를 sep= 인자에 넣어준다.
import pandas as pd
tax_data = pd.read_csv('us_tax_data_2016.tsv', sep='\t')

Modifying flat file imports

Limiting Columns

  • usecols 인자를 이용해 로드할 열을 선택한다.
  • 모든 열 이름이나 열 번호의 리스트를 사용할 수 있다.
col_names = ['STATEFIPS', 'STATE', 'zipcode', 'agi_stub', 'N1']
col_nums = [0, 1, 2, 3, 4]

# choose columns to load by name
tax_data_v1 = pd.read_csv('us_tax_data_2016.csv', usecols=col_names)

tax_data_v1 = pd.read_csv('us_tax_data_2016.csv', usecols=col_nums)

Limiting Rows

  • nrows 인자를 이용해서 불러올 행의 수를 제한한다.
  • skiprows 인자는 건너뛸 행의 수를 선택한다. 이 경우 header=None으로 설정해야 한다.

Assigning Columns Names

  • names 인자 사용
  • 모든 열의 이름의 리스트가 있어야 함
  • 일부 열만 바꾸려면 불러온 후에 수행해야 함
col_names = list(tax_data_first1000)

tax_data_next500 = pd.read_csv('us_tax_data_2016.csv', nrows=500, skiprows=1000, header=None, names=col_names)

Handing errors and missing data

Common Flat File import issue

  • 열 데이터 타입이 잘못됨
  • 값이 누락됨
  • pandas가 읽을 수 없는 값

Specifying data types

  • pandas는 자동으로 열의 데이터 타입을 유추한다.
  • 데이터 타입을 특정해주기 위해 dtype 인자를 사용한다. 각 키는 열 이름이고 값은 데이터 타입이 들어 있는 딕셔너리를 받는다.

Customizing Missing Data values

  • pandas는 자동적으로 결측치를 해석한다
  • na_value 인자를 이용해 missing values를 커스텀할 수 있다.
  • single value, list, dictionary가 들어갈 수 있다.
tax_data = pd.read_csv('us_tax_data_2016.csv', na_values={'zipcode':0})

Lines with errors

  • pandas가 읽을 수 없는 레코드
  • error_bad_lines=False인자를 추가하면 pandas는 에러가 나는 행을 건너 뛴다.
  • warn_bad_lines=True 인자를 추가하면 파싱할 수 없는 줄을 건너뛸 때, 메시지를 표시하게 된다.

Introduction to spreadsheets

spreadsheet

  • excel
  • 행과 열이 있는 데이터 셀이 있는 테이블에 데이터가 저장됨
  • 플랫 파일과 달리 자동으로 업데이트 되는 공식이 있을 수 있음
  • 여러 시트가 있을 수 있음

Loading spreadsheet

  • read_excel()
  • usecols'A:P'와 같은 excel 열문자의 범위 문자열도 허용함
survey_data = pd.read_excel('fcc_survey_with_headers.xlsx',
                           skiprows=2, 
                           usecols='W:AB, AR')

Getting data from multiple worksheets

Selecting sheet to Load

  • read_excel()는 기본으로 첫번째 sheet만 가져온다
  • sheet_name인자를 사용해서 달느 시트를 가져올 수 있다.
  • 시트의 이름이나 인덱스 넘버를 받는다(zero index).
  • read_excel()에 들어간 인자는 모든 시트에 적용된다.

Loading All sheet

  • sheet name에 None을 전달한다
  • OrderedDict 리턴

Putting It All Together

all_responses = pd.DataFrame()

# Key는 시트이름, value는 프레임
for sheet_name, frame in survey_responses.items():
    frame['Year'] = sheet_name
    all_responses = all_responses.append(frame)

Modifying imports: true/false type

Boolean Data

  • True/False
  • pandas는 True/False column을 float 데이터로 로드한다.
  • read_excel()dtype 인자로 어떤 column을 bool 타입으로 만들어 줄지 정할 수 있다.
  • 오직 True와 False 값만 가져야 하므로 N/A 값은 True로 인코딩된다.
  • 'Yes', 'No' 같이 0과 1이 아니고 값이 다를 경우 true_value 인자를 사용한다.
bool_data = pd.read_excel('fcc_survey_boolean.xlsx',
                         dtype={'AttendedBootcamp': bool,
                               ...},
                         true_values=['Yes'],
                         false_values=['No'])

Modifying imports: parding date

Date and Time Data

  • python의 datetime 데이터타입으로 저장된다.
  • pandas는 날짜/시간 데이터를 객체로 불러온다.
  • timespan을 계산하려면 datetime 데이터 타입을 이용해야 한다.
  • dtype이 아닌 parse_dates 인자를 사용한다!
# 시간 데이터가 여러 열에 분산되어 있을 경우 중첩 리스트 넣기
date_cols = ['Part1StartTime', 'Part1EndTime', [['Part2StartDate', 'Part2StartTime']]]

survey_df = pd.read_excel('fcc_survey.xlsx',
                         parse_dates=date_cols)

# 컬럼의 이름을 지정해주고 싶으면 dict
date_cols = {'Part1Start': 'Part1StartTime',
            'Part1End': 'Part1EndTime',
            'Part2Start':['Part2StartDate',
                         'Part2StartTime']}

Non-Standard Dates

  • parse_date는 pandas가 이해할 수 있는 형식에만 작동함
  • to_datetime() 인자를 이용
  • 데이터 프레임과 column을 format 형식을 이용해 datetime format으로 바꿔줌
  • strftime.org
format_string = '%m%d%Y %H:%M:%S'
survey_df['Part2EndTime'] = pd.to_datetime(survey_df['Part2EndTime'],
                                          format=format_string)

Introduction to databases

Relational Databases

  • table로 정리된 데이터
  • row와 column으로 이루어짐
  • primary key를 이용해 테이블들이 연결될 수 있음
  • 스프레드 시트나 플랫파일보다 더 많은 데이터를 처리하고 더 많은 동시 사용자를 지원함
  • SQL을 통해 데이터베이스와 인터페이스

Common realational databases

  • SQLite
    • 컴퓨터 파일로 저장되는 데이터 베이스

Connecting to Databases

  • 데이터 베이스로 연결할 수 있는 way를 만든다
  • database를 쿼리한다.

Creating a Database Engine

  • SQLAlchemy
    • create_engine()은 데이터베이스 커넥션을 다룰 수 있게 해준다.
      • database에 대한 문자열 URL이 필요함
      • sqlite:///filename.db

Quering Database

  • 데이터 베이스에서 데이터를 로드하기 위해pd.read_sql(query, engine) 사용

Refining imports with SQL queries

SELECTing Columns

  • SELECT [column names] FROM [table name];
  • WHERE을 이용해 필터링
    • 표준 연산자
      • =, >, >=, <, <=, <>
    • 문자열 필터링
    • AND, OR과 사용 가능

More complex SQL queries

  • Get unique values for one or more columns with SELECT DISTINCT
  • Aggregate function
    • sum, avg, max, min
    • count
    • group by

Loading multiple tables with join

  • database records는 unique한 identifier가 있다.
  • JOIN ON을 이용해 서로 다른 테이블을 identifier로 조인할 수 있다.
  • SQL 키워드의 순서
    • SELECT
    • FROM
    • JOIN
    • WHERE
    • GROUP BY

Introduction to JSON

  • common web data format(자바스크립트)
  • 테이블 형식이 아님
  • record가 모두 동일한 컬럼을 가질 필요가 없음
  • 속성-값 쌍을 가진 collection(dictiㅐnary와 비슷)
  • 중첩 가능

Reading JSON Data

  • read_json()
    • json 파일 경로나 json 문자열을 넣을 수 있음
    • dtype 인자로 데이터타입 명시
    • orient 인자로 레코드들이 어떻게 정렬될 것인지 정한다.(record oriented or column oriented)

Introduction to APIs

API

  • 어플리케이션이 다른 프로그램들과 어떻게 소통할지 정의한다.
  • 데이터베이스 구조를 몰라도 api를 통해 데이터를 얻을 수 있다.

request

  • request.get(url_string):url에서 데이터 가져오기
    • params: 딕셔너리를 받아 api에 값을 전달한다.
    • header: 딕셔너리를 받아 사용자 인증키를 전달한다.
  • response 객체를 리턴하며 response.json()메소드를 사용해야 결과값만 가져올 수 있다.

Working with nested JSONs

Nested JSONs

  • value 자체가 객체인 경우 JSON이 중첩된다.
  • pandas.io.json
    • JSON을 읽고 쓰기 위한 판다스의 서브모듈
    • json_normalize(): 딕셔너리나 딕셔너리의 리스트를 받아 데이터 프레임을 반환한다.
      • record_path인자는 파일경로에 폴더를 나열하는 것과 같이 중첩 데이터에 대한 속성 문자열 또는 문자열 목록을 사용한다.
      • meta: 속성의 리스트를 받아 어떤 속성을 로드할 것인지 결정
      • meta_prefix: 속성의 출처를 명확히하고 열 이름이 중복되지 않기 위해서 접두사 사용

Combining multiple datasets

  • appending: 데이터 프레임을 다른 데이터프레임에 row로 추가한다. (df1.append(df2, ignore_index=True))
  • merging: dataset을 column을 더해 합친다. merge()는 SQL의 조인과 같은 메소드다.
    • df.merge()
      • on
      • left_on, right-on

'Data Science > [DSF] Data engineering' 카테고리의 다른 글

What is Data Engineering?  (0) 2022.05.15
Data engineering for everyone  (0) 2022.04.10

What is data engineering?

In comes the data engineer

  • 데이터가 흩어져 있음
  • 데이터베이스가 어플리케이션에 최적화 되어 있고 분석에 최적화되어 있지 않음
  • 레가시 코드들이 데이터를 손상시킴

What is parallel

  • 메모리의 프로세싱 파워의 이득
  • 아이디어: task를 subtask로 나누어 여러 컴퓨터에 분산시킨다.

병렬처리의 리스크

  • 통신 오버헤드
    • task가 너무 작을 때
    • 프로세싱 유닛이 적을 때
    • 이 오버헤드로 인해 프로세싱 유닛이 늘어나도 속도가 선형으로 증가하지 않는다(pararell slowdown)

병렬 처리 구현방법

multiprocessing.Pool: 동일한 컴퓨터의 여러 코어에 작업을 분산처리

from multiprocessing import Pool
import pandas as pd

def take_mean_age(year_and_group):
    year, group = year_and_group
    return pd.DataFrame({'Age': group['Age'].mean()}, index=[year])

with Pool(4) as p:
    result = p.map(take_mean_age, athlete_events.groupby('Year'))

result_df = pd.concat(result)

dask: 추상화 제공 프레임워크

import dask.dataframe as dd

# partition dataframe into 4
athelte_events_dask = dd.from_pandas(athlete_events, npartitions=4)

result_df = athlete_events_dask.groupby('Year').Age.mean().compute()

Parallel computation frameworks

Hadoop

  • HDFS: 분산 파일 시스템
  • MapReduce: 빅데이터 처리 시스템

Hive

  • 하둡 에코시스템의 최상위 계층
  • SQL의 변형인 Hive SQL을 사용하여 구조화된 방식으로 쿼리를 할 수 있다.
  • 다른 데이터 처리 툴과 통합됨

Hive: an example

  • 일반 SQL 쿼리와 비슷하지만 분산처리로 작동한다
SELECT year, AVG(age)
FROM views.athlete_events
GROUP BY year 

Spark

  • 맵리듀스는 job 사이에 디스크를 많이 쓰지만, Spark는 가능한 한 메모리에서 작동한다.
  • 맵리듀스의 단점 보완

Resilient distributed datasets(RDD)

  • spark에서 사용
  • 여러개의 노드에 분산되어 저장하는 데이터
  • 데이터프레임과 달리 컬럼에 이름이 없음
  • 튜플의 리스트와 비슷함
  • Operation
    • Transformation: .map() or .filter() -> RDD 리턴
    • Action: .count() or .first() -> single result

PySpark

  • 스파크의 프로그래밍 언어 인터페이스
  • Python interface
  • pandas와 유사함

PySpark: an example

(athlete_events_spark
    .groupBy('Year')
    .mean('Age')
    .show())

Workflow scheduling frameworks

An example pipeline

  • 어떻게 스케줄링?
    • 매일 수동으로: 확장하기 어려움
    • cron: dependency 처리가 어려움(작업의 순서...)

DAGs(Directed Acyclic Graph)

  • Set of nodes
  • Directed edges
  • No cycles

The tools for the job

  • Linux's cron
  • spotify's Luigi
  • Airflow

Airflow: an example

# Create the DAG object
dag = DAG(dag_id='example_dag', ..., schedule_interval="0 * * * *")

# Define operations
start_cluster = StartClusterOperator(task_id='start_cluster', dag=dag)
ingest_customer_data = SparkJobOperator(task_id='ingest_customer_data', dag=dag)
ingest_product_data = SparkJobOperator(task_id='ingest_product_data', dag=dag)
enrich_customer_data = PythonOperator(task_id='enrich_customer_data', ..., dag=dag)

# Set up dependecy flow
start_cluster.set_downstream(ingest_customer_data)
ingest_customer_data.set_downstream(enrich_customer_data)
ingest_product_data.set_downstream(enrich_customer_data)

Extract

  • 의미: 데이터 스토리지에서 데이터를 추출하는 것

Extract from text files

  • unstructured
  • flat file은 row와 column으로 이루어져 있다.(ex. csv, tsv)

JSON

  • JavaScript Object Notation
  • semi-structured
  • number, string, boolean, null
  • array, object
  • python의 딕셔너리와 비슷, 매핑이 잘 됨(json 패키지)
  • 많은 웹서비스가 이 형태로 데이터를 전달함

Data on the Web

  • request

    • ex. Browss to Google
    • Request to Google server
    • Google responds with Web page
  • APIs

    • 데이터를 JSON 포맷으로 보냄
    • API: application programming interface
  • database

    • 기존 애플리케이션 데이터베이스에서 추출
      • 많은 Transaction(행 삽입)
      • OLTP
      • row-oriented
    • Analytical database
      • OLAP
      • Column-oriented
  • connection string/uri

    • postgresql://[user[:password]@][host][:port]

    • import sqlalchemy
      connection_uri = 'postgresql://repl:password@localhost:5432/pagila'
      db_engine = sqlalchemy.create_engine(connection_uri)
      
      import pandas as pd
      pd.read_sql('SELECT * FROM customer', db_engine)

Transform

  • selection of attribute (ex. email)
  • Transaltion of code values (ex. New York -> NY)
  • Data validation (ex. date input in 'created_at')
  • Splitting columns into multiple columns(email -> user, domain)
  • Joining from multiple sources

pyspark

import pyspark.sql

spark = pyspark.sql.SparkSession.builder.getOrCreate()
spark.read.jdbc('jdbc:postgresql://localhost:5432/pagila',
               properties={'user':'repl', 'password':'password'})

# jdbc: Spark가 여러 관계형 데이터베이스에 연결하는 데 도움이 되는 소프트웨어

example: join

customer_df # pyspark dataframe with customer data
rating_df # pyspark dataframe with rating data

# Groupby ratings
ratings_per_customer = ratings_df.groupBy('customer_id').mean('rating')

# Join on Customer ID
customer_df.join(
rating_per_customer,
customer_df.customer_id=ratings_per_customer.customer_id)

Loading

Analytics or applications databases

  • Analytics
    • Aggregate queries
    • online analysis processing(OLAP)
    • column-oriented
    • columns subset에 대해 쿼리함
    • 병렬화에 적합
  • Applications
    • lots of transaction
    • online transaction processing(OLTP)
    • row-oriented
    • 레코드를 넣고 빼는 것이 쉽고 빠름

MPP Databases

  • Massively parallel processing database
  • 쿼리가 하위작업으로 분리되어 여러 노드로 분산됨

example: Redshift

# Pandas .to_parquet() method
df.to_parquet('./s3://path/to/bucket/customer.parquet')
# pyspark .write.parquet() method
df.write.parquet('./s3://path/to/bucket/customer.parquet')
COPY customer
FROM 's3://path/to/bucket/customer.parquet'
FORMAT as parquet

Load to PostgrSQL

# Transformation on data
recommendations = transform_find_recommecdatins(ratings_df)

# Load into PostgreSQL database
recommendations.to_sql('recommendations',
                      db_engine,
                      schema='store',
                      if_exists='replace')

Putting it all together

  • ETL 과정을 하나의 함수로 초기화
def extract_table_to_df(tablename, db_engine):
    return pd.read_sql('SELECT * FROM {}'.format(tablename), db_engine)

def split_columns_transform(df, column, pat, suffixes):
    # Converts column into str and splits it on pat

def load_df_into_dwh(film_df, tablename, schema, db_engine):
    return pd.to_sql(tablename, db_engine, schema=schema, if_exists='replace')

db_engine = {...}

def etl():
    film_df = extract_table_to_df('film', db_engine['store'])
    film_df = split_columns_transform(film_df, 'rental_rate', '.', ['_dollar', '_cents'])
    load_df_into_dwh(film_df, 'film', 'store', db_engine['dwh'])

Airflow refresher

  • python으로 작성된 워크플로우 스케줄러
  • 비선형 그래프 작성 가능
  • DAGs

scheduling with DAGs in Airflow

from airflow.models import DAG
from airflow.operators.python_operator import PythonOperator

dag = DAG(dag_id='etl_pipeline',
         ...,
         schedule_interval='0 0 * * *') # cron 표현식

etl_task = pythonOperator(task_id='etl_task',
                         python_callable=etl,
                         dag=dag)

etl_task.set_upstream(wait_for_this_task)
# wait_for_this_task가 끝난 후 실행
  • cron 표현식: 분, 시간, 일, 월, 요일

From rating to recommendation

Our recommendation transform

  • 사용자가 대부분 높게 평가한 기술의 코스를 추천
  • 이미 평가 한 코스를 추천하지 않음
  • 가장 높은 등급의 코스 3개를 추천

Scheduling daily jobs

The loading phase

# pandas dataframe to sql
recommendations.to_sql(
"recommendations",
db_engine,
if_exists="append")

전체 ETL

def etl(db_engines):
    # Extract the data
    course = extract_course_data(db_engines)
    rating = extract_rating_data(db_engines)

    # Clean up courses data
    courses = transform_fill_programming_language(courses)

    # Get the average course rating
    avg_course_rating = transform_avg_rating(rating)
    courses_to_recommend = transform_courses_to_recommend(
    rating,
    courses,
    )

    # Calculate the recommendation
    recommendations = transform_recommendations(
    avg_course_rating,
    course_to_recommend,
    )

    # Load the recommendations into the database
    load_to_dwh(recommendations, db_engine)

Creating the DAG

from airflow.models import DAG
from airflow.operators.python_operator import PythonOperator

dag = DAG(dag_id='recommendations',
         scheduled_interval='0 0 * * *')

task_recommendations = PythonOperator(
task_id='recommendations_task',
python_callable=etl)

'Data Science > [DSF] Data engineering' 카테고리의 다른 글

Introduction to flat file  (0) 2022.05.15
Data engineering for everyone  (0) 2022.04.10

+ Recent posts