01_프로젝트 애로사항 - smart1004/doc GitHub Wiki

https://blog.naver.com/rek0822/221352272561 회귀분석 프로젝트가 끝났을 때는 막연한 기대감이 있었다. 한 번 프로젝트를 진행해 봤으니 다음 프로젝트는 조금 더 쉬워질 것이라고 더 쉽게 진행할 수 있을 것이라고. 오산이었다.

물론 전체적인 워크 플로우는 능숙해졌다. 파이썬, 특히 판다스 사용이 능숙해지면서 원하는 것을 구현하는데 걸리는 시간을 크게 단축했으며, 기본적인 진행 구조, 분업 등은 확실히 이전 프로젝트에 비해 진일보 했다.

그러나 이전 프로젝트에서는 경험하지 못한 새로운 문제들이 발생하면서 여전히 어려워 하고 있다... 아마 이번 프로젝트에서는 본격적인 분석뿐 아니라 아래 나열된 문제들을 해결하는 것이 키 포인트가 될 것 같다.

  1. 시간 문제

데드 라인이 정해진 상황(일반적으로 항상)에서 시간은 비용이다. 따라서 시간 또한 여타의 비용들과 같이 제한된 상황에서 최대의 효율을 뽑아낼 수 있는 방안을 고려해야 한다.

회귀 분석 프로젝트에서는 모델을 돌리는데 사용된 데이터의 수도 적고 연산 역시 비교적 복잡하지 않았다. 때문에 모델을 돌리면 분석 결과가 바로 나와 모델을 돌리는데 큰 시간이 소요되지 않았다. 덕분에 프로젝트를 하는 동안 전처리와 피쳐 셀렉션이 더 집중할 수 있었고, 다양한 시도도 부담없이 할 수 있었다.

그러나 머신러닝 프로젝트에서는 전처리와 피쳐 셀렉션뿐만 아니라 모델을 돌리는데 걸리는 시간도 고려해야 한다. 머신러닝의 경우 한 번 모델을 돌리는데 걸리는 시간은 짧게는 1분, 길게는 2시간까지 걸린다.

모델을 한 번 돌리는데 한 시간 반…. 이미지 분석 프로젝트일 경우 더 오래 걸리는 것도 부지기수이다.

때문에 어떤 모델이 더 시간이 적게 소모되면서도 좋은 결과를 도출하는지, 또 어떤 패키지가 좋은지 다방면으로 탐구하는 중이다 현재 우리는 Gradient Boost 방식을 쓰기로 가닥을 잡았는데 XG boost보다 더 빠른 lightGBM을 사용하고 있다. lightGBM의 경우XG Boost보다 실행 시간이 많게는 1/5정도 빨라진 것 같은데 성능 차이는 대동소이하다(XG Boost의 경우 Level-wise 방식을 사용하는데, lightGBM은 leaf-wise 방식을 사용하는 점에서 이러한 차이가 나오는 것 같다) 그러나 모델을 돌리는 동안은 다른 작업을 못 하기 때문에 여전히 부담이 되는 부분이다.

  1. 메모리 에러

가장 심각한 문제는 메모리 문제이다.

현재 우리가 다루고 있는 데이터는 7개의 열을 가진 60만개의 데이터이다.
이렇게 보면 그리 크지 않은 데이터 같다.

문제는 대부분의 데이터가 카테고리 데이터라는 것이다.
그리고 각 열마다 카테고리 종류는 DepartmentDescription은 69개, FinelineNumber은 5196개, Upc 는 97715개가 있다. 따라서 모든 값들을 더미변수화 하면 순식간에 데이터 용량이 훅 커져버린다. 특히 우리는 각 각 카테고리 값들을 단순히 있고 없고로 이진 분류를 하는 것이 아니라 각 아이템마다 팔린 개수를 연산한 후, VisitNumber로 groupby를 하려고 하는데, 시간을 견디지 못할뿐만 아니라 노트북에서 연산 과정을 견디지 못하고 계속해서 메모리 에러가 뜬다….

사실 분석에 앞서 데이터 파일을 만들어야 분석을 시작할 수 있는데 본격적인 분석을 시작하기도 전에 데이터조차 만들지 못하고 있으니 이 부분이 가장 답답한 것 같다….

이 문제를 해결하기 위해 여러가지로 알아보고 있다.

  1. 열 수 줄이기 가장 기초적이면서도 핵심적인 방안이다. .
    모든 카테고리 값들을 다 사용하는 것이 아니라 최소의 열 개수로 최대의 정보를 담고자 하는 것이 목표이다. 현재 열 개수를 3000에서 4000개 사이로 분석하고 있으며, 더 줄이는 것이 목표이다. 열 개수를 줄이는 기준은 크게 I)최소빈도 이상과 II)TF-IDF 이 두 가지로 잡았다.

I) 최소 빈도 이상 나온 카테고리 값.

먼저 최소 빈도를 정하고, 이 빈도 이하로 나온 클래스는 버리기로 했다. 예를 들어 전체 데이터에서 1~2번 나온 데이터의 경우 보편성도 떨어지고, 과적합의 가능성이 커질 것이라 가정했기 때문이다. 다만 최소 빈도를 몇번으로, 몇프로로 할것인지는 결과값을 보면서 계속해서 시도를 해야 할 것 같다.

II) TF-IDF TF-IDF는 사실 주로 텍스트 분석에서 사용되는 기법이다. TF-IDF는 여러가지의 문서군이 있을 때 한 단어가 특정 문서 내에서 얼마나 중요한지를 판단하는데 도움을 주는 지표이다. TF란 단어 빈도를 의미하며 특정 단어가 특정 문서 내에서 얼마나 자주 등장하는지를 나타내는 값이다. 따라서 TF가 높으면 해당 단어가 문서에서 중요하다고 판단할 수 있다.

IDF는 DF의 역수(inverse)이다. DF란 특정 단어가 전체 문서군 내에서 등장하는 빈도이다. DF가 높을 경우 모든 문서에서 흔하게 등장한다는 것을 의미하기 떄문에, 역수를 취해주는 것이다. 이렇게 TF와 IDF를 곱한(log등 변환도 함께 해서)값을 TF-IDF라 하는데,

우리는 이 개념이 우리 프로젝트에도 적용될 수 있을 것이라고 생각했다. 특정 TripType에 속하는 사람들이 주로 구입하면서 다른 TripType인 사람들은 구매를 하지 않는 상품일수록 TripType을 구분하는데 좋은 기준이 되는데, TF-IDF값이 높은 값일수록 이 조건을 만족하기 때문이다.
다만 앞선 빈도와 마찬가지로, TF-IDF의 값이 어느 정도 이상인 열만 자를지는 여러 시도를 해 보아야 할 것 같다.

TF-IDF에 대한 더 자세한 설명과 예시는 박사님의 Scikit-Learn의 문서 전처리 기능 강의 자료에 있다. https://datascienceschool.net/view-notebook/3e7aadbf88ed4f0d87a76f9ddc925d69/ 2) 데이터 타입 변환 판다스의 데이터프레임 객체는 기본적으로 np.float64 타입을 사용한다. 그런데 우리 데이터들은 VisitNumber 외에는 그다지 큰 값을 요하지 않기 때문에 np.float16타입이나 np.float32타입을 사용하면서 용량을 줄이는 방법을 강구하고 있다.

  1. Sparse Matrix Sparse Matrix, 한국말로 희소행렬은 행렬의 대부분 값이 0인 경우를 말 한다. 이 경우 단순히 자료를 저장하는 것이 아니라 다른 방식으로 저장해 메모리를 더 효율적으로 사용한다. Sparse Matrix도 여러 종류가 있다. 검색 해 보고 용도에 따라 사용하면 될 것 같다. SciPy에서 여러 Sparse Matrix를 지원하며, pandas에서 to_sparse 명령어를 통해 사용할 수 있다.
  2. DataFrame 내장 연산 메서드 우리는 분석의 정확도를 위해 각 카테고리 열들을 더미 변수를 취해준 후 각각의 판매량을 곱하고 있다.
    그런데 데이터의 수가 많다 보니, 단순히 곱하는 연산조차 시간이 오래 걸린다. 이 경우 apply나 *로 pandas에서 브로드캐스팅 하는 것이 아니라 mul, add 등 pandas 내부 메서드를 이용하면 시간이 더 적게 걸린다. 내부 메서드를 사용하면 value값만 numpy로 연산을 해주 때문이다. parameter 조정을 통해 열 단위 연산을 할지, 행 단위 연산을 할지 등을 정할 수 있다.

프로젝트의 대부분의 시간들을 위 문제를 해결하는데 쓰고 있다. 빨리 다방면으로 분석을 하고 싶어 마음이 급하기도 하지만 또 많은 것을 배우고 있으며, 이전에 신경쓰지 않았던 부분들을 고려하기 시작하면서 성장한 느낌이다(gc와 del 사용의 습관화…). 고생한 만큼 결과가 잘 나오기를! [출처] 프로젝트 애로사항|작성자 JT