머신러닝 무작정 뛰어들기

첫 시작을 무엇으로 할까 하다가, 이렇게 시작해보기로 했다.

“머신러닝 무작정 뛰어들기.”

그냥 무작정 단순한 머신 러닝 코드를 놓고, 이걸 분석해보는거다.

하지만 그 전에, 머신 러닝이 무엇인지에 대해서는 알아야 하지 않을까?

대상

  • 전혀 머신 러닝을 모름
  • 파이썬은 조금 앎
  • 수학 잘 모름

머신러닝이란?

코드를 분석하고 뭐고 자시고, 일단 머신러닝이 무엇인지에 대해 알아야 하지 않을까.

초등학교 때부터 이런 문제 많이 본 적 있을 것이다.

X Y
2 4
3 6
4 8
5 10
6 ???

이 문제를 풀면서, 풀이 과정을 상세히 적어야 한다고 생각해보자. 아마도 이런 풀이가 나오지 않을까?

‘먼저, 표를 잘 관찰한다. 4는 2의 두배이고, 6은 3의 두배, …, 그렇기 때문에 Y는 X의 두 배임을 알 수 있다. 따라서 X가 6일 때 Y는 12이다.’

수학적으로는 이런 식으로 표현할 수 있을 것이다.

‘함수 f가 X와 Y 사이의 관계라고 하면, f(2) = 4 = 2 * 2, f(3) = 6 = 2 * 3, … f(X) = Y = 2 * X이다. 따라서 f(6) = 12이다.’

f(X)가 2 * X라는 것을 알고 있다면, X 값이 무엇이든 Y값을 쉽게 구할 수 있다. 예컨데, 이런 코드를 만들어서…

def f(x):
    return 2 * x

X = int(input())
print(f"Y = {f(X)}")

하지만 f(X)가 2 * X라는 것을 모른다면 어떻게 할까?

def f(x):
    # ?????

X = int(input(x))
print(f"Y = {f(X)}")

…뭐, 어떻게든지 알아내야 하지 않을까?

즉, 문제 상황은 이렇다. “우리에겐 데이터는 있지만, 데이터 사이의 규칙은 모른다.”

물론 수학자를 갈아 넣어서 해결한다는 해결 방법도 있지만, 굳이 설명하지 않아도 될만한 각종 문제점이 생긴다.

게다가 수학자들이 해결하지 못할 만큼 어려운 문제도 꽤 많은데…

단적으로, 이런 예시를 생각해보자.

염소 사진을 하나 보고, 이 염소가 위 쪽을 향하고 있는지, 아래 쪽을 향하고 있는지를 알아내고 싶다고 하자.

위 쪽을 향하고 있는 염소 사진들과 아래 쪽을 향하고 있는 염소 사진들은 주어졌다.

수학자들이 열심히 노력하면 어느 쪽을 향한 사진인지 알 수 있을까?

def upgoat(image):
    # ???????

goat_image = #image here
print(f"Upgoat? = {upgoat(goat_image)})

…완전히 불가능할 것 같아 보이지는 않지만, 일단 불가능하다고 해도 될 정도로 어려운 문제라는 것은 확실하다.

더 어려운 문제를 만들어내라면 못할 것도 없겠지만, 이 정도로 충분하지 않을까?

결국 우리는, 어떻게든 데이터들을 가지고 규칙을 찾아내는 방법이 필요하다.

컴퓨터가 알아서 규칙을 ‘뿅’ 하고 만들어내는, 그런 방법이 필요하다.

사실 이런 필요성은 엄청 예전부터 있었다.

옛날 이야기

네이버 지식백과, ‘최소제곱법’ 글을 참조했다.

1780년대면 정말 옛날이다. 프리드리히 가우스 같은 교과서에서나 보일 것 같은 수학자들이 활동했던 시기니까.

그 때 천문학자들은 세레스라는 천체를 쫓고 있었다.

분명 몇 번인가 관찰된 기록은 있었다. 하지만 어느 순간 앗 하고 보니 어디에 갔는지 찾을 수가 없던 것이다.

즉 이런 상황이다. 분명 어떠한 ‘규칙’을 따라서 세레스는 움직이고 있었다. 몇 번 관찰된 ‘데이터’도 있다. 하지만 천문학자들은 이 ‘규칙’을 모르는 것이다.

데이터를 가지고 규칙을 찾아내는 방법이 필요하다.

( * 여담으로, 이 때 가우스가 사용한 방법이 최소제곱법이다.)

다시 돌아와서.

즉 머신 러닝은 데이터를 가지고 규칙을 찾아내는 방법이다.

머신 러닝에 대한 모든 연구는, 데이터를 가지고 규칙을 찾아내는 최고의 방법을 알아내는 것이다.

어떻게 하면 더 빨리, 더 정확하게 규칙을 찾아낼 수 있을까? 하는 연구이다.

그러면 최소제곱법인지 뭔지를 쓰면 되잖아?

…그게.. 그렇지도 않다.

솔직히 고백을 하나 하자면, 하나 빼먹은 부분이 있다.

‘규칙’ 부분 말인데… 이게 조금… 까다롭다.

다른 예를 하나 보자.

X Y
1 1
2 4

‘아! Y = X^2이구나!’ (^2는 제곱이다.)

라고 생각할 수도 있겠지만, 조금 더 보자.

X Y
1 1
2 4
3 7
4 10

짜잔! Y = 3 * X - 2였습니다!

왜 그 유명한 짤이 있지 않는가.

doge math meme

(여담이지만, 짤 생성기도 있다(…))

즉, 사실 규칙을 구성하는 것은 두 부분이라는 거다.

  • ‘규칙이 어떻게 생겼는지’, 그러니까 왠 이상한 4차방정식인지 아니면 예쁘게 생긴 직선 모양인지
  • ‘규칙을 이루는 수는 무엇인지’, 그러니까 작고 예쁜 정수인지 아니면 217331같은 괴상한 수인지

이를 각각 ‘모델’과 ‘매개 변수’(파라미터)라고 부른다.

최소제곱법은 모델이 주어졌을 때, 매개변수를 구하는 방법이다. 반면, 우리는 모델까지 구하기를 원한다.

‘매개변수만 구할 수 있으면 되는거 아닌가요’ 라고 할 수도 있겠다. 모델은 대충 데이터 분포를 보고 정할 수도 있으니까.

라고 생각한다면 염소 사진에는 도대체 어떤 모델을 써야 하는지를 다시 한번 고민해보자.

모델?

고백하겠다. 사실 거짓말을 했다.

매개변수만 구할 수 있으면 된다.

모델 역시 대충 데이터를 보고 정하면 된다.

하지만 대충 모델을 정하는 것 만으로는 염소 사진같은 어려운 문제는 풀 수 없다는 것 역시 사실이다.

그렇다면 염소 사진 문제는 풀 수 없는 모양이다. 이런.

문제는 ‘어떤 모델을 정하느냐’이다.

그 어떤 함수라도, 염소가 위를 향하는지 아래를 향하는지를 결정하는 정신 나간 함수라도 어떻게든지 묘사할 수 있는 모델은 없을까?

그런 모델이 있다면 염소 사진 문제도 풀 수 있을 것이다.

사실 있다.

인공신경망이니 서포트 벡터 머신이니 뭐니… 하는 그런 것들이 바로 그런 ‘어떤 함수라도 묘사할 수 있는 모델’이다.

(한번 쯤은 알파고 때문에라도 인공신경망 정도는 들어보지 않았을까?)

오케이, 모델은 정해졌다.

그러면 최소제곱법 (2트)

안된다. 이번에도.

매개 변수가 너무 많다.

최소제곱법은 이런 문제에 적용하기엔 너무 느리다.

‘느리면 컴퓨터 쓰면 되지 않나요’ 하기는 하는데, 컴퓨터가 문제를 넣으면 바로 답이 튀어나오는 만능 기계는 아니다.

컴퓨터가 느리다는 말은 렉이 걸릴 때 체감하게 된다.

‘느려도 어쨌든 가능은 하다는 거죠’라고 하면 할 말은 없겠지만… 뭐, 컴퓨터 앞에서 수천년동안 기다리고 있을 자신이 있다면.

조금 더 수학적인 표현을 원하는 사람을 위해, 이 글을 읽어보면 최소제곱법의 시간복잡도는 O(C^2N)이다.

C가 파라미터의 갯수, N은 데이터의 갯수인데, 파라미터가 10배가 되면 계산 시간이 100배 늘어난다는 뜻이다.

파라미터 갯수가 수천만개까지도 늘어날 수 있다면? 끔찍하다.

그래서 다른 더 좋은 방법을 사용하고는 한다.

뭐, 다시 말하지만 수천년동안 죽치고 앉아 있을 자신이 있다면 그냥 최소제곱법같은 다른 방법을 써도 되기야 한다. 아무도 그게 머신러닝이 아니라고는 하지 않는다.

정리

  • 머신 러닝은 데이터를 가지고 규칙을 만들어낸다.
  • 규칙은 모델과 파라미터로 이루어진다.
  • 선형계획법 같은 알고리즘은 파라미터를 알아낸다.
  • 하지만 선형계획법은 너무 느리다.