텐서플로우, 회귀분석, 머신러닝... 그게 대체 뭔데? - 머신러닝에 대해

Category: Data Sceince

<텐서플로우, 머신러닝, 회귀분석...그게 대체 뭔데?>


Tensorflow(텐서플로우) 는 구글이 개발한 머신러닝 / 딥러닝 오픈소스 라이브러리이다. 사실 과거에 scikit learn 라이브러리를 이용해 몇가지 지도/비지도학습 (Supervised learning / Unsupervised learning) 알고리즘을 통해 (k-mean, Naive Bayse 등) 간단한 머신러닝을 공부해보았는데 텐서플로우에 대한 이야기는 듣기만하고 한번도 접해보지 못했다. 그러던 중 우연한 기회에 텐서플로우를 살짝 접해보게 되었고 이참에 데이터분석과 함께 머신러닝 관련 내용도 공부하며 흥미로운 내용이 있으면 포스팅해볼까 한다. 

(필자도 배우는 학생 입장이고, 전문가는 아니다) 전공자/전문가가 아닌 이들에게 대체 머신러닝이 무엇이며, 텐서플로우는 대체 뭔지 아주 간단히 설명하고자 한다. 먼저  빅 데이터 기반 머신러닝의 대표적인 분석방식인 지도학습과 비지도학습에 대해 간단히 이야기하도록 하겠다. 그리고 다음 포스트에서는 이번에 텐서플로우를 처음 접하면서 공부하게된 텐서플로우 선형회귀분석 / 경사 하강법 (Gradient Descent)을 실행하는 코드를 소개하고, 마지막으로 이를 응용해서 실제 NBA 선수들의 스탯(Stat) 데이터를 가지고 몇몇 변수간 회귀분석을 진행해보겠다. 

만약 이 분야에 전문가/전공자가 아니고 관심이 많지 않아 도통 무슨 소리인지 모르겠다면 괜찮다. 나도 전문가가 아니기 때문에 세세한 공식과 원리까지 꿰뚫고있지는 못하기에, 이 분야에 조금 많이 관심있는 일반인들이 '아 이런거구나'하고 이해할 정도로 설명하도록 하겠다.
---


머신러닝(기계학습) 은 대체 뭘까?

인공지능, 빅데이터에 대해 이야기할 때 가장 많이 언급되는 것이 바로 머신러닝이다. 머신러닝이 도대체 뭘까? 말 그대로 Machine Learning - 기계가 배운다는 말이다. 빅 데이터를 통한 알고리즘으로 기계가 학습할 수 있게 만든다는것이 바로 머신러닝의 기본적인 아이디어이다.

과거의 컴퓨터 소프트웨어들은 그저 수행되도록 프로그램된 동작 외에는 수행할 수 없었다. 그래서 초창기의 프로그램들은 단순한 작업들을 인간을 대신해서 빠르게 수행하는 도구로 자리잡았다. 컴퓨터는 '슈퍼 계산기'라는 말을 들어봤을 것이다. 컴퓨터가 애시당초 Computer(Compute: 계산하다)라고 이름지어진 이유도 방대한 연산을 처리할 수 있는 기계였기 때문이다. 프로그램이 발전하면서 컴퓨터는 점점 더 많은 연산을 쉽게 처리할 수 있게 되었고, '정해진 동작'의 범위를 다양화하기 위해 프로그램들은 여러가지 변수와 예외에 대한 동작을 할 수 있게 되었지만, 예외와 변수에 대한 동작들 역시 일일이 프로그래밍해야 했다. 예를들어, 한국의 수도가 어딘지 묻는 질문이 나오고, 오답을 입력하면 '틀렸습니다'라는 문장이 출력되는 프로그램이 있다고 가정해보자. 내가 '미국'이라고 입력하면 컴퓨터는 '틀렸습니다'라고 할 것이다. 그렇지만 이는 프로그램이 한국의 수도가 어디인지 알기 때문이 아니라, 프로그래머가 '서울'이외의 다른 답을 입력하면 '틀렸습니다'라고 말하라고 프로그래밍했기 때문에 가능한 것이다.

그렇지만 기계학습을 통한 인공지능 프로그램은 조금 다르다. 기계학습의 기본적인 아이디어는 기계가 '학습'할 수 있는 알고리즘을 짜자는 것이다. 그렇다면 기계는 어떤 식으로'학습'하는 것일까? 결론부터 말하면 빅테이터를 통해 패턴을 학습하는 방식이다.


예를들어 머신러닝을 통해 기계가 사과와 오렌지를 구별하도록 학습시킨다고 생각해보자. 우선, 사과와 귤의 특성을 정제된 데이터의 형식으로 만든다. 예를 들자면 아래와 같은 방식으로 말이다. 

오렌지1 {색깔: 주황, 지름: 8cm, 표면: 울퉁불퉁함}, 
오렌지2 {색깔: 주황, 지름: 7cm, 표면: 울퉁불퉁함}
...

사과1 {색깔: 빨강, 지름: 5cm, 표면: 매끈함}
사과2...

이런식으로, '빅 데이터'라고 부를 수 있을만큼 많은 사과와 오렌지의 데이터를 수집하여 기계가 분석하도록 한다. 이 빅 데이터의 분석을 찾아 패턴을 발견해내고 기계는 사과와 오렌지를 구별할 수 있도록 '학습'된다. 빅 데이터를 통해 기계는 사과와 오렌지를 구별하는 알고리즘을 만들어내고, 새로운 과일의 데이터가 주어졌을 때 그 과일이 사과인지 오렌지인지 구분할 수 있는 것이다. 결국 인공지능, 머신러닝의 알고리즘은 모두 빅 데이터에 근간을 두고 있다. 이전의 글 - AI의 인지능력과 편향되지 않은 편향성 - 에서도 언급했듯이 기계가 실제로 인간과 같이 생각을 하거나 지능을 가지는 것이 아니다. 그저 수많은 빅 데이터의 분석을 통해 인간과 같은 수준으로 (혹은 인간 이상의 수준으로)패턴을 찾아내는 것이다. 


지도학습(Supervised learning)과 비지도학습(Unsupervised learning)

머신러닝에 대해 조금 더 자세히 알아보자. 머신러닝 알고리즘에는 크게 두 가지 대표적인 종류가 있다. 그것은 바로 지도학습(Supervised learning)비지도학습(Unsupervised learning)이다. (이 외에 강화학습 - Reinforcement 도 있지만 이 글에서는 다루지 않도록 하겠다). 지도학습은 기계가 알고리즘을 통해 학습하고자 하는 대상의 레이블 (Label)이 정해져있으며, 데이터와 레이블을 매칭시키는 방식으로 학습하는 방식이다. 반면 비지도학습은 대상의 레이블 (Label)이 정해져있지 않으며 단순히 퍼져있는 데이터를 분석해 패턴을 발견하거나 유사한 데이터끼리 그룹을 짓는 방식이다. 

아마 머신러닝을 접한지 얼마 되지 않은 이들인 이게 무슨 소리인가 싶을 것이다. 알기 쉽게 설명하기 위해 위에서 언급했던 사과와 오렌지의 예시를 다시 들어보겠다. 여기서 우리는 우리가 구별하고자 하는 것이 무엇인지 알고있다 - 오렌지와 사과를 구별하고자 하는 것이다. 다시말해, 우리가 머신러닝을 통해 구별하고자 하는 것의 답에는 범위가 '오렌지 아니면 사과'로 정해져있다. 따라서 '오렌지'와 '사과' 가 '레이블 (Label)이 되며 이는 지도학습에 해당한다. 위에서는 간단한 설명을 위해 '울퉁불퉁함', '매끈함'과 같은 수식어를 사용하여 데이터를 간단히 표현했지만, 실제 머신러닝을 이용해 사과와 오렌지를 구분하기 위해서는 사과와 오렌지의 특징 (feature)를 더 세세히 '데이터화'해야 한다. 예를들어, '매끈하다', '울퉁불퉁하다' 와 같은 추상적인 표현은 '매끈함의 정도'라는 항목을 만들어 수치화하던지, 그게 불가능하다면 '매끈함의 여부' 라는 항목으로 대체해 yes = 1, no = 0 으로 표현함으로써 코드화해야 한다. 그러면 오렌지와 사과를 구별하도록 기계를 '학습'시키기 위해, 우리는 다음과 같은 형태의 데이터셋이 필요하다. 

과일 1 {색깔: 주황색, 지름: 5, 무게: 50, 매끈함의 정도: 10} - 레이블: '오렌지'
과일 2{색깔: 주황색, 지름: 4, 무게: 45, 매끈함의 정도: 8} - 레이블: '오렌지'
과일 3 {색깔: 주황색, 지름: 6, 무게: 51, 매끈함의 정도: 11} - 레이블: '오렌지'
...
과일 99 {색깔: 빨간색, 지름: 9, 무게: 30, 매끈함의 정도: 50} - 레이블: '사과'
과일 100{색깔: 빨간색, 지름: 11, 무게: 33, 매끈함의 정도: 48} - 레이블: '사과'

이 100개의 데이터셋은 어느것이 '오렌지'이고, 어느것이 '사과'인지 답이 정해져있는 데이터셋이며, 이 데이터에 포함된 사과와 오렌지의 특징(feature)값들을 특정 알고리즘을 통해 학습하여 사과와 오렌지를 구분할 수 있는 모델을 만들어낸다. 이 100개의 데이터를 포함한 데이터셋을 'Training Data'라고 하며, Training Data 의 크기가 너무 작거나 편중되어 있다면 사과와 오렌지를 충분히 잘 구별하도록 정확히 학습하지 못할 수 있다. 지도학습의 경우 이렇게 Training data를 통해 사과와 오렌지를 구별하는 규칙을 학습하고, Training dataset 외의 과일을 가져왔을 때 이것이 사과인지 오렌지인지 구별하게 된다. 



이와 다르게 비지도학습은 Label 없이 데이터만으로 학습 알고리즘을 만들어낸다. 즉, '이 과일이 사과인가 오렌지인가?' 하는 문제에 대답하기보다는, 수많은 과일들이 놓여있을 때 이들의 특징을 분석하여 같은 종류의 과일들끼리 묶어내는 알고리즘인 것이다. 




지도학습은 사과와 오렌지 문제처럼 레이블이 정해진 데이터를 구별하는 기준점(Classifier)을 찾기 위한  'Classification' 문제나, 주어진 데이터의 변수간 관계를 나타내는 함수를 찾는 '선형 회귀' (Linier Regression) 문제 등에 사용된다. 비지도학습은 여러 데이터를 종류별로 묶어내는 Clustering에 주로 사용된다. 


한번 해보자 - iris Dataset

*본 문단은 코딩에 관한 내용을 포함하고있으니 코딩에 관심이 없다면 넘기셔도 됩니다

이제 기계학습, 지도학습과 비지도학습의 원리를 대강 알았으니 한번 직접 시연해보자. 그렇게 어려울 것 없으며 간단한 파이썬 코드와, 머신러닝을 학습하도록 만들어진 파이썬 라이브러리를 활용해서 시연해 볼 수 있다. 파이썬 코딩을 처음 배울 때 'Hello World'를 입력하는 것 부터 시작하는 것 처럼, 머신러닝을 배울 때 가장 먼저 사용해보는 학습용 데이터셋인 iris dataset을 사용하도록 하겠다. 먼저 데이터를 로드하고 출력해보자

import pandas as pd
import numpy as np
from sklearn import datasets
iris = datasets.load_iris()
print (iris.data)
print (iris.target)
iris_X = iris.data
iris_y = iris.target


(iris.data 를 통해서 데이터셋만 따로, iris.target을 통해서 target(label)만 따로 변수에 저장할 수 있다. 데이터는 iris_X 변수에, 레이블(target)은 iris_y변수에 따로 저장해보자. )

먼저 파이썬의 sklearn패키지에서 iris dataset을 호출한다. 데이터는 다음과 같이 구성되어있다:
---

[4.9, 3. , 1.4, 0.2],
[4.7, 3.2, 1.3, 0.2],
[4.6, 3.1, 1.5, 0.2],
[5. , 3.6, 1.4, 0.2],
[5.4, 3.9, 1.7, 0.4],
[4.6, 3.4, 1.4, 0.3],
[5. , 3.4, 1.5, 0.2]
....

'feature_names': ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)','petal width (cm)']

'target': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]),

'target_names': array(['setosa', 'versicolor', 'virginica'], dtype='<U10')}

---

자 먼저 이 데이터셋을 한번 풀어헤쳐보자. 이 데이터셋은 iris(붓꽃) 150개의 데이터셋이다. 각각 꽃 하나하나마다 4가지 feature (특성) - Sepal length(꽃받침 길이), Sepal width(꽃받침 너비), Petal length(꽃잎 길이), Petal width(꽃잎 너비)의 값을 순서대로 리스트([]) 안에 기록하여 데이터셋으로 만들었다. Target은 앞에서 설명한 Label을 말한다. 즉, 붓꽃의 세 가지 종류 - 'setosa', 'versicolor', 'virginica' - 를 빅데이터 처리를 위해 0, 1, 2로 코드화시킨 것이다. 

자, 이제 iris의 데이터와 target을 가지고 기계학습을 진행해 보겠다. target (꽃의 종류)별 4가지 특성 값을 분석하여 세 꽃을 구분짓는 Classifier를 만드는 Classifying 알고리즘을 사용하도록 하겠다. 그런데 그 전에 150개의 데이터로 이루어진 데이터셋을 Training Data와 Test Data로 나누는 작업이 필요하다. 이는 Training Data를 통해 학습시킨 Classifyier 모델이 효과적으로 꽃의 종류를 구별해주는지 test data를 이용해 실험해보기 위해서이다. 

iris_X_train = iris_X[:-10]
iris_y_train = iris_y[:-10]
iris_X_test = iris_X[-10:]
iris_y_test = iris_y[-10:]

이제 우리는 Training을 위한 데이터와 target, Test를 위한 데이터와 Target을 모두 가지고있다. 이제 특정한 머신러닝 알고리즘에 training dataset을 넣어 훈련시키고, test data를 통해 이 모델이 얼마나 정확한지 확인하는 작업을 수행하겠다. 


from sklearn.neighbors import KNeighborsClassifier #CNN이나는 Classifying 알고리즘을 사용
knn = KNeighborsClassifier() #Classifyer를 불러왔다
knn.fit(iris_X_train, iris_y_train) #Classifying 알고리즘에 Training data를 집어넣어 훈현시킨다
knn.predict(iris_X_test) #이제 훈련된 모델에 Test data를 집어넣어 모델이 예상한 결과를 출력한다
print(iris_y_test)

###이제 실제 test data의 label과 추측한 label을 비교해 모델의 정확도를 측정해본다
n = 0
for i in range(0, len(knn.predict(iris_X_test))):
    if knn.predict(iris_X_test)[i] == iris_y_test[i]:
        n+=1
accuracy = (n/len(iris_y_test)) * 100
print (accuracy)


여기서는 KNN (K nearest neighbor 라는 classifying 알고리즘을 사용했다. 파이썬의 sklearn 패키지에 포함되어있기 때문에 코드를 따라하기만 한다면 KNN알고리즘의 원리를 모르더라도 누구나 사용할 수 있다. 알고리즘의 자세한 원리는 추후 포스트에서 설명하도록 하겠다. )

코드를 실행하니 100프로의 정확도가 나왔다. knn.predict(iris_X_test), 즉 knn 알고리즘이 학습을 통해 예측한 test data의 label은 array([2, 2, 2, 2, 2, 2, 2, 2, 2, 2]) 였으며 실제 test data의 label 역시  array([2, 2, 2, 2, 2, 2, 2, 2, 2, 2])로 모두 2였던 것이다. 위와 같이 iris data를 classify 하고 그래프로 표현하면 다음과 같은 그림이 나온다.

sklearn 패키지의 홈페이지 에 들어가면 위의 그래프를 그리기 위한 코드식 뿐 아니라 sklearn 패키지의 다양한 사용법을 배울 수 있다. 


이번엔 iris dataset을 이용해 clustering을 해보자.

전체 과정의 코드를 먼저 첨부하겠다. 이번엔 target (레이블)없이 데이터만을 KMeans 라는 clustering 알고리즘을 이용하여 분석하고, 유사한 종류끼리 묶었다.

import pandas as pd
import numpy as np
from sklearn import cluster
from sklearn.cluster import KMeans
from sklearn import datasets

iris = datasets.load_iris()
iris_X = iris.data

kmodel = KMeans(n_clusters = 3)
kmodel.fit(iris_X)
clusterlabel = kmodel.labels_
print (clusterlabel)

array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 0, 2, 0, 2, 0, 2, 2, 0, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 0], dtype=int32)

이렇게 사이사이 몇 개의 데이터를 제외하고는 전체적으로 일관되게 유사한 종류끼리 묶었다(cluster)는 것을 확인할 수 있다.

---

자세한 알고리즘의 원리와 코드의 내용은 이해하지 못하더라도, 이쯤되면 왜 머신러닝에 빅 데이터가 중요한지, 적어도 기계가 수많은 데이터의 특징값(feature value)를 분석해 패턴을 찾아냄으로써 학습한다는 사실을 이해했을 것이다. 여기서 가장 핵심적인 요소중 하나는 그 특징값들을 분석하는 알고리즘이다. 위의 예시에서 사용한 KNN, KMeans와 같은 다양한 지도/비지도학습 알고리즘이 존재한다. 다음 포스트에서는 지도학습 알고리즘 중 하나인 회귀분석 (Linear regression)을 텐서플로우를 이용해 간단히 알아보고자 한다. 또, 이번 포스트에서 사용했던 KMeans와 KNN에 대해서도 기회가 닿는다면 알아보도록 하자. 



댓글

이 블로그의 인기 게시물

[Python mini projects] Python을 활용한 텍스트 속 유의미한 통계 산출하기 -1

(2부) 플랫폼 비즈니스,그리고 카카오의 수익모델에 대한 idea

Kaggle competition 간단후기