프로젝트

비슷한 차트 탐색 프로젝트 - 1. 시간을 줄이기 위한 여러 실험과 테스트

dodo4723 2024. 2. 17. 10:01
728x90
반응형

2023년 9월 중순 이야기입니다.

 

제 프로젝트는 사용자가 특정 차트를 고르면, 코스피 코스닥 전 종목의 과거(5년) 차트들을 모두 탐색하여 가장 유사한 차트 10개 정도를 골라 사용자에게 보여주는 것이 목표입니다.

 

https://www.similarchart.com/

 

similar chart finder

내 종목의 차트는 상승하는 차트일까요?

3.35.36.208

 

 

 

전 종목 탐색으로 인해 응답시간이 너무 길다

앞선 포스팅에서 사용자가 '삼성전자'의 32거래일치 차트와 비슷한 과거 차트를 찾아달라고 요청하면 요청 한 번에 최소 4억 번 이상의 연산이 필요하고, 2GB 이상의 메모리가 필요하다고 했습니다. 부가적인 로직들도 고려하면 이보다 훨씬 시간과 자원을 많이 소모할 것입니다.

 

1초에 2천만 번 정도의 연산을 수행하는 파이썬으로 구현하면 30초 이상이 걸릴 것으로 예상됩니다. 파이썬보다 훨씬 빠르다고 알려진 C언어를 사용해 볼까도 생각해 봤습니다. 찾아보니 파이썬에서 C코드를 사용할 수 있는 cpython이라는 라이브러리도 있었습니다. 하지만 다른 라이브러리들과 호환이 잘 이루어지지 않는 느낌이라 사용을 포기했습니다.

 

좋게 생각해서 사용자가 몇십 초를 기다려준다고 해도 요청 한 번에 몇십 초가 소요되면 많은 사용자의 요청이 갑자기 동시에 들어온다면 서버는 과부하가 걸리고 응답도 매우 느려질 것입니다.

 

그래서 미리 전 종목별 비슷한 차트 목록을 DB에 준비해 두고, 사용자의 요청이 들어오면 저장되어 있던 비슷한 차트 목록을 프런트로 보여주기만 한다면, 위 문제가 해결될 것이라고 생각했습니다.

 

하지만 DB에 전 종목별 비슷한 차트 목록을 준비해 둔다고 하면 사용자가 요청하지 않은 종목을 불필요하게 준비할 수도 있다는 단점이 있습니다. 또한 이렇게 한다고 해도 준비에 걸리는 시간이 매우 오래 걸립니다. 4억X2630으로 1조 번 이상의 연산이 필요합니다.



일단 구현하고 보자 - by코랩

저는 파이썬으로 프로젝트를 하는 경우에는 코랩을 많이 사용합니다. 여러 라이브러리들을 간편하게 설치할 수 있어 괜히 제 개인 컴퓨터에 이것저것 설치할 필요가 없습니다.

 

또한 여러 계정이 있으면 웹의 탭 하나당 한 계정을 이용하여 동시에 여러 개의 프로그램을 실행 가능합니다. 제 학과가 AI학과기도 하고, 이전에 딥러닝 주가예측 프로젝트에서 계정을 5개 만들어서 돌리기도 했습니다.

제 동기중 한 명은 10개의 계정을 돌리더라구요..

 

처음에는 시간과 메모리를 생각하지 않고 그냥 생각나는 대로 구현해 보았습니다. 역시 전 종목의 데이터를 준비하는 것은 너무 오래 걸리고 메모리도 많이 사용했습니다. 새로운 알고리즘이 필요했습니다.

 

1. 시간을 줄여보자

챗 GPT에게 제 사정을 잘 설명하고 해결책을 요구했지만, 알고리즘에 있어서는 아직 좀 약한 모습을 보여줬습니다. 일단 모든 차트를 탐색하는 것은 비효율적입니다.

 

그래서 떠올린 해결책이 차트의 특징을 골라내어 같은 특징을 보이는 것 끼리 모아놓고, 이후 비교해야 하는 차트가 제시되면 해당 특징에 맞게 모아놓은 차트들만 탐색하는 방법으로 구현했습니다. 자세한 내용은 이후 포스팅에서 다루겠습니다.

 

2. 메모리를 줄여보자

메모리를 줄이는 것도 매우 중요한 부분입니다. 특히 실행시간을 더 빠르게 하려고 할수록 메모리를 더 많이 사용하는 것이 보통입니다. 시간과 메모리 둘 사이에서 적절한 합의가 중요한 것 같습니다.

 

일단 5년 치 차트를 모두 메모리에 띄우면 실행시간이 빠른 편이지만, 메모리를 너무 잡아먹기에 연단위, 월단위, 10일 단위, 100개 종목단위, 30개 종목단위 등 여러 기준으로 분할하며 테스트해 봤습니다. 결론적으로 300만 개의 모든 차트를 파일로 저장하고 몇만 개 정도의 차트만 메모리에 띄워 해결했습니다.

 

3. 그 외 여러 가지 최적화 실험들

이외에도 여러가지 최적화 방법을 연구하고 테스트해 보았습니다. 이 과정에서 알고리즘 공부를 할 때 배웠던 DP, 그리디, 우선순위 큐, 비트마스킹 등을 활용할 수 있었습니다. 확실히 실전에서 사용되는 것을 보니 이제까지 했던 알고리즘 공부들이 도움 된다는 것이 보람찼습니다.

import matplotlib.pyplot as plt
import math

code = '005930'
latest_image = convert_image(get_stock_data(code, '2023-09-15', preceeding=31), 1, DAY_NUM, '삼성전자', '005930')[0][0]

# 한 행에 표시될 서브플롯 수 (예: 4개)
cols = 10

# 필요한 행 수 계산
rows = math.ceil(50 / cols)

# 새로운 figure 생성
plt.figure(figsize=(20, rows * 2))

# 모든 유사한 이미지 출력
i = 0
for dif, data in similar_images[code][:50]:
    plt.subplot(rows, cols, i+1)
    plt.imshow(data.image)
    # plt.axis('off')  # 축 제거
    i += 1

plt.show()
for dif, data in similar_images[code][:20]:
    print(dif, data.name, data.date)

예시로 삼성전자의 2023년 8~9월 차트와 비슷한 100개의 차트를 테스트하는 부분입니다.





 

배포환경에서도 잘 될까..?

결론적으로 약 2시간의 실행시간과 400MB 정도의 메모리로 전 종목의 비슷한 차트목록추출을 성공했습니다.

 

하지만 최대 사용가능한 메모리가 10GB 이상이고 애초에 CPU 처리속도가 매우 빠른 코랩환경이나 로컬환경에서 테스트를 성공한 것은 의미가 없습니다. 최대 사용가능한 메모리가 1GB이고, 연산속도도 현저히 떨어지는 AWS EC2 인스턴스 환경에서도 과연 성공할 수 있을까 하는 불안감을 가지고 있었습니다.

 

최대한 빠르게 배포 환경을 구축하여 잘 되는지 테스트해 봐야겠네요.

반응형