본문 바로가기

spartacodingclub/개발보고서

가장 쉽게 배우는 머신러닝 2주차

https://spartacodingclub.kr/

*스파르타 클럽 강의 2주차를 듣고 난 개인적인 후기*

더보기
1주차 때부터 느낀 거지만 '쉽게 배우는 머신러닝'은 전공자들을 위한 강의인 것 같다.중간중간 리눅스 명령어 등 전공자들은 당연히 알고 있는 정보들에 있어서는 세부 설명 없이 강의가 이어진다.그래도 전공자 입장에서는 굉장히 좋은 강의들 중 하나라고 생각한다.이 강의는 이론을 공부하는 사람들에게도 좋겠지만, 그것보다도 당장 실전에 투입하는, 예를 들어 공모전을 해야 하는 학생들에게 더 유용한 편인 것 같다.

 

*강의 내용*

 

논리 회귀Logistic regression란?

머신러닝에서 입력값과 범주 사이의 관게를 구하는 것을 논리 회귀라 한다.

선형 회귀로 풀기 어려운 문제에서 사용된다.

예를 들어 특정 수준이 넘어서면 참으로 넘어가는 참과 거짓, 즉 이진 출력값을 가지는 이진 논리 회귀에서는 입력값은 어떤 것이든 받을 수 있으나 출력값은 항상 0에서 1사이 값이 된다.

실제로 많은 확률값들은 선형이 아닌 S 커브 형태를 따르는 경우가 많은데, 이것을 표현해내는 것이 로지스틱 함수Logistic function이다. 딥러닝에서는 시그모이드 함수Sigmoid function이라고 부른다.

>> 실질적인 계산은 선형 회귀와 똑같지만 출력에 시그모이드 함수를 붙여 0에서 1 사이의 값을 가지도록 한다.

 

시그모이드 함수Sigmoid function란?

입력값이 음수 방향으로 갈수록 출력은 0에 가까워지고, 입력값이 양수 방향으로 갈수록 출력은 1에 가까워진다.

정답이 1일 경우 예측한 라벨 1일 때 확률이 100이어야 하고, 반대로 정답이 0일 경우 예측한 라벨이 0일 때 확률이 0이어야 한다. 즉, 위의 그림에서 빨간색 그래프는 정답이 0인 경우를 보여준다.

만약 정답이 0인 경우에 우리가 학습 중인 입력값의 확률 분포가 파란색 그래프처럼 나왔다고 가정하면, crossentropy는 파란색 그래프를 빨간색 그래프처럼 만들어주기 위해 노력하는 함수이다.

선형 회귀를 했을 때 정답값을 나타내는 점과 우리가 세운 가설 직선의 거리를 최소화하려고 했던 거리 함수처럼.

>> keras에서 이진 논리 회귀의 경우 binary_crossentropy 함수를 사용한다.

 

다항 논리 회귀Multinomial logistic regression란?

논리 회귀 문제에서 클래스를 나누게 되면 이를 다중 논리 회귀라고 한다.

원핫 인코딩One-hot encoding은 다항 분류Multi-label classification 문제를 풀 때 출력값의 형태를 가장 예쁘게 표현할 수 있는 방법이다.

예를 들어 클래스를 0~4까지, 총 다섯 개로 분류한다고 치면 아래와 같은 표처럼 원핫 인코딩이 만들어진다.

Softmax 함수는 선형 모델에서 나온 결과를 모두 더하면 1이 되도록 만들어주는 함수이다. 이때 다 더해서 1이 되게 만드는 이유는 예측의 결과를 확률로 표현하기 위해서이다.

입력값에서 선형 형태로 바꾸고, 그 값을 softmax에 적용하면 위의 그림처럼 세 가지 숫자를 전부 더했을 때 1이 나오는 수로 만들어진다. 이때 crossentropy를 이용해 마지막에 있는 확률 분포의 차이를 구한다.

Keras에서 다항 논리 회귀의 경우 categorical_crossentropy 손실 함수를 사용한다.

 

다양한 머신러닝 모델

Support vector machine(SVM)은 그래프의 각 축에 특징을 부여해 분류하는 방식으로, 분류된 공간에 그은 빨간 벡터를 Support vector라고 부른다. 이때 margin이 넓으면 넓을수록 이 모델은 훌륭한 모델이라고 볼 수 있다.

k-Nearest neighbors(KNN)은 비슷한 득성을 가진 개체끼리 군집화하는 알고리즘이다. 예를 들어, 한 개체가 나타났을 때 일정 거리 안에 다른 개체들의 개수를 보고 자신의 위치, 특성을 결정하게 한다.

Decision tree, 의사 결정 나무는 우리가 자주하는 스무고개 같은 방식으로 예와 아니오를 반복해 추론하는 방식이다. 성능이 좋아 간단한 문제를 풀 때 자주 사용한다.

Random forset은 의사 결정 나무를 여러 개 합친 모델로 의사 결정 나무와는 다르게 랜덤 포레스트는 각각의 나무들이 결정을 하고 마지막에 투표Majority voting를 통해 최종 답을 결정하게 한다.

 

전처리Preprocessing란?

전처리는 넓은 범위의 데이터를 정제하는 작업을 의미한다. 예를 들어 필요없는 데이터를 지우는 것, null 값의 행을 삭제하는 것, 정규화Normalization, 표준화Standardization 등의 많은 작업을 포함하고 있다.

정규화Normalization란?

데이터를 0과 1사이의 범위를 가지도록 만든다. 가장 작은 값을 0으로 만들고, 가장 큰 값을 1로 만든다.

표준화Standardization란?

평균이 0이 되도록 하고, 표준편차가 1이 되도록 만들어 준다. 표준화를 시켜주면 학습 속도(최저점 수렴 속도)가 빠르고, Local minima(1주차에서 배웠던 경사 하강법 중 최저점이 아닌데 주변이 다 현재 위치보다 높아 최저점이라 오해하는 치명적인 오류)에 빠질 가능성이 적어진다.

위는 정규화의 예시로, 모든 값의 최저는 0으로, 최대는 1로 맞춘 결과를 보여준다.

표준화는 평균을 전부 동일하게 맞추는 것을 의미한다.

 

*실습*

캐글 데이터셋을 가지고 와 이진 논리 회귀 실습

(https://colab.research.google.com/drive/14Ya5ueEmwSo8zZszLwjeQ8j0ldEPNYhj?usp=sharing)

 

import os
os.environ['KAGGLE_USERNAME'] = 'gaebal' # username
os.environ['KAGGLE_KEY'] = 'c39115761fccb8b26bfa86a4af0e2703' # key

!kaggle datasets download -d kandij/diabetes-dataset

!unzip diabetes-dataset.zip

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import Adam, SGD
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt 
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

df = pd.read_csv('diabetes2.csv')

 

위의 코드는 1주차 실습과 매우 비슷하기 때문에 넘긴다.

 

x_data = df.drop(columns=['Outcome'], axis=1)
# y값으로 쓰여야 하는 것을 빼낸 후에 x_data를 만든다.
x_data = x_data.astype(np.float32)

y_data = df[['Outcome']]
# 빼낸 값을 y_data에 집어넣는다.
y_data = y_data.astype(np.float32)

scaler = StandardScaler()
x_data_scaled = scaler.fit_transform(x_data)
# scaler로 정의한 후 transform을 호출해 x데이터만 표준화한다.

x_train, x_val, y_train, y_val = train_test_split(x_data, y_data, test_size=0.2, random_state=2021)
#1주차와 마찬가지로 훈련 데이터와 검증 데이터를 이용한다.

print(x_train.shape, x_val.shape)
print(y_train.shape, y_val.shape)
# x와 y 값의 형태를 확인한다.

model = Sequential([
  Dense(1, activation='sigmoid')
])
# 1주차와는 다르게 논리 회귀이기 때문에 sigmoid 함수를 넣어준다.

model.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.01), metrics=['acc'])
# 이진 논리 회귀이기 때문에 binary_crossentropy를 이용한다.

model.fit(
    x_train,
    y_train,
    validation_data=(x_val, y_val), # 검증 데이터를 넣어주면 한 epoch이 끝날때마다 자동으로 검증
    epochs=20 # epochs 복수형으로 쓰기!
)

 

최종적으로 위의 코드를 실행하게 되면 출력값에 훈련 데이터를 이용한 값과 검증 데이터를 이용한 값이 나타나게 된다.