인공지능

[빅데이터 직무연구회] 1주차 모임 정리

Chipmunks 2018. 4. 14.
728x90

[빅데이터 직무연구회] 1주차 모임 정리

작성자 : 블로거

모임 요일 : 4월 12일 목요일 저녁 6시



학교 커뮤니티에서 빅데이터쪽으로 관련해 스터디 및 공모전 준비하는 직무연구회를 모집한다는 글을 보고 신청했다. 직무연구회란 직무 중심의 채용이 일반화 된 상황에서 학생의 희망진로 및 관심이 유사한 학생들이 모여 '직무'별 자치 학습조직(동아리, 취업스터디 등)을 운영하여 취엽역량을 제고하는 목적으로 학교측에서 정식 지원해주는 모임이다.


1차적으로 모집된 사람들끼리 간단하게 모여, 운영 방향을 어떻게 잡으면 좋을지 의논했다. 도서는 '파이썬 라이브러리를 활용한 머신러닝, 안드레아스 뮐러, 세라 가이도 지음, 박해선 옮김, 한빛미디어', 으로 정했다. 다음 1주차 모임까지 챕터 1장까지 하는 것으로 끝이 났다.



< 앞 표지 >


< 뒷 표지 >




1주차 모임에서 앞으로의 스터디 방향을 정했다. 모두 사전에 정한 진도까지 공부한다. 매 번 발표자 2명을 두어, 그 진도를 간략하게 브리핑한다. 이후 발표자는 물론 다른 동아리원끼리 책에 쓰여져있는 설명 이외에 다른 레퍼런스 자료를 참고하여 얻은 지식들을 공유하고, 이해가 되지 않거나 궁금한 점을 다같이 토의한다.


발표자는 동아리 구성원 상 통계학 전공자도 있고, 아닌 비전공자도 있다. 발표자를 선정할 때 통계학 전공자 중 1명과 비전공자 중 1명을 짝짓는다.


발표자 이외에 전 시간에 했던 내용을 리뷰하는 복습자를 사전에 정한다. 복습자는 모임이 끝날 때 까지 몰랐던 점이나, 이후 복습을 통해 깨달은 사실들을 추가로 공유할 수 있다.




챕터 1장은 소개 챕터이다. 1.1 장은 머신러닝이 무엇인지, 어떤 문제를 해결하는지 알려준다. 1.2장부터 1.6장까지는 아나콘다를 통해 기본적인 파이썬3 설치와 scikit-learn 라이브러리 설치를 설명한다. scikit-learn 의 디펜던시 라이브러리는 NumPy와 SciPy, matplotlib, pandas, mglearn 이 있다. 실습 환경으로 주피터 노트북 설치법을 알려준다.


1.7장은 scikit-learn의 예제 데이터셋인, 붗꽃(iris)의 꽃받침 길이와 폭, 꽃잎의 길이와 폭으로 품종이 어떤 것인지 머신러닝 모델을 돌려본다.


1.1 왜 머신러닝인가?

직접 규칙을 만드는 것은 두 가지 큰 단점이 있다. 첫 번째로, 작업이 조금만 변경되더라도 전체 시스템을 다시 개발해야할 수 있다. 두 번째로, 규칙을 설계하려면 그 분야 전문가들이 내리는 결정 방식에 대해 잘 알아야 한다.
얼굴 인식은 규칙을 직접 만드는데 실패한 대표적인 예다. 그러나 머신러닝을 사용하여 알고리즘에 많은 얼굴 이미지를 제공해주면 얼굴을 특정하는 요소가 어떤 것인지 찾아낼 수 있다.

1.1.1 머신러닝으로 풀 수 있는 문제

지도학습 : 이미 알려진 사례를 바탕으로 일반화된 모델을 만들어 의사 결정 프로세스를 자동화하는 것
알고리즘을 학습시켜 사람의 도움 없이 새로운 입력이 주어지면 적절한 출력을 만들 수 있다.

지도학습의 예는, 편지 봉투에 손으로 쓴 우편번호 숫자 판별과 의료 영상 이미지에 기반한 종양 판단, 의심되는 신용카드 거래 감지 등이 있다.

비지도학습 : 알고리즘에 입력은 주어지지만 출력은 제공되지 않는다. 이 알고리즘의 성공 사례는 많지만 비지도 학습을 이해하거나 평가하는 일은 쉽지 않다.

비지도학습의 예는, 블로그 글의 주제 구분, 고객들을 취향이 비슷한 그룹으로 묶기, 비정상적인 웹사이트 접근 탐지 등이 있다.

하나의 개체 : 샘플(sample), 데이터 포인트(data point)
샘플의 속성, 열 : 특성(feature)

어떤 머신러닝 알고리즘도 아무런 정보가 없는 데이터로는 그 어떤 것도 예측할 수 없다.

1.7 첫 번째 어플리케이션: 붓꽃의 품종 분류

붓꽃의 꽃잎(petal)과 꽃받침(sepal)의 폭과 길이를 센티미터 단위로 측정하였다. 전문 식물학자가 setosa, versicolor, virginica 종으로 분류한 붓꽃의 측정 데이터도 가지고 있다. 우리의 목표는 새 데이터가 들어오면, 그 데이터는 어떤 붓꽃의 품종인지 예측하는 머신러닝 모델을 만드는 것이다.

붓꽃의 품종을 정확하게 분류한 데이터를 가지고 있으므로 지도 학습이다.
몇 가지 선택사항(붓꽃의 품종) 중 하나를 선택하는 문제이므로 분류(Classification) 문제이다.
출력될 수 있는 값(붓꽃의 종류)들을 클래스(class)라고 한다.
데이터 포인트 하나(붓꽃 하나)에 대한 기대 출력은 꽃의 품종이고, 레이블(label)이라고 한다.

예시 소스는 다음과 같다.


from IPython.display import display
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import mglearn
In [2]:
from sklearn.datasets import load_iris
iris_dataset = load_iris()
In [3]:
print("iris_dataset의 키 : \n{}".format(iris_dataset.keys()))
iris_dataset의 키 : 
dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names'])
In [4]:
print(iris_dataset['DESCR'] + "\n...")
Iris Plants Database
====================

Notes
-----
Data Set Characteristics:
    :Number of Instances: 150 (50 in each of three classes)
    :Number of Attributes: 4 numeric, predictive attributes and the class
    :Attribute Information:
        - sepal length in cm
        - sepal width in cm
        - petal length in cm
        - petal width in cm
        - class:
                - Iris-Setosa
                - Iris-Versicolour
                - Iris-Virginica
    :Summary Statistics:

    ============== ==== ==== ======= ===== ====================
                    Min  Max   Mean    SD   Class Correlation
    ============== ==== ==== ======= ===== ====================
    sepal length:   4.3  7.9   5.84   0.83    0.7826
    sepal width:    2.0  4.4   3.05   0.43   -0.4194
    petal length:   1.0  6.9   3.76   1.76    0.9490  (high!)
    petal width:    0.1  2.5   1.20  0.76     0.9565  (high!)
    ============== ==== ==== ======= ===== ====================

    :Missing Attribute Values: None
    :Class Distribution: 33.3% for each of 3 classes.
    :Creator: R.A. Fisher
    :Donor: Michael Marshall (MARSHALL%PLU@io.arc.nasa.gov)
    :Date: July, 1988

This is a copy of UCI ML iris datasets.
http://archive.ics.uci.edu/ml/datasets/Iris

The famous Iris database, first used by Sir R.A Fisher

This is perhaps the best known database to be found in the
pattern recognition literature.  Fisher's paper is a classic in the field and
is referenced frequently to this day.  (See Duda & Hart, for example.)  The
data set contains 3 classes of 50 instances each, where each class refers to a
type of iris plant.  One class is linearly separable from the other 2; the
latter are NOT linearly separable from each other.

References
----------
   - Fisher,R.A. "The use of multiple measurements in taxonomic problems"
     Annual Eugenics, 7, Part II, 179-188 (1936); also in "Contributions to
     Mathematical Statistics" (John Wiley, NY, 1950).
   - Duda,R.O., & Hart,P.E. (1973) Pattern Classification and Scene Analysis.
     (Q327.D83) John Wiley & Sons.  ISBN 0-471-22361-1.  See page 218.
   - Dasarathy, B.V. (1980) "Nosing Around the Neighborhood: A New System
     Structure and Classification Rule for Recognition in Partially Exposed
     Environments".  IEEE Transactions on Pattern Analysis and Machine
     Intelligence, Vol. PAMI-2, No. 1, 67-71.
   - Gates, G.W. (1972) "The Reduced Nearest Neighbor Rule".  IEEE Transactions
     on Information Theory, May 1972, 431-433.
   - See also: 1988 MLC Proceedings, 54-64.  Cheeseman et al"s AUTOCLASS II
     conceptual clustering system finds 3 classes in the data.
   - Many, many more ...

...
In [5]:
print("타깃의 이름: {}".format(iris_dataset['target_names']))
타깃의 이름: ['setosa' 'versicolor' 'virginica']
In [6]:
print("특성의 이름: {}".format(iris_dataset['feature_names']))
특성의 이름: ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
In [7]:
print("data의 타입: {}".format(type(iris_dataset['data'])))
data의 타입: <class 'numpy.ndarray'>
In [8]:
print("data의 크기: {}".format(iris_dataset['data'].shape))
data의 크기: (150, 4)
In [9]:
print("data의 처음 다섯 행:\n{}".format(iris_dataset['data'][:5]))
data의 처음 다섯 행:
[[5.1 3.5 1.4 0.2]
 [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]]
In [10]:
print("target의 타입: {}".format(type(iris_dataset['target'])))
target의 타입: <class 'numpy.ndarray'>
In [11]:
print("target의 크기: {}".format(iris_dataset['target'].shape))
target의 크기: (150,)
In [12]:
print("타깃:\n{}".format(iris_dataset['target']))
타깃:
[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]
In [13]:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(iris_dataset['data'], iris_dataset['target'], random_state=0)
In [14]:
print("X_trian의 크기: {}".format(X_train.shape))
print("y_train의 크기: {}".format(y_train.shape))
X_trian의 크기: (112, 4)
y_train의 크기: (112,)
In [15]:
print("X_test 크기: {}".format(X_test.shape))
print("Y_test 크기: {}".format(y_test.shape))
X_test 크기: (38, 4)
Y_test 크기: (38,)
In [16]:
iris_dataframe = pd.DataFrame(X_train, columns=iris_dataset.feature_names)
pd.plotting.scatter_matrix(iris_dataframe, c=y_train, figsize=(15, 15), marker='o', hist_kwds={'bins': 20}, s=60, alpha=.8, cmap=mglearn.cm3)
Out[16]:
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x10c407748>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x10c451be0>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x10c484208>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x10c4a9898>],
       [<matplotlib.axes._subplots.AxesSubplot object at 0x10c4d3f28>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x10c4d3f60>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x10c52cbe0>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x10c55d240>],
       [<matplotlib.axes._subplots.AxesSubplot object at 0x10c583860>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x10c5abef0>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x10c5dc588>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x10c602ba8>],
       [<matplotlib.axes._subplots.AxesSubplot object at 0x10c634240>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x10c65c8d0>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x10c685f28>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x10c6b45f8>]],
      dtype=object)
In [17]:
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=1)
In [18]:
knn.fit(X_train, y_train)
Out[18]:
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
           metric_params=None, n_jobs=1, n_neighbors=1, p=2,
           weights='uniform')
In [19]:
X_new = np.array([[1, 1.9, 2, 5]])
print("X_new.shape: {}".format(X_new.shape))
X_new.shape: (1, 4)
In [20]:
prediction = knn.predict(X_new)
print("예측: {}".format(prediction))
print("예측한 타깃의 이름: {}".format(iris_dataset['target_names'][prediction]))
예측: [2]
예측한 타깃의 이름: ['virginica']
In [21]:
y_pred = knn.predict(X_test)
print("테스트 세트에 대한 예측값:\n {}".format(y_pred))
테스트 세트에 대한 예측값:
 [2 1 0 2 0 2 0 1 1 1 2 1 1 1 1 0 1 1 0 0 2 1 0 0 2 0 0 1 1 0 2 1 0 2 2 1 0
 2]
In [22]:
print("테스트 세트의 정확도: {:.5f}".format(np.mean(y_pred == y_test)))
테스트 세트의 정확도: 0.97368


iris_dataset 자료 안에는 data, target, target_names, DESCR, feature_names 등의 키로 분류되어 데이터를 저장하고 있다. data는 꽃받침과 꽃잎의 길이와 폭 숫자 데이터가 들어가있고, target은 품종 '숫자' 데이터가 들어가 있다. target_names 에는 각 숫자가 어떤 품종을 뜻하는지 문자열로 들어가 있다. DESCR은 데이터에 대한 간단한 통계치들을 설명한다. feature_names는 각 속성이 어떤 것을 뜻하는지 문자열로 들어가있다.


성과를 측정하기 위해 주어진 데이터셋에서 훈련 데이터와 테스트 데이터로 나눠야 한다.

레이블된 데이터(150개의 붓꽃 데이터)를 두 그룹으로 나눈다. 그 중 하나는 머신러닝 모델을 만들 때 사용하며, 훈련 데이터 혹은 훈련 세트(training set)라고 한다. 나머지는 모델이 얼마나 잘 작동하는지 측정하는 데 사용하며, 이를 테스트 데이터, 테스트 세트(test set) 혹은 홀드아웃 세트(hold-out set)라고 부른다.


scikit-learn 에서 데이터셋을 섞어 나눠주는 train_test_split 함수가 있다. 기본적으로 75%의 훈련 세트와 나머지 25% 테스트 세트를 나눠준다. 일반적으로 그렇게 하는 것이 좋은 선택이다. 바꾸기 위해서는 test_size 매개변수로 .5  또는 .65 같이 비율을 설정해줘 바꿔줄 수 있다.


가장 먼저 할 일은 데이터를 살펴보는 것이다. 그 중 산점도(scatter plot)를 사용할 것이다. 산점도는 데이터에서 한 특성을 x 축에 놓고 다른 하나는 y축에 놓아 각 데이터 포인트를 하나의 점으로 나타내는 그래프이다. 3개 이상의 특성을 표현하기 위해 산점도 행렬(scatter matrix)을 사용한다. 4개의 특성을 가진 붓꽃의 경우처럼 특성의 수가 적다면 괜찮은 방법이다. 산점도 행렬은 한 그래프에 모든 특성의 관계가 나타나는 것은 아니기 때문에 각각의 나누어진 산점도 그래프에는 드러나지 않는 중요한 성질이 있을 수 있다.


pd.plotting.scatter_matrix(iris_dataframe, c=y_train, figsize=(15, 15), marker='o', hist_kwds={'bins': 20}, s=60, alpha=.8, cmap=mglearn.cm3)

첫번 째 인수는 산점도 행렬을 만들, 팬더스를 통해 만든 데이터프레임이다. c는 색으로 구분할 데이터이다. figsize는 시각화한 그림의 크기이다. marker는 출력되는 특성이 어떤 글자로 나오게할 지 설정해준다. hist_kwds 매개변수는 딕셔너리로 넘겨준다. bins 는 히스토그램의 구간 수를 뜻한다. s 매개변수는 출력되는 특성의 크기, alpha 매개변수는 출력되는 특성의 투명도, cmap은 어떤 컬러맵을 사용할지 정한다.


머신러닝 모델로, k-최근접 이웃(k-Nearest Neighbors, k-NN) 분류기를 사용했다. 단순히 훈련 데이터를 저장하여 만들어진다. 새로운 데이터 포인트에 대한 예측이 필요하면 알고리즘은 새 데이터 포인트에서 가장 가까운 훈련 데이터 포인트를 찾는다. 그런 다음 찾은 훈련 데이터의 레이블을 새 데이터 포인트의 레이블로 지정한다.


k-최근접 이웃 알고리즘에서의 k는 가장 가까운 이웃 '하나'가 아니라 훈련 데이터에서 새로운 데이터 포인트에 가장 가까운 'k개' 이웃을 찾는다는 뜻이다. 그 다음 이웃들의 클래스 중 '빈도'가 가장 높은 클래스를 예측값으로 사용한다. 현재 예시에서는 1로 설정되어 있다.


훈련 데이터셋으로부터 모델을 만들기 위해 knn 객체의 fit 메서드를 사용한다.

예측을 할 떄는 knn 객체의 predict 메서드를 사용한다.

모델을 평가할 때는 테스트 세트를 predict 하여 나온 결과를, knn 객체의 score 메서드로 측정할 수 있다.




다음 진도는 Chapter 2 지도학습에서 2.1 분류와 회귀, 2.2 일반화, 과대적합, 과소적합, 3.3 지도 학습 알고리즘에서 k-최근접 이웃, 선형모델, 2.3.4 나이브 베이즈 분류기(~101P) 까지이다.


다음 발표자 : 블로거, 강OO

복습자 : 정OO


다음 모임은 4월 29일 일요일 저녁 6시이다.

댓글