데이터를 분석하거나 모델링 하는 업무는 어떤 언어, 어떤 개발환경(IDE)를 사용하던지 핵심에는 차이가 없다.

파이썬은 입문 난이도 및 확장성을 고려했을 때 가장 효율적인 언어이다.

 

서비스에 모델 결과를 제공하기 위해서는 .py 스크립트로 작성하지만,

코드 한줄 한줄마다의 결과를 관찰하며 모니터링 하기엔 주피터 노트북을 사용하는 것이 효율적이다.

(jupyter notebook 또는 jupyter lab)

 

주피터 노트북에서 분석한 결과는 해당 노트북 파일의 링크를 바로 공유할 수도 있고,

내보내기를 통해서 다양한 파일 포맷으로 다운받을 수 있다. (pdf, html, slide 등)

 

nbconvert와 RISE 패키지는 이러한 변환 or 노트북 환경에서의 슬라이드쇼 보기를 지원한다.

- nbconvert : .ipynb 노트북 파일을 HTML, LaTeX, PDF, 마크다운 등 정적인 포맷 파일로 전환

- RISE : 즉각적으로 주피터 노트북을 슬라이드쇼 형태로 보기 (Reveal.js - Jupyter/IPython Slideshow Extension)

Primarily, the nbconvert tool allows you to convert a Jupyter .ipynb notebook document file into another static format including HTML, LaTeX, PDF, Markdown, reStructuredText, and more. 
nbconvert can also add productivity to your workflow when used to execute notebooks programmatically.

With RISE, a Jupyter notebook extension, you can instantly turn your jupyter notebook into a live reveal.js-based presentation.

 

plotly로 분석결과를 시각화 했을 때 인터랙티브한 그래프를 손쉽게 그릴 수 있다.

이 때 pdf 파일로 출력하는 경우 해당 기능을 출력물에서 온전히 사용하기 어렵다.

 

슬라이드 타입은 PPT 같은 느낌을 줄 수 있으나,

이를 위한 사이즈 조정, 포매팅 작업이 더 손이 많이 간다고 판단했다.

 

따라서 HTML 파일로 출력하고자 했고,

jupyter notebook 내에 download 기능은 설치오류가 있어서 

서버 커맨드 라인에서 pip install을 통해 nbconvert를 설치하고,

커맨드라인 명령어를 통해서 파일을 생성했다.

 

최종 결과 코드는 아래와 같다.

--execute 명령어를 입력하지 않으면 plotly 그래프 결과물이 보이지 않는다.

--no-input 명령어를 입력하면 input으로 들어가는 코드 부분이 출력되지 않아 결과만 깔끔하게 볼 수 있다.

jupyter nbconvert --to html --execute --no-input /work_dir/temp.ipynb
# --execute : 실행
# --no-input : 코드 없이

 

 

 

 

[참고]

 - nbconvert: Convert Notebooks to other formats — nbconvert 7.2.10 documentation

 - RISE — RISE 5.7.1

파이썬 및 판다스는 분석가 입장에서 개발적인 지식이 많지 않아도

코드를 활용해서 분석할 수 있게끔 도와주는 훌륭한 도구이다.

 

대용량 데이터를 분석하다보면 결국 한정된 서버자원으로 많은 데이터를 다뤄야하는 순간이 오고,

이 때 분산처리를 활용하는 등의 방법도 있지만,

기존에 판다스로 구성된 코드라면 여러가지 방법으로 메모리 사용량을 줄일 수 있다.

 

여기에 대한 아이디어는 아래 영상을 많이 참고했다. (가급적 이 글보다 영상을 정독하는 것을 추천한다.)

→ https://www.youtube.com/watch?v=0Vm9Yi_ig58

 

위 영상에 나오는 내용 중 내가 채택한 방식은 아래 두가지이다.

 - 데이터프레임에 사용할 컬럼 타입을 효율적으로 지정

 - 파일 저장 포맷을 변경 (csv → parquet)

 

 

1. reduce memery usage

 - 각 컬럼의 전체 값을 스캔한 후 최대, 최소값에 따라 최소한의 가능한 타입을 지정해준다. (float, int)

   이렇게 했을때 약 20~70% 까지 메모리 사용량이 감소하는 것을 확인했다.

   object 타입은 category 타입으로 지정해주면 메모리 사용량이 감소한다.

   메모리 사용량을 측정할 때는 파이썬 패키지 중 memory_profiler를 활용했다.

   (여담이지만 나중에 고생하는 것보다 최초 코드 작성 시에 코드 레벨로 메모리를 프로파일하면 좋았을 것 같다.)

 

 - 데이터가 작은 경우 타입을 조정했을 때 오히려 메모리 사용량이 커지는 경우도 존재했는데,

   무시 가능한 수준으로 보인다.

 

 - 스캔하여 적정한 타입을 찾는 것도 시간이 걸리는 일이라,

   해당 데이터에 얼마나 자주 접근해야하는지 등을 기준으로 두어 위 방법을 적용할지 선택하면 좋을 것이다.

 

2. pyarrow parquet 파일로 저장할 때 halffloat (float16) 타입은 저장이 불가한 오류

 - 위 방식으로 최소한의 타입을 지정하다보면 float16으로 컬럼타입을 지정해주는 경우가 있다.

   이 상태로 판다스의 to_parquet() 기능으로 저장하면 halffloat 타입은 지원하지 않는다는 오류가 발생한다.

   이 경우의 조치 방식은 두가지이다.

   1) float16 > float32 로 변경 후 저장 : 이 방식은 간단하지만 최초 메모리 사용량을 줄이고자 했던 취지에 반한다.

   2) pyarrow에서 engine='fastparquet' 활용

      - pyarrow로 데이터를 처리할 때 엔진을 pyarrow와 fastparquet 중 선택할 수 있다.

        default는 pyarrow로 설정되어 있는데, 필요한 경우 fastparquet을 엔진으로 사용할 수 있다는 걸 알아두면 좋다.

 

 

- 참고 : Parquet에서 Unhandled type for Arrow to Parquet schema conversion: halffloat 이 발생할 때 (velog.io)

Airflow는 목적에 따라 직렬, 병렬로 Task를 배치 및 실행 가능하다.

 

그 중 Dynamic Tasks는 Dag에서 병렬의 개수를 미리 정하지 않아도,

Task가 실행하는 메서드와 연결되어 유연한 병렬 Task 실행을 도와준다.

 

이 때 Command 생성을 위해 사용하는 메서드에 @Task 데코레이터를 사용해 개별 Task를 생성할 수 있고,

데코레이터 없이 메서드를 생성한 후, 실행하는 Operator만 운영할 수도 있다.

 

Command Task → Dynamic Tasks 구조로 연결된 경우 앞선 Command Task가 정상적으로 수행되면

여기서의 xcom 결과를 받아 따라오는 Dynamic Task가 실행되어야 하지만 Skip 되는 에러가 발생.

 

결론적으로 Command Task의 결과가 None 값을 보내주면

Command Task는 Success로 마킹한 채로 Dynamic Task로 넘어가지만,

Dynamic Task에서 실행할 병렬 Task는 0개이므로, 이 전체 Tasks는 Skipped로 처리된다.

 

어느 Task에서도 에러로 표기해주지 않아 문제 원인을 정확히 파악하는데 시간이 많이 걸렸다.

+ Recent posts