개발공부 & 부트캠프/[부트캠프] 회고

[데이터 엔지니어링 부트캠프]9월 4주차 회고

포리셔 2023. 9. 30. 15:50

좋았던 점

  • 주가 예측 미니 프로젝트는 그런대로 성공적으로 끝난 것 같습니다. 미니 프로젝트가 시작되었던 지난 주 목요일부터 주식 거래만 전문적으로 하는 사람들만큼은 아니더라도 이미 어떤 식으로 종목을 선정하고 어떤 식으로 논리를 전개하면서 발표를 진행할 지 구상할 수 있었습니다.
  • 사전에 어떤 툴과 기능을 쓸 지 미리 선정하고 들어간 덕분에 부족한 부분이 있는 팀원들은 추가로 어떤 부분을 공부할 지 알 수 있었고, 웬만큼 기능에 익숙한 조원들은 바로 데이터를 분석하고 다른 팀원들을 도울 수 있었습니다.

아쉬웠던 점

  • 저를 포함해서 그나마 주식을 어느 정도 만져본 팀원이 있어서 초기 구상 자체는 수월하게 끝난 것 같지만, 이후에 이론적인 적용을 코드로 구현하면서 강사님의 예제 코드에 포함된 설명만으로는 우리 팀이 종목을 선택한 논리적 근거와, 그렇게 선정된 종목의 매수/매도 타이밍을 언제로 선택할 것인지에 대한 확신이 부족했다는 점이 아쉬웠습니다. 한마디로 정리하자면 도메인 지식의 부족이 어떤 영향을 미치는지 좋은 쪽으로도, 안 좋은 쪽으로도 느낄 수 있는 프로젝트였습니다.
  • 또 한 가지, 논리를 대변하려면 재무제표 등 주가 이외의 데이터가 필요했는데, 강사님이 주신 데이터에서 군데군데 구멍이 뚫린 부분이 포착되었습니다. 일부 종목의 재무제표가 연도와 무관하게 아예 조회가 되지 않았던 것이었죠. 너무 늦게 이 점을 알아채서 크롤링 등으로 정보를 보충하지 못했고, 차후 프로젝트에서는 사용할 데이터를 먼저 살펴보면서 검증할 필요성을 느끼게 되었습니다.

배운 점

에어플로우(Airflow)

파이썬 기반의 워크플로우 생성 툴인 에어플로우를 이용해 바이낸스 API에서 비트코인을 비롯한 가상화폐 가격 데이터 수집과 이를 이용한 미래 가격 예측 실습을 진행했습니다.

들어가기 전에: 이번 실습은 Windows 10 기반 로컬 환경에 WSL과 우분투 22.04 버전을 설치한 후 진행했습니다. WSL 버전이 1로 바뀌어 있었기 때문에, Powershell을 관리자 권한으로 실행한 뒤, wsl -l -v로 우분투의 wsl 버전을 확인해보고, wsl --set-version <사용하고 있는 환경이름> 2으로 바꾼 후 우분투를 다시 실행했고, 버전 변경에는 약 3분 정도 소요되었습니다.

  • 에어플로우에서 작업을 관리할 때는 DAG라는 단위로 진행합니다. 파이썬 스크립트로 작성한 새로운 DAG는 에어플로우에서 조회할 수 있고, 브라우저에서 DAG 관리 창을 열어서 워크플로우 실행 등을 관리할 수 있습니다.
  • 우분투 환경 상에서 vi 등의 에디터를 이용해 DAG 파일을 작성하기에는 아무래도 번거로운 면이 많아서인지, 이번 실습에서는 윈도우 VS Code를 관리자 권한으로 실행한 뒤, Remote-SSH 확장 프로그램(extension)을 설치함으로써 VS Code에서 우분투 환경에 원격으로 접속해 파일 작성 및 저장을 완료했습니다.
    ssh extension
  • 에어플로우 구동과는 별개로, 파이썬 스크립트를 별도로 작성해 바이낸스 API에서 수집한 데이터를 MySQL 데이터베이스 테이블에 저장했습니다. 이를 위해 미리 MySQL 워크벤치에서 쿼리를 작성해 테이블과 그 컬럼을 미리 작성했습니다.
CREATE DATABASE coin_db;
USE coin_db;
CREATE TABLE coin_tbl (  
num INT AUTO_INCREMENT PRIMARY KEY, -- 일련번호  
Open_time datetime, -- 날짜와 시간  
Open_price DECIMAL(10, 3), -- 시가  
High_price DECIMAL(10, 3), -- 고가  
Low_price DECIMAL(10, 3), -- 저가  
Close_price DECIMAL(10, 3), -- 종가  
Volume DECIMAL(10, 3), -- 거래량  
Symbol VARCHAR(30), -- 코인 이름  
predic_price DECIMAL(10, 3) -- 비트코인 예측값  
);
import requests
from datetime import datetime
import time
import pandas as pd
from tqdm import tqdm
import pymysql

db = pymysql.connect(
    host='localhost',
    port=3306,
    user='root',
    passwd='yourPassword', # MySQL 비밀번호
    db='coin_db',
    charset='utf8'
)

cursor = db.cursor()

url = 'https://api.binance.com/api/v3/klines'
coin_name = "BTCUSDT"
start_date = "2023-09-15"
end_date = "2023-09-26"

start = int(time.mktime(datetime.strptime(start_date + ' 00:00', '%Y-%m-%d %H:%M').timetuple())) * 1000
end = int(time.mktime(datetime.strptime(end_date + ' 23:59', '%Y-%m-%d %H:%M').timetuple())) * 1000

params = {
    'symbol': coin_name, # 코인 이름 - BTCUSDT(비트코인), ETHUSDT(이더리움)
    'interval': '1m', # 수집 시간 간격 - 1m (1분), 1h(1시간)
    'limit' : 1000, # 한번에 가져올 데이터의 수
    'startTime': start,
    'endTime': end
}

# start가 end보다 작을 동안 반복
while start < end:
    # 시작 시간 갱신
    params['startTime'] = start
    # 바이낸스 API 접속 결과 리턴
    ## 접속 결과(비트코인 가격)을 result에 저장
    result = requests.get(url, params=params)
    coin_list = result.json()

    if not coin_list:
        break

    # coin_list에서 코인 가격 하나를 coin 변수에 저장
    for coin in coin_list:
        print('coin =', coin)
        open_time = datetime.fromtimestamp(coin[0] // 1000)
        print("open_time =", open_time)
        open_price = coin[1]
        print("open_price =", open_price)
        high_price = coin[2]
        print("high_price =", high_price)
        low_price = coin[3]
        print("low_price =", low_price)
        close_price = coin[4]
        print("close_price =", close_price)
        volume = coin[5]
        print("volume =", volume)
        print("=" * 50)

        sql = "INSERT INTO coin_tbl (open_time,open_price,high_price,low_price,close_price,volume,symbol) "
        sql += " VALUES (%s, %s, %s, %s, %s, %s, %s)"

        cursor.execute(sql, (open_time, open_price, high_price, low_price, close_price, volume, coin_name))
        db.commit()

    # coin_list[-1][0]: 코인 리스트 마지막 행 0번째 열 -> 수집한 마지막 시간이 int로 저장되어 있음
    start = coin_list[-1][0] + 60000 # 다음 step으로
    time.sleep(1)

db.close()
  • 가격 예측은 사이킷런이나 텐서플로우 등을 사용하는 대신 비교적 사용이 간편한 Prophet이라는 라이브러리를 사용했습니다.

도커컴포즈(Dockercompose) 기초

위에서 실습했던 환경 구축과 워크플로우 실행을 좀더 간편히 하기 위해 도커파일을 작성함으로써 자동화하는 도커컴포즈에 대한 학습을 했습니다. 다만, 이 부분은 실습 시간의 부족으로 바이낸스 API를 이용한 가상화폐 가격 조회와 예측에는 이용하지 못했고, 도커허브(Docker Hub)에서 블로그 작성 패키지인 워드프레스의 도커파일을 이용해 이미지 생성 - 컨테이너 가동까지 진행했습니다. 가상화폐 가격 조회는 연휴가 끝난 후에 도커컴포즈를 복습하면서 진행하기로 했습니다.

  • 도커허브에서 워드프레스를 검색한 뒤, 우분투 터미널 상에 docker pull wordpress를 입력하고 실행합니다.
  • docker run --name some-wordpress -p 9088:80 -d wordpress로 로컬에서 워드프레스를 실행했습니다. 이 명령어에서 볼 수 있듯이 9088번 포트를 이용했습니다.
  • 워드프레스를 실행하려면 워드프레스 도커파일 뿐만 아니라 MySQL DB 또한 함께 실행해야 합니다. 이 둘을 따로 실행시키지 않고 한번에 실행시키는 방법을 도커컴포즈로 실습했습니다. 그래서 로컬 접속이 되는 것만 확인한 후에 /etc/init.d/ssh restart & 명령어로 ssh를 재시작했습니다. 바이낸스 실습 때와 같은 요령으로 VS Code에서 SSH에 원격으로 접속한 뒤, yaml 파일을 하나 작성합니다. 여기서 MySQL 실행과 워드프레스 컨테이너 실행을 함께 정의합니다. 특이점이자 주의사항으로, yaml 파일은 탭 키(스페이스바 4번에 해당)가 아니라 스페이스바 두 번으로 들여쓰기를 인식한다는 점이었습니다. 또한 로컬 환경 실습 때와 달리 포트도 7077번으로 수정했습니다.
version: "1.0"

services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - "7077:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
volumes:
  db_data: {}
  • docker compose -f wordpress_dockercompose.yaml up을 실행하면 yaml 파일에서 정의한 MySQL DB와 워드프레스가 실행됩니다. 실행 후 브라우저에서 http://localhost:7077을 입력하면 우리의 사이트가 실행되는 것을 볼 수 있습니다.

앞으로 바라는 점

  • 파이널 프로젝트 관련: 주제 선정과 함께 사용할 툴을 먼저 선정하는 것이 얼마나 중요한 지 이번 미니 프로젝트에서 느꼈습니다. 그래야 나중에 다른 툴을 추가하더라도 방향성에 맞는 툴을 골라서 사용할 수 있을 것 같습니다. 다행히도 데이터 분석 쪽으로 잔뼈가 굵은 조원이 한 명 있어서 그 조원과 상의하면서 큰 틀을 잡아나가는 것을 1차 목표로 삼아야겠습니다.
  • 학습 관련: 스터디 소집까지는 좋았는데... 수업자료 만들고 어떻게 진행할지는 조금 더 고민해봐야 할 거 같습니다...! 연휴가 껴있어서 정말 다행이네요;; 저는 이제 수업 자료 만들러 갑니다......