데이터 사이언스 수업 수강생들의 질문

0
1076

Teaching position에 있다보면 친구들끼리 모임에서 내 수업에 진짜 똑똑한 학생 있다는 이야기를 하는 경우는 거의 없고 (애시당초 그런 학생이 잘 없다 ㅋㅋ), 대부분은 “내 수업에서 이렇게 깝깝한 질문 받았음ㅋㅋ” 이라는 불평을 토로하는 경우가 많다. 보스턴에서 박사 시절, 학부나 MBA 학생들용 수업 TA로 들어가면, 정말 충격적인 질문을 많이 받았는데, 고교 수준의 등비급수를 몰라서 이해를 못하는 학생, 등비 급수 푸는 법을 알려주고 변수 문자를 r에서 x로 바꾸면 처음보는 것 같은 표정을 짓던 학생 등등 저래놓고 MBA 졸업했다고 자랑질하고 다니겠지… 라는 생각이 들만큼 퐝당한 학생들이 정말 많았다. (그런 친구들 때문에 백인 애들이 수학 못한다는 편견이 생기긴 한다.)

제일 기억에 남는 사건은, MBA 학생 중 하나가 Finance concentration을 고르고 나니 정말 삶이 너무 힘들어졌다, Marketing concentration할 껄이라면서 후회하는걸 엘리베이터 안에서 얼핏 들은 적이 있었는데, 정작 그 MBA 학생이 들었던 수업들은 경영학과 학부 2-3학년 수준의 재무관리보다도 쉬운 수업이었다. 그 과목 시험 채점하면서 Partial credit을 도대체 어디에서 어떻게 줘야할지 모르겠다고 교수님께 불평했더니, “그래서 내가 TA가 필요한거지 ㅋㅋㅋ 그냥 적당히 잘 줘~ 그래야 Complaint 안 들어오지.”라는 조언을 들은 적도 있다. (이게 MBA의 현실이다.)

데이터 사이언스 수업을 하면서도 물론 당황스러운 질문을 받는 경우가 꽤 있지만, 그래도 수학, 통계학 못하면 오지마라는 공포 마케팅(?)에도 제 발로 찾아오신 분들이라 그런지, 굉장히 수준이 높다는 느낌을 받는 경우도 있다. (가끔은 학부만 졸업하고도 수준 높은 질문을 하는 사람들이 있는데, 나는 왜 학부 시절에 저렇게 공부 안 하고 놀았을까 부끄러워지는 경우도 은근히 있다.)

며칠 전엔, 한 달 수업 듣고 정말 열심히 고민하고 또 고민했다는 흔적이 잔뜩 묻어나는 질문 메일을 하나 받았는데, 수강생 분의 동의 아래 질문과 답변 몇 개를 공유할까 한다. 이런 내용을 수업에 가르치고 있고, 또 이런 고민을 따라올 수 있는 사람들이 Data Scientist구나는 이해를 할 수 있는 좋은 자료가 될 것 같아 보인다. (질문 보면서 “깝깝한 질문”이라는 생각보다, 요런거 조금만 더 뚫으면 되는데… 같은 아쉬움이 많이 생겼으니 오해마시라.)

참고로 질문자 분은 수학과 출신으로 어느 회사 데이터 관련 업무 하시는 분이라고 하시더라.

 

1. 회귀모델의 진단

Q. 다중 회귀분석 (Multinomial regression)에서는 모델링 과정에서 정규성, 선형성, 등분산성, 이상치 등을 살펴보기 위해서 Plot을 그려보던데, 머신러닝에서 Gradient descent를 할 때는 Regression에서 하던것처럼 잔차에 대한 여러 가정들을 별도로 확인해보지 않아도 되나요?

A. 수업 중 Ensemble을 다루면서 저 질문에 대한 답변을 좀 더 깊이 있게 다룬다. 통계학에서 Regression은 모델링의 결과값이 Error 최소화, 즉 Variance 최소화에 맞춰져 있다. Variance가 크게 나오면 Regression 모델에서 나온 상관계수들이 0이 아니라고 주장하는 p-value 값을 믿을 수가 없기 때문이다. 그런데, Regression을 (특히 Linear regression을) 적용하는 데이터들은 Error의 패턴이 없는 경우, 즉 데이터의 Error에 해당하는 부분이 랜덤으로 생성된 경우다. 머신러닝을 쓰는 이유는 그런 랜덤이 아닌 부분, 패턴이 있는 부분, 특히 패턴이 단순한 선형 관계 (ax+b)가 아닌 부분을 찾아내기 위해서다.

그런 비선형의 복잡한 패턴을 다항식으로 (무식하게?) 찾아내는데는 한계가 있으니까, 머신러닝의 여러가지 방법론들 (SVM, Decision Tree, Neural network 등등)을 활용하는 것이고, Gradient descent는 그런 탐정놀이 게임 중 수학식으로 쉽게 떨어지지 않는 trial-and-error 계산을 하기 위해 디자인된 계산 방법이다. 비선형 함수를 찾아낸다는 말 자체에서 이미 데이터의 non-random을 가정하고 접근하는 것이고, Gradient descent는 계산 비용을 줄이면서 결과값이 최대한 근사치가 나오도록하는 계산법이다보니, 당연히 잔차의 구조에 대한 고민을 안 하게 될 수 밖에 없다.

 

2. 데이터의 정규성 확인

Q. 데이터에 알고리즘을 적용하기 전에 먼저 정규분포를 따르는지 아닌지 확인하기 위해 Histogram과 QQ-plot을 그려봤는데요, t-test 적용에서와 같이 정규성 검정까진 할 필요가 없는 건가요? 중심극한정리에서는 표본이 충분할 때 “표본분포”가 정규분포의 형태를 따른다고 했는데, 우리가 가진 데이터는 표본 하나인 것과 같으니 단순 데이터 셋의 정규성만 확인해도 충분한 것인지 궁금합니다.

A. 우선 몇 가지 사실 관계를 점검해야할 것 같다.

t-test하는데 정규성 검정이라는 것은, 원래 데이터가 (approximately) 정규분포를 따르고 있는지에 대한 확인이다. 원래 데이터가 정규분포가 아니라면 학부 수업 때 배운 t stat말고 다른 계산법이 존재한다. (수학 & 통계학 시간에 Poisson일 경우 어떻게 해야된다고 했는지 노트 참조)

또 중심극한정리 (Central Limit Theorem, CLT)는 표본이 충분하면 분포가 정규분포를 따르는게 아니라, 샘플 추출을 여러번 했을 때, 그 평균값이 정규분포를 따른다는 정리다. 쉽게 예시를 들면, 모집단을 모르고 단순하게 1,000명의 표본집단만 여러번 뽑으면 (ex. 선거 직전 여론 조사), 그 표본집단의 평균값들 (처음엔 평균이 49%, 다음엔 51%, 그 다음엔 48.5% 등등등)이 정규 분포 형태고르게 퍼진다는 뜻이다. (수학적으로는 정규분포에 수렴한다고 표현한다.) 데이터가 많으면 무조건 정규분포에 수렴한다고 잘못 알고 있는 사람들이 많은데 (나도 예전엔….), 그러다보니 Underlying distribution이 포아송 분포인데도 t stat을 무조건 정규분포 기반으로 계산해서 모델 테스트를 엉망으로 하고 있다고 수학 & 통계학 시간에 강조한 바 있다.

일단 위의 1번에서 설명한대로, 데이터(의 에러)가 정규분포를 따른다면 Random 이라는 뜻이니까, 단순한 Linear regression으로 충분한 모델링이 되고, 머신러닝에서 배운 여러 테크닉들은 그런 randomness가 깨질 때만 의미가 있다. 따라서 현재 가진 데이터의 정규성을 확인해보는 것만으로 충분하다.

 

3. lm(), glm() 등의 함수와 caret 패키지 사용의 차이

Q. R 코딩 실습 부분에서 저는 평소 caret 패키지를 사용하지 않았었는데요, lm(), glm(), svm() 드으이 함수를 쓰는 것과, caret 패키지에서 method = ‘lm’, ‘glm’, ‘svm’ 등을 지정하는 것은 계산 방식에서 어떤 차이가 있나요? 앞의 함수들은 Normal equation으로 해를 구하고, caret은 gradient descent 알고리즘을 이용하는 건가요?

A. 우선 Normal equation이 작동하는 유일한 영역은 데이터가 정규분포를 따르고, 그 때 Best Unbiased Estimator인 MLE가 OLS estimator와 똑같을 때 밖에 없다. 이게 통계학 수업 시간에 배우는 내용이다.

위에 나온 glm(), svm() 같은 머신러닝 모델을 간략화해놓은 함수들은 Normal equation을 쓰는게 아니라, glm은 Newton’s method를 이용한 approximation, svm은 Duality를 이용한 Group error minimization 계산을 한다.

두 계산 함수 그룹의 차이는, caret은 R 플랫폼의 함수들을 결합해서 위의 계산을 하도록 만든 패키지고, svm, xgboost등의 외부 패키지들은 외부 플랫폼 (C++, Java 등등)의 계산 모듈을 빌려온다. 왜? 계산 속도 자체만 놓고보면 시스템 자원을 효율적으로 쓰지 못하는 R이 압도적으로 느리니까. 참고로 Python, R등의 언어는 C++, Java가 시스템 자원을 활용하는 방식과는 완전히 다른 설계로 짜여져 있기 때문에, 계산 속도가 현격하게 차이날 수 밖에 없다.

Python에서도 scikit-learn을 쓰면 R의 caret과 똑같은 상황이 벌어질 것이다. 진정한 개발용 언어인 Java, C++이 1초만에 계산하는걸 R이나 Python위에서 Java, C++의 계산 모듈을 빌리면 3-4초로 늘어나고, 그냥 caret, scikit-learn 위에서 돌리면 거의 20초 정도 걸린다는 벤치마크도 있다. 데이터를 처리하고 모델링을 고민할 수 있도록 만들어 놓은 프로그램이니만큼, 복잡한 데이터 구조 (ex. n x k x p x q 행렬)를 처리하는데 초점이 맞춰져 있다보니 정작 계산 속도의 효율성 측면에서는 굉장히 나쁜 플랫폼이 되어버리는 것이다.

 

4. Polynomial regression의 경우의 수

Q. 회귀 직선이 주어진 변수만으로 적합이 안 되어서 Polynomial 형태를 적용하게 될 때, 기존 변수가 n개라면 n(n+1)/2의 경우의 수가 생기게 되잖아요. 그럼 회귀 모델 적용할 때 2차 교호작용까지 고려해서 모델을 만드는게 이런 Polynomial 형태를 고려하는 형태의 예라고 생각해도 될까요? 만약 맞다면, 그래서 2차 교호작용 외 다른 경우의 수도 고려하고 싶다면, 실제로 n(n+1)/2 횟수만큼 변수를 바꿔가며 코딩을 해야하나요?

A. 아니다. (걱정하지 마시라ㅋㅋ)

그런 Polynomial regression을 이것저것 모든 조합으로 다 해보는게 무모한 작업이라는 걸 알고 있기 때문에 svm, decision tree, ensemble, neural network 같은 대체재들이 있는 것이다. Polynomial을 쓴다는 것 자체가 이미 데이터가 선형으로 설명되지 않는다는 이해를 깔고 있고, 데이터가 랜덤이라는 가정을 깨고 들어가는 것이다. Non-linear 패턴을 잡아낸다고 했을 때, 인간이 할 수 있는 가장 단순(무식)한 방법이 Polynomial이고, 이걸 좀 더 수학적으로 세련되게 (학문적으로는 Elegant라고 표현함) 만드는 모델이 바로 여러분들이 열심히 머신러닝 테크닉이라고 배우는 svm, ensemble, neural net 같은 모델들이다.

참고로, 지금도 사회학 계열로 연구하는 분들 중에 통계학을 거의 모르는 분들은 stepwise regression이라고 모든 변수를 다 넣어보고 그 중에 설명력 (R-squared)이 제일 좋은 모델을 “단순하게” 고르는 경우도 있다. (저 분도 박사학위가 있는데, 니가 생각하는거처럼 그렇게 절망적으로 통계학을 모르진 않을꺼야…라고? 연구자 취급 못 받을 사람들 진짜로 많다 ㅋㅋㅋ)

 

5. Variable Importance를 통한 변수의 중요도 판단

Q. Random Forest, Boosting 계열의 모델을 보면 Variable importance에 순위를 잡던데, 그 변수가 중요변수가 아닐수도 있다고 하셨던 부분이 어떤 경우였는지 잘 기억이 안 납니다. 

A. Random Forest를 비롯한 Tree 기반의 모델들에서 중요한 변수들 중에, 한 변수가 Tree 안에 여러번 반복이 되기 때문에 중요한 변수로 나타나는 경우가 있다. Tree 구조를 보면 이해가 되겠지만, 그 변수의 여러 구간 (ex. 3-5, 10-15, 30-37 등등, 연속되지 않은 여러 구간)이 y값에 영향을 주는 경우에 Linear regression에서는 연속된 구간 값을 사용하는 탓에 두 모델간 변수의 중요도가 다르게 나올 여지가 있다. 수업 중에서 Variable Importance plot을 그린 다음, 이걸 Regression 기반 모델들에도 무조건 적용하면 문제가 생길 수 있다고 지적하기도 한다.

 

6. 기타 추가 질문

Q. 우연히 ‘머신러닝 피드백을 이용한 게임 지표 분석’ 이라는 글을 보게 되었는데, 제가 실무적으로 활용하면 도움이 될듯한 내용들이라 꼭 적용해보고 싶은데요, 정확히 어떤 개념을 이용하는 것인지 잘 모르겠습니다.

링크의 글을 읽어보면, Vowpal-wabbit을 통해 손실함수를 계산해서 각 독립 변수들이 종속 변수에 어떻게 영향을 주는지 귀납적으로 추론한다는 방식이고, 여기서 독립 변수마다 계산된 연관성 점수 (Relation score)에 따라 positive, negative를 판단하여 독립 변수들의 영향도? 효과? 등을 파악한다는 것인데 여기서 나오는 연관성 점수가 무엇일까요?

A. 두 가지 경우를 생각해보자.

1번. 위의 5번에서 본 Variable importance를 구하는데, +인 경우와 -인 경우를 구분해서 순위를 다시 잡으면 어떻게 될까? 그 다음 단순하게 몇 %의 기여도만 따지는게 아니라, 기여도가 있는 변수들을 다 모아놓고 -100% ~ +100%로 재조정을 한다면?

2번. Regression에서도 가능할까? 물론이다. 모든 변수를 standardize 해놓고, 각각의 상관계수 값에 따라서 어떤 변수가 더 큰 기여도를 가지는지, 어떤 변수가 마이너스 기여도를 가지는지 구분할 수 있다. 그렇게 상관계수들을 모아놓고 등수를 잡거나, -100% ~ +100%로 재조정을 해도 된다.

실제로 Variable importance를 구하는 과정을 보면, 각각의 변수가 cost function 값이 얼마나 변하도록 만드는지에 따라서 변수의 중요도를 따진다. Regression에서 모든 변수를 같은 구간에서 움직이게 묶은 다음 (i.e. 표준화) 상관계수를 보는 것도 같은 컨셉이다.

저 링크의 글을 보면 Vowpal-wabbit이 무슨 엄청나게 기술(!)력 있는 모델인 것처럼 느껴지는데, 정작 위에서 설명한 단순한 중요도 계산 + 재조정 작업에 불과하다.

“우와~ 이거 완전 대박이네!”, “어캐 베끼지?”

보통 공대생, 특히 수학 (계산말고 수학) 공부 많이 하는 전공자들에게서 흔히 보는 모습인데, 뭔가 새로운 계산만 나오면 “우와~ 이거 완전 대박이네!”, “어캐 베끼지?” 이런 반응을 보이더라. (뭐, 스티브 잡스도 베끼는거 좋아하긴 했다.) 머신러닝에서 Neural network도 그래서 “떴다”고 생각한다. 그러나, 필자 같은 사람들 눈에는 “저거 XYZABCD로 계산했겠네”가 그냥 눈에 보인다. 평소에도 저런 모델링을 하는걸 머리속으로 고민하고 있으니까. 더더군다나 Vowpal-wabbit은 그렇게 수학적으로 Elegant 한 방법도 아니다. 저거 제대로 돌아가게 하려면 보정작업이 엄청나게 많이 필요할 것이다. (직접 적용해보시라.)

 

나가며 – 데이터 사이언스 (진짜) 공부란?

질문이 더 많았는데, 질문자분의 Privacy도 좀 고려해드려야 되겠고, 나머지는 강의와서 들으시라고, (더 솔직하게는 치다가 지쳐서…) 6개의 질문으로 요약정리해 봤다. 질문 내용도 아주 살짝 바꿔썼는데, 자기 글을 고쳐서 기분 좋을 사람 없다는 걸 잘 알기에, 질문자 분의 넓은 아량을 구한다.

마지막 6번 질문을 제외하고 받았던 모든 질문들은 사실 수업 시간에 최소 1번 이상 언급하고 갔던 부분이고, 많은 부분은 여러번 반복 설명을 하게 된다. 보통은 수업 때 했던 이야기를 다시 질문하면 (귀차니즘에) 메일로 상세하게 답장을 하질 않는데, 질문자 분이 뭔가 열심히 노력하고 있는데 (아주 얇은) 벽을 하나 못 뚫은 상태인 것 같아서 큰 맘을 먹고 최대한 상세하게 답변을 해 드렸다.

아마 수업에 오시는 분들 중 석, 박 학위까지 깊이있는 공부를 안 하신 분들 대부분이 위의 질문자 분과 비슷한 수준의 이해도를 갖고 강의장을 떠나게 될 것이다. 한번듣고 쉽게 알 수 있는 내용이 아니니까 ㅋㅋ

“한번 듣고 쉽게 이해할 수 있는 내용은 아니죠.”

학부 3학년 때 계량경제학을 듣는데, 황윤재 교수님이 “한번 듣고 쉽게 이해할 수 있는 내용은 아니죠.”라고 웃으면서 질문을 받아주셨던 기억이 난다. 위의 짧은 질문 & 답변을 보면서, 어느 경제학과 출신 학생 분처럼, 계량 공부 잘 해놨으면 머신러닝이라는거 진짜 쉽구나는 생각을 하신 분도 있을 것이고, 이거 진짜 코딩이랑 완전히 다른 지식이네라고 깜놀(!)하시는 개발자 분도 있을 것이다. 그런 정보 공유 차원에서 수업 내용 중 일부에 해당하는 질문 & 답변을 공개해봤다.

꼭 필자의 수업을 오라고 홍보하는건 절대로 아니고 (모르면 진짜 오지마시라… 가르치기 힘들다ㅠㅠ 특히 무조건 코딩이라고 우기는 꼰대 개발자들…), 굳이 더 속내를 드러내자면 아마 시중에 돌아다니는 대부분의 교재들에서 위의 질문에 대한 제대로된 답변을 못 찾을텐데, 이게 진짜 데이터 사이언스 공부라는 걸 좀 일깨워드리고 싶었다. 그 책들 십중팔구는 개발자들이 여기저기서 코드 따와서 급조한 책이니까. 필자만큼 수학 공부한 사람들이 머신러닝 바라보고 이해한 책을 쓰면 “수포자 입장에서 수학이 너무 어려웠다”는 둥, “다시 고교 정석책을 펴야될 것 같은 압박이 생기네요.”라는 둥의 잘못된 이해에 기반한 비겁한 변명만 들을 가능성이 높기도 하고, 그런 책은 잘 안 팔리기도 할 것이기 때문에 기획하기가 더더욱 힘들지 않을까? 이거 코딩인 줄 알고 있는 개발자들 제발 비겁한 변명 좀 그만했으면 좋겠다 ㅋㅋ

“R이랑 Python 코드 비교하기” 같은 코딩 책 써달라던 어느 출판사 분 생각난다. 데이터 사이언티스트 입장에서 양심의 가책이 느껴지는 코딩(!) 책을 내 이름을 걸고 내고 싶지 않더라.