gimmesilver's blog

Agbird.egloos.com

포토로그



기계 학습과 코딩의 종말 #2 - 연역적 프로그래밍과 귀납적 프로그래밍 데이터분석


-----------------------------------------
4. 기존의 프로그래밍과 기계 학습에 의한 프로그래밍
  단순화해서 보면 프로그램은 어떤 입력에 대해 특정한 출력을 하는 함수라고 생각할 수 있습니다. 예를 들어 여러분이 이 글을 볼 때 사용하는 웹 브라우저는 마우스 클릭 등의 사용자 행동을 입력으로 받으면 그에 맞는 웹 페이지를 출력하는 함수입니다. 그리고 프로그래머는 프로그래밍 언어를 이용해서 해당 프로그램(함수)의 내부 로직을 구현하죠. 이것을 도식화하면 <그림 7>과 같습니다.

<그림 7> 기존의 프로그래밍 방식

  한편, 기계 학습을 이용한다면 방식이 조금 달라집니다. <그림 8>에 나와있듯이 '기계 학습 프로그램'이 있고 이 프로그램에 사용자가 입력값과 그 입력값을 통해 출력되기 원하는 결과값으로 이뤄진 '학습 데이터'를 입력하면 이 '기계 학습 프로그램'이 사용자가 원하는 '프로그램'을 생성합니다. 비록 기계 학습 분야에서는 기계 학습 프로그램이 만든 프로그램을 '프로그램'이라고 부르지 않고 '모델'이라고 부릅니다만 위 관점에서 보자면 기계 학습 모델은 일종의 프로그램(혹은 함수)입니다. 마치 기존에는 사람이 어떤 물건을 직접 만들었다면 요즘에는 '어떤 물건을 만드는 로봇'을 사람이 한번 만들고 나면 그 로봇이 '물건'을 계속해서 생산하는 것과 비슷합니다.

<그림 8> 기계 학습을 이용한 프로그래밍 방식

  예를 들자면, 우리가 많이 사용하는 네이버나 구글 같은 웹 메일 서비스에서 흔히 제공하는 스팸 메일 분류기를 생각할 수 있습니다. 스팸 메일을 분류하기 위한 규칙을 정규 표현식 같은 방법을 써서 프로그래머가 직접 구현하는 방식이 <그림 7>과 같은 방식입니다(그리고 과거에는 실제 이런 식으로 분류기를 직접 개발하는 경우가 종종 있었습니다).
  반면, 나이브 베이지안 알고리즘과 같은 기계 학습 알고리즘을 사용하여 스팸 분류를 위한 기계 학습 프로그램을 구현한 후 이 프로그램에 대량의 스팸 메일과 일반 메일 데이터를 입력하여 학습을 시키는 방식이 <그림 8>과 같은 방식입니다. 이 프로그램은 수많은 메일 데이터를 이용해서 스팸을 적절히 분류할 수 있는 '스팸 메일 분류 프로그램'를 생성합니다. 그러면 웹 메일 서비스 업체에서는 이 기계 학습 프로그램이 생성한 '스팸 분류 프로그램'을 이용하는 것이죠. 
  대개의 경우 실전에서는 <그림 7>과 <그림 8>의 방식을 혼용해서 사용합니다. 예를 들어 기계 학습이 만든 스팸 필터를 이용해서 1차 분류를 한 다음 좀 더 정교한 분류 규칙은 프로그래머가 추가로 구현하는 것이죠. 그러나 점점 기계 학습 기법이나 성능이 발전하고 학습에 사용할 수 있는 데이터가 많아지면서 후자의 역할은 줄어들고 있습니다. 마치 기존에는 기계가 사람의 노동력을 보조하는 수준이었다면 이제는 점점 로봇에 의해 완전 자동화되고 있는 것처럼요.

5. 기계학습으로 8bit 덧셈기 구현하기
  '8bit 뎃셈기' 란 말 그대로 0~255 까지의 범위를 갖는 두 개의 숫자를 더한 값을 출력하는 디지털 회로를 의미합니다. '덧셈'은 너무나 단순하고 기본적인 연산이고 보통은 어떤 프로그래밍 언어에서든 기본으로 제공되기 때문에 간과하기 쉽지만, 사실 이것 역시 두 개의 숫자를 입력하면 두 숫자의 합을 출력하는 '프로그램(혹은 함수)' 입니다. <그림 9>는 논리 회로를 이용해 덧셈 연산을 구현한 도식입니다.

<그림 9> 논리회로를 이용해 구현한 8bit 덧셈기

  1편에서 소개했듯이 뉴럴 네트워크는 이론적으로 어떤 논리회로도 표현이 가능합니다. 따라서 적절히 학습만 한다면 <그림 9> 에 있는 덧셈 연산기 역시 뉴럴 네트워크를 이용해서 구현할 수 있습니다. 아래 코드는 H2O 라는 딥 러닝 라이브러리를 이용해서 덧셈 연산기를 구현하는 아주 간단한 R 코드입니다.

library(h2o)
h2o.init()
sample.size<-500000
x1<-sample(1:255, sample.size, replace=TRUE)
x2<-sample(1:255, sample.size, replace=TRUE)
y<-x1+x2
train<-data.frame(x1, x2, y)
adder<-h2o.deeplearning(x=1:2, y=3, training_frame=as.h2o(train), hidden = c(200, 200))

  보다시피 위 코드에서는 두 개의 숫자를 더하는 작업을 하는데 필요한 로직을 구현하는 코드를 찾아 볼 수 없습니다. 단지 0~255 사이에서 임의로 선택한 두 수와 그 합으로 구성된 데이터 50만개를 '기계 학습 프로그램'의 입력값으로 넣을 뿐입니다. 그러면 '기계 학습 프로그램'은 출력으로 덧셈을 계산하는 '프로그램'(위 코드에서 'adder')을 반환합니다.

<그림 10> 위 기계 학습 프로그램이 생성한 8bit adder 실행 예. 12 와 209 를 입력하면 221이라고 정답을 내놓습니다.

  어떤 분들은 이런 단순한 연산은 어찌 가능할지 몰라도 우리가 일반적으로 사용하는 복잡한 프로그램을 어떻게 훈련만으로 만들 수 있겠느냐고 생각하실지 모릅니다. 그러나 앞서 1편에서도 언급했듯이 우리가 사용하는 바로 그런 프로그램들 역시 모듈 단위로 점점 세분화해 보면 이런 단순한 연산자들의 조합일 뿐입니다. 따라서 그럼 복잡한 로직을 흉내내는데 필요한 데이터와 훈련 시간만 충분하다면 그런 프로그램을 뉴럴 네트워크를 통해 학습하지 못할 이유는 없습니다.

  다만 이것은 기존 관점에서 보면 '프로그래밍'이라고 부르기 힘듭니다. Wired 의 컬럼 제목인 'Soon we won't program computers. We'll train them like dogs' 에서 표현되어 있듯이 이것은 그저 우리가 개를 훈련시킬 때 원하는 행동을 계속 반복해서 가르치는 것과 비슷합니다. 기계 학습 프로그램에게 어떤 입력에 대한 출력을 반복해서 입력함으로써 원하는 로직을 학습시키는 것이죠.
  더 나아가 <그림 7>과 <그림 8>의 '프로그램'을 만드는 방식에는 논리적으로도 매우 큰 차이가 있습니다. <그림 7>에서 프로그램 로직은 사람의 연역적 사고에 의해 만들어집니다. 일종의 우리가 알고리즘이라고 부르는, 다시 말해 'A 이면 B 이고 B 이면 C 이니 A 이면 C 이다'와 같이 연역적으로 타당한 규칙의 흐름을 통해 로직을 구성합니다.
  반면 <그림 8>의 프로그램은 다릅니다. 기계 학습은 수많은 데이터를 통해 귀납적으로 로직을 구성합니다. 기계 학습 알고리즘은 실제 사용자의 의도에 대한 이해를 바탕으로 로직을 구성하는 것이 아니라 학습 데이터 상에 나온 어떤 입력에 대해서 정답과 최대한 근사한 값이 나오는 것을 목표로 로직을 구성합니다. 비약하자면, 물리 법칙에 맞춰 정확한 설계대로 자동차를 만드는 것이 기존의 프로그래밍 방식이라면 기계 학습은 부품들을 쭉 늘어놓고 마구잡이로 부품을 끼워 맞춰서 어찌됐던 굴러가는 무언가를 만드는 방식입니다. 그게 우연히 기존 자동차와 동일한 설계를 가질 확률은 거의 0에 가깝지만 그렇다고 해서 0은 아닙니다. 게다가 설령 전혀 기존 자동차와 다른 형태를 지녔더라고 해도 일단 굴러간다는 목적만 충족한다면 크게 상관이 없을 수도 있죠.

  그런데 바로 이런 점 때문에 (적어도 현재까지의) 기계 학습이 만드는 로직은 귀납법이 가진 한계를 똑같이 같고 있습니다.

6. 귀납의 오류
  위에서 예로 든 덧셈기는 사실 실제 덧셈기와 동일한 로직을 갖고 있지는 않습니다. 아니 좀 더 정확히 말하면 동일한지 아닌지를 알 수 없습니다. 단지 테스트를 해 보니 실제 덧셈기와 동일한 결과를 출력하니 그런가 보다 하는 것이죠. 이건 마치 존 설이 제기한 '중국어 방' 문제를 연상케 합니다.
  <그림 11> 존 설의 '중국어 방' - 중국어를 모르는 어떤 사람이 단지 주어진 메뉴얼대로 중국말에 답할 경우 이 사람이 중국어를 안다고 말할 수 있을까요?

  그런데 이 때문에 뉴럴 네트워크를 통해 구현한 덧셈기는 오류의 가능성을 내포하고 있습니다. 게다가 실제로도 그렇습니다. 위 덧셈기에 대해서 계속 덧셈 문제를 테스트해보면 약간의 오차가 발생합니다. 예를 들어 제가 아래와 같이 다양한 숫자에 대해서 1000번을 테스트를 해보면 기계 학습이 만든 덧셈기는 대략 0.5정도의 오차가 발생합니다. 

test.size<-1000
x1<-sample(1:255, test.size, replace=TRUE)
x2<-sample(1:255, test.size, replace=TRUE)
y<-as.numeric(x1+x2)
test<-data.frame(x1, x2, y)
result<-as.data.frame(h2o.predict(adder.model, as.h2o(test)))
test$pred<-round(result$predict)
sqrt(sum((test$pred-test$y)^2)/nrow(test)

  물론 이런 오차는 아마도 더 복잡한 뉴럴 네트워크를 구성하고 더 많은 데이터를 학습시킨다면 점차 줄어 들겠지만 완벽히 없앨 수 있다는 보장은 할 수 없습니다. 연역적으로 구성된 로직이라면 알고리즘에 대한 수학적 검증을 통해 알고리즘이 정확한지 여부를 알 수 있습니다. 반면 귀납적으로 구성된 로직은 모든 경우의 수를 테스트해 보지 않는한 정확성을 보장할 수 없습니다. 이 '모든 경우의 수'는 우리가 프로그램 QA를 할 때의 '모든 테스트 시나리오'와 다릅니다. QA에서 수행하는 테스트는 좀 더 추상화된 수준이지만 귀납적 로직에서의 '경우의 수'는 말 그대로 가능한 모든 경우의 입력 데이터를 말합니다. 따라서 현실적으로는 불가능에 가까운 수준입니다.
  바로 이런 점 때문에 기계 학습은 '프로그래밍에 의해 만든 프로그램'을 비슷하게 흉내낼 수는 있지만 정확히 그 프로그램을 '훈련'시킬 수는 없습니다.

7. 맺음말
  쓰고 나니 글이 불필요하게 길어진 것 같은데 짧게 요약하자면, 뉴럴 네트워크 기반의 기계 학습은 이론적으로 보면 기존의 프로그램을 그대로 표현할 수 있습니다. 하지만 기계 학습이 프로그램을 만드는 방식은 기존의 소프트웨어 개발과는 매우 다른 방식입니다. 어떤 복잡한 로직을 구현하기 위해 프로그래머가 머리를 싸맬 필요가 없고 단지 원하는 결과를 기계 학습이 제대로 구현할 때까지 반복해서 학습 시키기만 하면 될 뿐입니다. 이건 마치 프로그래머가 테스트 케이스를 먼저 만들어 놓고 이 테스트를 통과하도록 로직을 구현하는 TDD를 자동화하는 것과 비슷해 보이기도 합니다.
  그렇다면 이제 정말 프로그래밍이 더 이상 필요없어질까요? 아쉽게도 (아니 다행스럽게도) 이런 방식에는 현재까지로 볼 때 6장에서 언급한 것과 같은 치명적인 한계가 있습니다(만약 없다면 이 세상의 프로그래머들은 대부분 필요가 없어지겠죠). 그리고 바로 이런 한계를 극복하는 것이 아마도 기계 학습의 과제 중 하나이지 않을까 싶습니다. 다만 제가 생각하기에 초기의 자동차도 형편없는 효율성을 갖고 있었지만 결국 말과 마차를 넘어섰듯이 기계 학습에 의한 프로그램 역시 현재의 프로그래밍을 상당 부분 대체할 수 있지 않을까 생각합니다.

IEEE TIFS 논문 게재 단상

비록 숟가락만 얹은 논문이지만 그래도 내 이름이 들어간 논문이 무려 IEEE transactions 에 실리다니... 기쁘다.


pxd talks #70 - 데이터 분석을 통한 게임 유저 모델링 데이터분석

  지난 주 pxd 라는 회사에서 데이터 분석을 이용한 게임 유저 모델링을 주제로 발표를 했습니다. UX 관련 회사이고 직원분들 대부분이 데이터 분석과 직접적인 관련이 없다고 들었는데 예상외로 굉장히 열심히 들어주시고 질문도 많이 주셔서 놀랐습니다. 오히려 제가 충분히 원하시는 정보나 답변을 못드린 것 같아 죄송하네요. 
  혹시 관심있으신 분들을 위해 해당 자료 공유합니다.




선형 회귀 모델에서 '선형'이 의미하는 것은 무엇인가? 데이터분석

1. '선형(linear)'은 x의 1차 다항식을 의미하는 것이 아니다.
  인터넷에 돌아다니는 많은 자료들을 보면 선형 회귀 모델을 잘못 설명하고 있습니다. 이런 자료들을 보면 공통적으로 선형 회귀 모델의 의미를 독립 변수(x)와 종속 변수(y) 간의 관계가 일차식으로 표현되는 것이라고 설명하고 있습니다. 그래서 독립 변수를 제곱근이나 로그 함수 등을 이용해서 적당히 변환하면 비선형 모델을 선형 모델로 만들 수 있다고 설명합니다. 그러나 이것은 '선형'의 의미를 잘못 이해하고 있는 것입니다. 즉, 아래 그림에서 왼쪽 그림은 선형 모델이고 오른쪽 그림은 비선형 모델이라고 설명하는 경우가 많은데 잘못된 예시입니다(둘 다 선형 회귀 모델로 표현 가능합니다).

<그림 1> 선형 회귀 모델과 비선형 회귀 모델로 각각 검색했을때 나오는 대표적인 이미지 예

  선형 회귀 모델은 '회귀 계수(regression coefficient)를 선형 결합으로 표현할 수 있는 모델'을 말합니다. 즉, 독립 변수가 일차식이냐 이차식이냐 로그 함수식이냐가 아니라 우리가 추정할 대상인 파라미터가 어떻게 생겼느냐의 문제입니다. 가령 아래 함수들은 모두 선형 회귀식입니다.

  예를 들어 첫번째 식의 경우 독립변수인 x를 기준으로 생각하면 x^2, x^3 때문에 비선형이라고 생각하기 쉽지만, 앞서 언급했듯이 회귀 모델의 선형성은 x가 아니라 회귀 계수인 베타0, 베타1, 베타2, 베타3을 기준으로 생각하는 것이기 때문에 이 기준으로 보면 선형 회귀식입니다. 게다가 위 식들은 '선형성'에 직접적으로 관련되지 않은 변수인 x와 y를 적절히 변환할 경우 모두 선형 회귀식으로 표현이 가능합니다. (아래 식에서 log 는 모두 자연 로그) 

  비록 위와 같이 데이터 변환을 통해 선형 회귀식으로 표현가능한 회귀식을 좀 더 엄밀하게는 linearizable regression model(우리말로 하면 선형 가능 회귀 모델?)이라고 구분하여 부르기도 하지만 포괄적으로 봤을 때는 그냥 선형 회귀 모델이라고 부르는 것이 맞습니다. 왜냐하면 이런 linearizable regression model 의 파라미터를 추정할 때도 일반적인 선형 회귀 모델과 동일한 기법을 사용하기 때문입니다.

2. 그럼 비선형 회귀 모델은 무엇인가?
비선형 모델은 데이터를 어떻게 변형하더라도 파라미터를 선형 결합식으로 표현할 수 없는 모델을 말합니다. 이런 비선형 모델 중 단순한 예로는 아래와 같은 것이 있습니다. 이 식은 아무리 x, y 변수를 변환하더라도 파라미터를 선형식으로 표현할 수 없습니다.

  선형 회귀 모델은 파라미터 계수에 대한 해석이 단순하지만 비선형 모델은 모델의 형태가 복잡할 경우 해석이 매우 어렵습니다. 그래서 보통 모델의 해석을 중시하는 통계 모델링에서는 비선형 회귀 모델을 잘 사용하지 않습니다.
  그런데 만약 회귀 모델의 목적이 해석이 아니라 예측에 있다면 비선형 모델은 대단히 유연하기 때문에 복잡한 패턴을 갖는 데이터에 대해서도 모델링이 가능합니다. 그래서 충분히 많은 데이터를 갖고 있어서 variance error를 충분히 줄일 수 있고 예측 자체가 목적인 경우라면 비선형 모델은 사용할만한 도구입니다. 기계 학습 분야에서는 실제 이런 비선형 모델을 대단히 많이 사용하고 있는데 가장 대표적인 것이 소위 딥 러닝이라고 부르는 뉴럴 네트워크입니다.

3. 결론
  정리하자면, 선형 회귀 모델은 파라미터가 선형식으로 표현되는 회귀 모델을 의미합니다. 그리고 이런 선형 회귀 모델은 파라미터를 추정하거나 모델을 해석하기가 비선형 모델에 비해 비교적 쉽기 때문에, 데이터를 적절히 변환하거나 도움이 되는 feature들을 추가하여 선형 모델을 만들 수 있다면 이렇게 하는 것이 적은 개수의 feature로 복잡한 비선형 모델을 만드는 것보다 여러 면에서 유리합니다.
  반면 선형 모델은 표현 가능한 모델의 가짓수(파라미터의 개수가 아니라 파라미터의 결합 형태)가 한정되어 있기 때문에 유연성이 떨어집니다. 따라서 복잡한 패턴을 갖고 있는 데이터에 대해서는 정확한 모델링이 불가능한 경우가 있습니다. 그래서 최근에는 모델의 해석보다는 정교한 예측이 중요한 분야의 경우 뉴럴 네트워크와 같은 비선형 모델이 널리 사용되고 있습니다.

실전 데이터 분석에서 염두해야할 사항 데이터분석

링크: http://www.unofficialgoogledatascience.com/2016/10/practical-advice-for-analysis-of-large.html

데이터 분석을 할 때 꼭 필요한 팁이 잘 정리되어 있어 데이터 분석에 관심있으신 분들은 꼭 한번 읽어보면 좋겠습니다. 




1 2 3 4 5 6 7 8 9 10 다음