• Home

엔터프라이즈 환경에서 R Local Repository 구축하기

엔터프라이즈 환경에서 R을 기반으로 분석 환경을 구축할때 가장 문제가 되는 점이 CRAN을 폐쇄된 내부 환경에서 어떻게 접근하느냐 이다. 물론 CRAN접속 없이 소스파일만으로도 설치가 가능하지만 대부분의 유명 패키지의 경우 다른 패키지와 의존관계를 보이고 있고 그러한 의존관계를 가지고 있는 패키지들이 타 패키지들과 의존관계를 가지고 있는 경우가 많아 CRAN없이 하나의 패키지를 설치하기 위해서 많은 불편함이 존재하고 있다.

필자의 경우 http://cran.nexr.com을 구축한 경험이 있어 내부 로컬 저장소를 구축하는데 어려움은 없으나 좀더 간단하게 설정을 하고 싶은 욕구가 있었다. 일반적인 CRAN 미러링 서버의 경우 rsync로 외부 소스 CRAN과 주기적 싱크를 하게 되는 로직으로 동작하는데, 자신의 선택한 버전과 패키지들에 대한 경량 저장소를 만드는것 매우 까다로운 작업이다. 이러한 이유는 내부의 분석 환경은 거의 동질적인 환경으로 설정되어서 같은 패키지에 대해서 여러 버전을 가지고 있을 필요가 없기 때문이다. 물론 이 부분정도는 rsync설정으로 가능하지만 불편하다. 또한 웹서버를 하나 둬야 되는 단점도 존재한다. 물론 웹서버 설정이 그렇게 어려운것도 아니지만 요 하나만으로 apache같은 웹서버를 쓰는건 다소 부담스럽다.

필자가 사용한 방법은 miniCRAN패키지와 경량 웹서버를 이용한 방법이다.

여기서 가정하고 있는 환경은 외부망 <==> 내부 저장소 <= 내부 분석 환경 이러한 환경을 기반으로 한다고 가정한다. 이 환경의 장점은 내부 저장소에서는 외부망을 접근할 수 있지만 내부 저장소에서 내부의 어떠한 다른 서버에 전혀 접근할 수 없고 내부 분석 환경에서는 내부 저장소에 접근 가능한 형태이다. 최소 이러한 환경 정도는 있어야 보안적인 측면과 편리함을 동시에 추구할 수 있다.

내부 저장소에 진입해서 특정 디렉토리에 진입해 miniCRAN패키지를 설치하고 아래와 같은 명령어를 수행해 모든 소스 패키지를 다운받는다(주석 처리된 두 라인을 주석 해제하고 그 아래 두라인을 주석으로 처리하면 된다).

#모든 소스 패키지 백업
library(miniCRAN)

repo <- 'http://cran.nexr.com'

dir.create(pth <- file.path('local_cran'))

#avail_pkgs <- pkgAvail(repos= repo, type='source')[,1]
#makeRepo(avail_pkgs, path=pth, repos=repo)
dep_pkgs  <- pkgDep('quantreg', repos=repo, type = "source")
makeRepo(dep_pkgs, path=pth, repos=repo)

테스트로 quantile 회귀를 수행할 수 있는 quantreg 패키지만 백업했는데, 무려 15개의 의존성을 가진 패키지가 자동으로 로컬 저장소로 저장 되었다.

local_cran 디렉토리 아래의 구조는 아래와 같을 것이다.

  • src/contrib
    • PACKAGES
    • PACKAGES.gz
    • quantreg..

참고로 source만 백업한 이유는 UNIX계열의 R환경은 모두 소스기반으로 패키지를 직접 빌드를 하기 때문이다.

이렇게 구축된 로컬 R 저장소를 서비스 하도록 해보자!

역시 이 부분도 R로 수행이 가능하지만, 간단하게 Python 경량 웹 서버를 이용한다. 이 명령어는 local_cran디렉토리에서 수행한다. 경량 웹서버를 사용하는 이유는 닭잡는데 소잡는 칼을 쓸 필요가 없기 때문이다.

python -m SimpleHTTPServer 5000

경량 웹서버를 실행하고 아래와 같은 명령어로 quantreg패키지를 설치해 보자! 물론 실제 환경이라면 이 부분은 R분석 환경에서 실행되는 명령어고 위 웹 서버 명령어는 로컬 저장소 서버에서 실행될 명령어다.

install.packages('quantreg', repos="http://127.0.0.1:5000", type='source')

아래는 출력 로그이다. 필자의 랩톱이 맥북이라 환경에 맞게 컴파일 된다.

R > install.packages('quantreg', repos="http://127.0.0.1:5000", type='source')
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0100 1677k  100 1677k    0     0   299M      0 --:--:-- --:--:-- --:--:--  327M
* installing *source* package ‘quantreg’ ...
** package ‘quantreg’ successfully unpacked and MD5 sums checked
** libs
gfortran-4.8   -fPIC  -g -O2  -c akj.f -o akj.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c boot.f -o boot.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c brute.f -o brute.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
clang -I/Library/Frameworks/R.framework/Resources/include     -I/usr/local/include -I/usr/local/include/freetype2 -I/opt/X11/include    -fPIC  -Wall -mtune=core2 -g -O2  -c chlfct.c -o chlfct.o
gfortran-4.8   -fPIC  -g -O2  -c cholesky.f -o cholesky.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c combos.f -o combos.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c crq.f -o crq.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c crqfnb.f -o crqfnb.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c dsel05.f -o dsel05.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c etime.f -o etime.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c extract.f -o extract.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c idmin.f -o idmin.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c iswap.f -o iswap.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c kuantile.f -o kuantile.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
clang -I/Library/Frameworks/R.framework/Resources/include     -I/usr/local/include -I/usr/local/include/freetype2 -I/opt/X11/include    -fPIC  -Wall -mtune=core2 -g -O2  -c mcmb.c -o mcmb.o
gfortran-4.8   -fPIC  -g -O2  -c penalty.f -o penalty.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c powell.f -o powell.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c rls.f -o rls.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c rq0.f -o rq0.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c rq1.f -o rq1.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c rqbr.f -o rqbr.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c rqfn.f -o rqfn.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c rqfnb.f -o rqfnb.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c rqfnc.f -o rqfnc.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c rqs.f -o rqs.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
gfortran-4.8   -fPIC  -g -O2  -c sparskit2.f -o sparskit2.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
clang -I/Library/Frameworks/R.framework/Resources/include     -I/usr/local/include -I/usr/local/include/freetype2 -I/opt/X11/include    -fPIC  -Wall -mtune=core2 -g -O2  -c srqfn.c -o srqfn.o
clang -I/Library/Frameworks/R.framework/Resources/include     -I/usr/local/include -I/usr/local/include/freetype2 -I/opt/X11/include    -fPIC  -Wall -mtune=core2 -g -O2  -c srqfnc.c -o srqfnc.o
gfortran-4.8   -fPIC  -g -O2  -c srtpai.f -o srtpai.o
gfortran-4.8: warning: couldn’t understand kern.osversion ‘15.0.0
clang -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/usr/local/lib -o quantreg.so akj.o boot.o brute.o chlfct.o cholesky.o combos.o crq.o crqfnb.o dsel05.o etime.o extract.o idmin.o iswap.o kuantile.o mcmb.o penalty.o powell.o rls.o rq0.o rq1.o rqbr.o rqfn.o rqfnb.o rqfnc.o rqs.o sparskit2.o srqfn.o srqfnc.o srtpai.o -L/Library/Frameworks/R.framework/Resources/lib -lRlapack -L/Library/Frameworks/R.framework/Resources/lib -lRblas -L/usr/local/lib/gcc/x86_64-apple-darwin13.0.0/4.8.2 -lgfortran -lquadmath -lm -L/usr/local/lib/gcc/x86_64-apple-darwin13.0.0/4.8.2 -lgfortran -lquadmath -lm -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
installing to /Library/Frameworks/R.framework/Versions/3.2/Resources/library/quantreg/libs
** R
** data
** demo
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded
* DONE (quantreg)

The downloaded source packages are in
    ‘/private/var/folders/32/j84wlpn91z7f48xmxys_07jc0000gn/T/RtmpafWFHz/downloaded_packages’

몇가지 경고 메시지가 있지만 패키지와 OS마다 상이한 경고인데 일단 잘 설치가 되었으니 무시하도록 한다.

아주 간략하게 컨셉만 설명했는데, 완벽하게 잘 구성된 환경을 구축하기 위해서는 웹서버 프로세스를 데몬화하는 과정이 필수이고 글에 첨부되어 있지는 않지만 패키지를 주기적으로 업데이트 하는 cron잡 역시 관리되어야 될 대상이며, 새로 추가되는 패키지들의 경우에도 주기적으로 로컬 저장소에 저장되는 잡이 추가 되어야 된다. 요런 시스템 관련 작업은 포스팅 주제에 크게 벗어나는 주제니 필요한 분들은 관련 내용을 리서치 해보길 바란다.

Boosting Tree를 이용한 특징 추출

Tree기반의 Boosting 알고리즘을 일반적으로 GBDT라고 이야기한다. 사실 필자가 Boosting기법을 실무에 직접 활용한건 약 9년전 Yahoo!에서 였는데, 당시 지금 모델링하는 방식과는 다른 무식한 방법으로 모델링하고 적용하기를 반복하면서 깊이있는 활용과 이해는 하지 못했던 아쉬움이 있었다. 하지만 다시 그 진가를 확인하고 있는 순간이 왔고 모델링 뿐만 아니라 속성 추출에도 활용 가능한 팔방미인이라는 것을 최근에 알게 되면서 다소 방법론 자체에 고무되어 있는 상황이다.

참고로 Boosting기법에 대한 설명은 이전 포스팅을 참고하기 바란다.

실직적인 의미에서 데이터 분석하고는 거리가 조금 있다고 생각하고 있는(문제의 맥락과 변수 자체의 의미해석과 타 변수와의 관련성을 파악해서 실제 의사결정에 도움을 주는 것을 일반적인 데이터 분석이라 생각하는데, 대회의 경우 성능 목적 자체에만 집중하기 때문이다) 머신러닝 대회인 Kaggle을 보면 2015년도 들어오면서 Boosting 방법이 randomForest와 SVM에 이어서 새롭게 부각되고 있다는 느낌을 많이 받았고 R의 gbm이나 Python 유저들이 즐겨 사용하는 xgboost와 같은 편리한 패키지와 caret과 같은 모델 튜닝 프레임웍의 도움으로 그 활용 범위는 더 넓어지고 이미 대중적인 알고리즘이 되었다는 느낌을 많이 받았다.

불과 몇일전에 팀분에게 소개받은 xgboost의 경우 학습속도가 무지막지하게 느린 gbm에 비해 10배 이상 학습 속도의 향상을 가져온다는 것을 직접 체험하였고, 몇가지 파라메터 셋팅으로 자신만의 Learner를 구성할 수 있는 큰 장점을 가지고 있어 사용자로 하여금 유연하게 활용할 수 있는 여지를 제공해주고 있다. 예를 들면 트리를 독립적으로 생성하고 노드의 속성 선택을 랜덤하게 선택하게끔 파라메터 설정을 하게되면 randomForest 알고리즘으로 동작하게 되는 등 다양한 설정이 가능하다.

게다가 힘들게 튜닝한 gbm 파라메터를 그대로 xgboost로 활용 가능한데, 아래와 같은 파라메터 매핑을 하면 된다.

gbm xgboost
interaction.depth max.depth
n.trees nrounds
shrinkage eta

gbm의 n.minobsinnode파라메터는 대부분 튜닝 포인트에서 빠지니 핵심적인 튜닝 포인트인 위 파라메터만 정리했다.

Boosting Tree를 이용한 속성 추출

Criteo 대회의 우승 코드와 문서를 몇개 찾아볼 수 있는데, 뭐 현재로서는 일반적인 방법이라고 하는 꽤 쇼킹한 속성 추출 방식을 보여주고 있고, 실제 이 덕분에 우승까지 한 것을 볼 수 있다.
간단하게 설명하면 GBDT를 이용해 추가 속성들을 만들어주고 이들 속성과 기본 속성을 모두 별도의 모형(Factorization Machines)에 넣어서 모델링을 수행한 것이다. (이런 특징 추출 작업 + SVM 활용이 Factorization Machines 방법이지 않을까 하는 생각을 해본다)

레코드별로 추가되는 n개의 별도 속성을 만들어 주기 위해 n개의 부스팅 트리를 생성한 이후 각 트리의 leaf노드의 인덱스숫자를 속성값으로 넣어준 것이다. 이 작업으로 속성간의 interaction에 대한 변수를 직접적으로 생성하게되는 효과를 가져오게 되는 것이다. 이 속성을 GBDT features라고 이야기 하는데 이걸 그림으로 표현하며 아래와 같다.


from : https://github.com/guestwalk/kaggle-2014-criteo

개인적으로 이 방식이 시사하는 바가 큰데, 매우 sparse한 속성들에 대해서 다소 차원축소를 하는 효과를 가져오는 잇점이 있다는 것이다. 특히나 속성의 갯수가 레코드의 갯수에 비해서 많은 경우에 활용할 수 있는 유용한 기법이란 생각을 해본다.

사실 이 방식으로 GBDT를 활용하는 사례가 많아져 xgboost의 경우 leaf node의 index를 뽑아내게 옵션까지 제공하고 있는 상황인데, 아래는 관련 예제중이 하나이다.

#from https://github.com/dmlc/xgboost/blob/master/R-package/demo/predict_leaf_indices.R
library(xgboost)

#load in the agaricus dataset
data(agaricus.train, package='xgboost')
data(agaricus.test, package='xgboost')
dtrain <- xgb.DMatrix(agaricus.train$data, label = agaricus.train$label)
dtest <- xgb.DMatrix(agaricus.test$data, label = agaricus.test$label)

param <- list(max.depth=2,eta=1,silent=1,objective='binary:logistic')
watchlist <- list(eval = dtest, train = dtrain)
nround = 5

# training the model for two rounds
bst = xgb.train(param, dtrain, nround, nthread = 2, watchlist)
## [0]  eval-error:0.042831 train-error:0.046522
## [1]  eval-error:0.021726 train-error:0.022263
## [2]  eval-error:0.006207 train-error:0.007063
## [3]  eval-error:0.018001 train-error:0.015200
## [4]  eval-error:0.006207 train-error:0.007063
cat('start testing prediction from first n trees\n')
## start testing prediction from first n trees
### predict using first 2 tree
pred_with_leaf = predict(bst, dtest, ntreelimit = 2, predleaf = TRUE)
head(pred_with_leaf)
##      [,1] [,2] 
## [1,]    4    3 
## [2,]    3    3 
## [3,]    4    3 
## [4,]    4    3 
## [5,]    5    4 
## [6,]    3    3 
# by default, we predict using all the trees
pred_with_leaf = predict(bst, dtest, predleaf = TRUE)
head(pred_with_leaf)
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    4    3    5    4    4
## [2,]    3    3    5    3    4
## [3,]    4    3    5    4    4
## [4,]    4    3    5    4    4
## [5,]    5    4    5    3    4
## [6,]    3    3    5    3    3

 

`Boosting`은  “too good to be true.”라는 문장이 생각이 날 정도로 성능향상이 많이 되는 경우가 있는 다소 사기적인 모형중에 하나인데, 위와 같이 새로운 속성을 추출하는 용도로 활용 가능하다는 것에 필자는 다소 충격을  받은 상황이다.  그리고 데이터를 모형을 통해 추상화 해석하여 새로운 속성을 도출하는 방식은 다소 deep learning의 그것을 보는 듯한 느낌까지 준다.

인정받는 데이터 분석가 되기 – 외부 세미나 요약 –

얼마 전에 발표했던 외부 세미나 자료 요약을 공유한다. 발표자료에 워낙 내용이 없어서 핵심 내용 중심으로 간단한 코멘트를 해본다.

이날 발표제목은 “인정받는 데이터 분석가 되기”였다. 다소 자극적인 제목이나 실제 실무를 해보면서 느꼈던 부분에 기반해서 정리한 내용이라 이런 부분에 대해서 평소 고민했었던 분들에게는 정말 필요하고 힐링되는 내용이였으리라 생각한다.

필자에 대해 다른 분들은데이터 사이언티스트라 부르곤 하며,  자칭 데이터 분석가로 부르니 위 발표제목을 “인정받는 데이터 사이언티스트 되기”로 봐도 될 것이다.

발표때 언급했다시피 아래 11가지 지침은 지극히 개인적인 경험에 의해 도출된 포인트라는걸 염두에 두길 바란다. 개인적으론 이렇게 문장으로 모호한 것들을 정리할 수 있었다는데 의미를 두고 싶다.

손가락(R, Python, SAS …)을 보려하지 말고 달(데이터 분석, 통계…)을 봐라.

 

1

이 부분은 실제 데이터 분석에 입문하는 분들이 가장 많이 시행착오하는 부분이라 넣어본 것이다. 그나마 손가락에 시선이 머물다가 종국에는 달을 바라보는 분들도 적지 않아 나름 손가락을 쳐다보는게 의미있으나, 달을 쳐다보기 까지 시행착오가 필요한것은 안타까운 일이다. 취미로 혹은 잠시 데이터 분석의 맛을 보기 위한다면 달을 볼 필요까지는 없겠으나 업으로 삼으려면 달을 거쳐 저 멀리까지도 갈 의지와 시간이 있어야 할 것이다.

 

데이터 분석가라면 전문 도구를 사용해라! 맨토의 노하우는 도구에 존재하기도 한다.

 

2

 

 

도구라는것은 참 미묘해서 의미를 평가 절하하기도 과대 포장하기도 매우 어려운 존재이다. 시중에는 “도구는 도구일 뿐이다”라는 말이 거의 정답처럼 여겨지기도 하는데 이는 맞기도 하고 틀리기도 하다. 사실 도구는 사고(분석 방향)의 틀을 제공해주는 아주 긍정적인 역할을 수행한다. 게다가 언어적으로 데이터 분석에 맞는 언어를 사용할 경우 효율성도 좋지만 무엇보다 데이터 분석 과정의 여러 실수를 줄여줄 수 있다.

예상보다 우리가 세운 가정들에 대한 데이터 분석 실패가 비교할 수 없을 만큼 다수인 이유의 중요 요인중에 하나는 도구를 잘못 사용한 결과이지 않을까 하는 생각을 해본다. 유의미한 분석 결과는 그 과정 자체에 랜덤한 코딩 실수가 들어갈 경우엔 나오기 어려울 것이고, 코딩 실수는 코드가 복잡하면 할수록 발생할 확률이 높기 때문이다(아이러니하게도 대부분의 코더는 자신의 코드가 완벽하다고 믿는다). 이 때문에 전문 데이터 분석 도구를 사용하는건 반드시 필요하다고 생각한다.

도구를 잘못 사용한 예로는 엑셀불황사례가 있는데, 엑셀이라는 도구가 코드와 데이터가 혼재되는 형태로 만들어진 아주 직관적인 도구라는데서 실수가 나온 대표적인 사례가 아닐까 한다.

도구에는 이 분야의 선구자들의 노하우가 숨겨져 있기도 하다. 예를 들어 Tidy Data로 알려진 `dplyr`, `ggplot2`, `reshape2` 등의 패키지 셋은 정확하고 간단하게 데이터를 전처리하고 시각화하는 어떤 문법이 존재할 수 있음을 알려주며, 실제 여러 실무에서 널리 사용되고 있다는 사실이 그것을 증명하고 있다.

데이터 분석은 과학연구이다. 대조군을 빼먹지 마라!

 

3

 

대부분 과거 데이터를 기반으로 관찰 연구를 많이 하게 되는데, 데이터 분석이 실험연구의 연장선이란 생각을 많은 사람들이 하지 못하기 때문에 대조군 설정에 대한 생각을 하지 못하는 경우가 많다. 논문에서는 빠지지 않는 존재인데, 왜 데이터 분석에서는 빼먹기 일쑤인지 필자도 정확한 원인은 모르겠다.
이런 이유 때문에 논문 쓰기나 읽기가 좋은 데이터 분석 사례가 되는 경우가 많으니 많이 쓰고 읽으라고 권하곤 한다.
실제 이 부분은 자신이 보고자 하는 효과의 `Effect Size`가 어느정도인지 정확하게 설명할 수 있어야 된다는 것의 의미와 같다. 시각적인든 통계적이든 `대조군 대비 실험군의 효과크기`를 항상 생각해야 되며, 대부분의 분석 과제에서 대조군 설정이 어렵고 불가능하지 않다는 것을 잘 인지해야 될 것이다.

개인적으로 트위터 분석 등 대부분의 SNS 텍스트, 네트워크 분석을 신뢰하지 않는 이유중에 하나는 ‘대조군’이 대부분 누락되어 있어 과학이라 말하기 어렵기 때문이다.

 

대조군을 설정하기 너무 어려운가? 그럼 그냥 랜덤으로 선택하라!

 

대부분의 실무 클러스터링은 실패한다! 고객의 다양성을 인정하라!

 

4

from : http://www.kdnuggets.com/2015/08/paradoxes-data-science.html

 

클러스터링이 EDA의 과정이 될 수 있으나, 분석의 결과는 되기 매우 어렵다는 말을 다소 공격적으로 적어봤다. 특히나 고객분석의 경우 클러스터링이 교과서 처럼 될 수 있다는 환상을 버리는게 중요하고, 시간이 가면서 고객은 변하고 그 스펙트럼은 매우 다양하다는 것을 이해할 필요가 있으며 같은 기본가정을 기반으로 분석을 수행하는게 맞다고 생각한다. 이런 관점에서 고객을 베이지언적인 관점으로 바라보는게 때로는 적절하다고 본다.

가설 검증에 실패한것이 분석 실패를 의미하지는 않는다! 애정있게 정리하고 공유하라!

 

5

 

분석 실패는 다양한 원인에 의해서 발생한다.

1. 데이터 전처리 실수
2. 적법한 통계적 방법론 적용 실패
3. 무리한 가설… 혹은 불가능한 가설
4. 소프트웨어 버그
5. ….

1,2,3 항목은 주니어 데이터 분석가들이 주로 실수하는 것이며, 지식이 부족해서 실패한다기 보다는 경헝 부족으로 실패하는 경우라 볼 수 있다. 따라서 분석가 본인이 보기에 실패한 분석 결과라도 애정있게 정리하고 공유하면 여러 동료들의 예리한 눈으로 부족한 부분, 실수한 부분, 보완한 부분들을 찾을 가능성이 높다. 그럼 다시 그 가설은 살아날 기회를 얻게 된다.

자신의 생각을 모두 보여준다는 것에 대해 부끄럽게 생각하지 말고, 공유하고 논의하라!

큰 데이터가 항상 좋은건 아니다.

 

6

 

빅 데이터가 반드시 필요한 영역은 그렇게 많지 않다. 단적인 예로 outlier detection이라든지, anomaly detection류의 문제는 희소한 이벤트 때문에 모집단에 근접한 데이터량이 필요하지만 대부분 모델링, 통계분석을 기반으로 하는 의사 결정에 모집단의 모든 정보가 필요하지는 않다. 오히려 데이터 노이즈와 에러로 인해 전처리를 하는데 많은 시간이 소요되기 십상이다.

필자가 가장 난감하게 생각하는 빅 데이터 기술중에 하나는 통계 모델링을 대량의 데이터로 하게끔 하는 로직을 구성하는 오픈소스 결과물들이다. 예를들어 linear regression의 대용량 버전의 경우 구현이 그렇게 어렵지 않아서(matrix 계산 순서만 바꾸면 되는…) 많은 도구에서 제공하고 있으나 `influencer`들의 영향을 많이 받는 알고리즘적인 특징과 변수간의 평균적인 관계를 찾는 목적때문에 빅 데이터를 사실상 사용할 필요가 없다. 이는 모든 값을 이용한 평균값과 샘플링을 이용한 평균값의 차이가 그리 크지 않다는 간단한 실험만으로도 간접적으로 확인이 가능할 것이다. 물론 데이터가 많을수록 정확도가 향상되는 모델링 기법들이 존재하는데, 이 두 모델의 차이와 의미를 이해하고 빅 데이터 기반 방법론을 활용하는게 효과적일 것이다.

Agile하게 분석하자! 빠른 발걸음으로 보폭은 짧게!

 

7

데이터 분석 과정이나 결과를 주변과 자주 빠르게 공유하는 행위는 올바른 분석을 위해서 매우 필요한 행동이다. 이 과정을 통해서 좋은 분석 아이디어나 자신이 보지 못한 분석 포인트에 대한 힌트를 얻을 수 있으며, 공유를 염두에 두고 데이터를 분석하다 보면 항상 초기의 목적을 상기하는 효과를 가져와 분석이 다른길로 빠지는것을 막을 수 있다.

진짜 좋은것은 빛을 발하는데 시간이 걸릴 수 있다.조바심 내거나 실망하지 말고 때로는 자신만의 업무 가치관 관점으로 바라보는 것이 필요하다!

8

 

요건 데이터 분석가 혹은 과학자가 “장인”과 같은 자세로 일을 임해야 된다는 것을 의미한다. 자신의 가치관으로 혹은 과학적인 관점에서 올바르게 접근해서 나온 결과물은 주변의 상황에 따라서 받는 평가하고는 별개로 봐야 된다. 자신이 생각하기에도 과학적이고 멋진 분석 결과이나 주변에서 인정하지 않는 결과라면 그 가치를 인정받는데 시간이 걸릴 뿐 언젠가는 결국 인정받을 수 있게 된다.

또한 분석 결과에 대한 자신만의 퀄리티 기준과 가치관을 가지는것은 해당 분석 업무를 고퀄로 유지하는데 큰 동기부여가 된다.

EDA는 의뢰인에게 ‘인지적 편안함’을 주는 방향으로 시작하되 그 끝은 차별화된 성과로 맺어야 된다.

9

from : 데이터 분석 상담, 이태림 허명회 공저

 

많은 경우 EDA의 종말은 ‘이미 알고 있는 사실을 데이터로 확인한 결과’가 되는 경우가 많다. 이런 경우 의뢰인에게 `인지적 편안함`만 주고 분석은 끝나게 된다. 이는 대부분 초보 분석가 분들이 가지는 많은 고민중에 하나인데, 이러한 결과가 나오는 원인중에 하나는 대부분 교과서적인 분석만 해봤고, 봐왔기 때문이다. 하나의 분석 주제라도 이를 해결해 나가는 방식은 매우 다양하고 그 결과의 깊이도 다를 수 있다. 고수와 초보의 차이는 여기서 어떻게 한 발자국 더 나아가는지에 따라 갈라진다.

고수와 하수를 가르는 기준은 지능의 차이라기 보다는 이런 훈련이 되어 있느냐 아니느냐 차이인데, 따라서 이런 고민을 평소에 많이 해보는 방법밖에 없다. 그리고 그 도구로 통계를 사용하는 포인트가 매우 중요하다. 그렇지 않으면 분석가의 질문을 검증할수도 없고 검증이 불가능하면 의뢰인에게 전달할 수도 없기 때문이다.

필자가 하나의 팁을 알려주자면 해결하고자 하는 문제를  `Formula` 형태로 정의해 보는 것이다. 이와 같이 정의해보면 단면적으로 문제를 보는 것보다 입체적인 사고를 할 수 있게 되는데, 흡사 위 `Formula`를 `Regression`의 형태로 보는 것만으로도 상당히 많은 인사이트 단서를 발굴해 낼 수 있다. 물론 이를 위해서는 최소 `Regression`에 대해서는 예측 뿐만아니라 추론영역 혹은 이를 활용한 다양한 분석 방식에 통달해 있어야 될 것이다.

매년 1회씩 기초 통계학을 탐독하라!

10

from : 데이터 분석 상담, 이태림 허명회 공저

 

필자가 매년초에 주기적으로 하는 일중에 하나는 기초통계학 책을 탐독하는것이다. 신기하게도 매년 그 의미의 깊이가 다르게 느껴지고 문구 하나하나가 이전에 탐독을 했을때와는 다르게 느껴지는 것을 경험한다. 통계학은 의사결정의 학문이여서 하루에도 수십번 혹은 수백번 의사결정을 하고 살아가는 우리들이 다소 오해할 가능성이 많은 학문이라 생각한다. 왜냐면 우리 자신이 의사결정의 전문가라고 착각하기 때문이다. 따라서 다소 성경책과 같이 곁에 두고 의미를 곱씹어 통계적 의사결정 방식을 몸에 배게 하는 노력이 필요하다.

전공의 프레임에 빠지지 말고 필요한것은 집요하게 공부하고 익혀라!

11

 

대부분 어떠한 전공 커리큘럼을 따라서 공부하는것에 매우 큰 부담을 안고 있다. 이는 이전에 자신이 시간 투자하고 공부한 자신의 전공의 프레임에 빠져 있기 때문이라 생각한다.

능력있는 분석가가 되기 위해서는 사실 거의 체내화 되어 있어야 되는 개념(학문)들이 다수 존재하는데, 이를 위해 시간투자는 불가피하다. 게다가 개론서/소개서 몇권만으로 절대 익히기 어려운 개념들이 대다수여서 필자의 경우 커리큘럼 자체를 공부하라고 추천하곤 한다. 이는 개론서만으로 얻을 수 없는 해당 학문 응용의 지혜를 그 시간투자를 통해서 얻을 수 있기 때문이다. 단순히 교과서적인 분석만을 자신이 수행하고 있다고 한다면 잠시 업무를 내려놓고 여러 통계학 서적과 통계를 여러 다른 방식으로 활용한 방법론 책을 보길 추천하고, 이 과정을 확대하면 통계학 커리큘럼을 따라가게 되는 것이다.

 


 

데이터 분석가는 다소 중세시대의 “장인”과 유사한 직무분야라 생각한다. 상당히 고된 업무이고 분석실패하는 경우도 많으나 경험이 쌓일수록 좋은 분석 결과를 내기 마련이며, 그런 분석 결과를 안정적으로 내기 위해 자신만의 분석 결과 품질 가치관이 정립되는 과정을 겪게 된다. 따라서 긴 호흡으로 문제에 대한 발전적인 고민을 반복하고 개선하려 하는 자세를 가짐이 매우 중요하다 생각한다.