본문 바로가기
프로그래밍/ML, DL 제대로 공부하기

ML, DL 제대로 공부하기 - 1 (머신러닝 개요)

by _OlZl 2025. 1. 8.

 

 

상당히 오랜만에 티스토리에 글을 써보네요. 오늘부터는 대학교 공부에 대비해서 머신러닝 및 딥러닝에 대해 공부해보려 합니다. 이거 외에도 선형대수학 공부나 학인시 대비 공부도 할 생각인데 정리도 할 겸 티스토리에 다 정리하면서 남겨보도록 하겠습니다.

 

책은 '핸즈 온 머신러닝(3판)', '모두의 딥러닝', '밑바닥부터 시작하는 딥러닝' 이렇게 3개를 이용해 공부할 거고요. 코드 실습 같은 건 핸즈 온 머신러닝이 제일 챕터가 다양하고 세분화 되어있길래 이 책을 기준으로 가려고 합니다. 순서는 아마

핸즈 온 머신러닝 1권 앞부분 → 퍼셉트론 → 핸즈 온 머신러닝 1권 뒷부분 → 딥러닝 기초 → 핸즈 온 머신러닝 2권 & 다른 책 진도 같이"

 

이 정도로 나가지 않을까 싶습니다. 코드는 아까 말했듯 핸즈 온 머신러닝 기준 & 이 책에 없는 내용이나 보충할 게 있다면 다른 책에서 가져오는 정도로 하겠습니다. 그리고 지금까지 모델 만들거나 할 때 GPT의 도움을 꽤 많이 받았는데 앞으로는 그런 일을 좀 줄여보기 위해 가급적 모든 코드를 제가 짜보려고 합니다. 그럼 지금부터 한 번 시작해보겠습니다.

 

그리고 대학교에서 영어로 수업을 한다길래 가급적이면 용어나 이런 것은 영어로 적어보겠습니다.


머신러닝 개요

1.1 머신러닝이란?

머신러닝(이하 ML)은 데이터에서 학습하도록 컴퓨터를 프로그래밍하는 과학입니다.

좀 더 일반적인 정의는

머신러닝은 명시적 프로그래밍 없이 컴퓨터가 학습하는 능력을 갖추게 하는 연구 분야다.
- Arther Samuel, 1959

이고, 좀 더 공학적인 정의는

어떤 작업 T에 대한 컴퓨터 프로그램의 성능을 P로 측정했을 때 경험 E로 인해 성능이 향상됐다면,이 프로그램은 작업 T와 성능 측정 P에 대해 경험 E로 학습한 것이다.
- Tom Mitchell, 1997

라고 할 수 있겠습니다.


1.2 머신러닝 사용 이유?

머신러닝을 사용하면 프로그램이 무언가를 자동으로 학습하므로 수동으로 할 때보다 코드가 짧아지고 유지 보수가 쉬우며, 대부분 정확도가 더 높습니다.

 

또한 전통적인 방식으로는 너무 복잡하거나 알려진 알고리즘이 없는 문제에 대해서도 유용하게 사용할 수 있습니다. 음성 인식을 예로 들자면,하드코딩을 통해 어떤 사람이 말한 'one'과 'two'를 구분해내는 건 정말 쉽지 않을 일이겠지만 ML을 사용하면 간단하게 구현해낼 수 있습니다.

 

또, ML 알고리즘이 학습한 것을 조사함에 따라 새로운 추세나 상관관계가 밝혀지기도 하고, 이를 통해 우리가 무엇인가를 배울 수도 있습니다. 이처럼 대용량의 데이터를 분석해 패턴을 발견하는 것을 Data Mining이라고 합니다.


1.3 머신러닝 시스템 종류

ML은 다음과 같이 다양한 기준으로 분류가 가능합니다.

(1) 훈련 시 지도 방식 (지도, 비지도, 준지도, 자기 지도, 강화학습)

(2) 실시간 학습 여부 (온라인 학습, 배치 학습)

(3) 일반화 방식 (사례 기반 학습, 모델 기반 학습)

 

1.3.1 훈련 시 지도 방식

ML 시스템을 훈련(학습) 시의 지도 형태나 정보량에 따라 분류할 수 있습니다.

 

(1) Supervised Learning [지도학습]

지도 학습은 훈련 데이터에 레이블이 포함됩니다. 또 특성을 이용해 타깃 수치를 예측합니다.

대표적 기법으로는 Classification, Regression이 있습니다.

지도학습 과정

 

(2) Unsupervised Learning [비지도학습]

비지도 학습은 훈련 데이터에 레이블이 없고, 시스템이 도움 없이 학습하게 됩니다. 따라서 모델이 스스로 데이터들을 군집화하게 됩니다. 또, Hierarchical Clustering (계층 군집) 알고리즘을 사용하면 더 작은 그룹으로 세분화 할 수 있습니다.

비지도학습 과정

 

※ 비지도 학습의 예

(2-1) Visualization Algorithm : 대규모 데이터를 넣으면 도식화 가능한 2D or 3D 표현을 만들어줍니다.

(2-2) Dimensionality Reduction [차원 축소] : 상관관계가 있는 여러 특성을 하나로 합칩니다.

ex) 차의 주행거리 & 연식 = 연관되어있음 → 차의 마모 정도를 나타내는 하나의 특성으로 합침 = Feature Extraction [특성 추출]

(2-3) Outlier Detection [이상치 탐지] : 데이터셋에서 이상치를 자동으로 제거합니다. ≒ Novelty Detection [특이치 탐지] : 훈련 세트의 샘플과 달라보이는 새로운 샘플을 탐지합니다. 따라서 특이치 탐지에는 아주 clean한 훈련 데이터가 필요합니다.

ex) 강아지 사진 수천 장 중 1%가 치와와 → Novelty Detenction Algorithm ≠ 치와와 특이치로 처리 ↔ Outlier Detection Algorithm = 치와와 이상치로 처리

(2-4) Association Rule Learning [연관 규칙 학습] : 대량의 데이터에서특성 간의관계를 찾습니다.

ex) 마트 물품 판매 기록에 연관 규칙 적용 → 바비큐 소스 & 감자 구매 시 스테이크 구매 경향 있음을 알아냄.

 

(3) Semi-supervised Learning [준지도학습]

레이블이 일부 데이터에만 달려있을 때, 준지도학습을 사용하게 됩니다. 대부분의 준지도학습 알고리즘은 지도 학습과 비지도 학습이 조합되어 있습니다. 

ex) 군집 알고리즘 → 그룹화 → 그룹 별 가장 많이 나타나는 레이블 할당 → 전체 데이터에 레이블 부여 → 지도 학습 알고리즘 사용

준지도학습 과정

 

(4) Self-supervised Learning [자기 지도 학습]

자기 지도 학습은 레이블이 전혀 없는 데이터셋에서 완전히 레이블을 부여한 데이터셋을 생성합니다. 여기서도 데이터셋에 레이블이 전부 부여되면 지도 학습 알고리즘을 사용할 수 있습니다.

ex) 레이블 없는 데이터셋 → 마스킹 후 복원하도록 훈련 (마스킹 = 입력, 원본 = 레이블)

보통 자기 지도 학습을 통해 훈련된 모델은 후에 관심 대상을 위해 약간 수정하거나 Fine Tuning을 합니다.

 

자기 지도 학습은 훈련 도중 생성된 레이블을 사용하기 때문에 굳이 따지자면 지도 학습에 더 가깝습니다.

 

(5) Reinforcement Learning [강화 학습]

강화학습은 agent가 환경을 관찰해 action을 취하고 이에 따른 보상이나 벌점을 받으며 최적의 policy를 찾아가는 알고리즘입니다. 자세한 내용은 이미 전에 다룬 적이 있으니 넘어가겠습니다.

2024.04.08 - [프로그래밍/틱택토 강화학습 (TTT-RL)] - 틱택토 강화학습 (Tik-Tak-Toe RL) - [정보과학융합탐구 - 4월 과제]

 

틱택토 강화학습 (Tik-Tak-Toe RL) - [정보과학융합탐구 - 4월 과제]

2024.03.28 - [프로그래밍/강화학습 (RL)] - 틱택토 강화학습 (Tik-Tak-Toe RL) - [정보과학융합탐구 - 3월 과제] 틱택토 강화학습 (Tik-Tak-Toe RL) - [정보과학융합탐구 - 3월 과제]저번 백준 풀이 과제에 이어

olzl07.tistory.com

 

 

1.3.2 실시간 학습 여부

또한 ML 시스템을 입력 데이터의 스트림으로부터 점진적으로 학습할 수 있는지 여부에 따라 분류하기도 합니다.

 

(1) Batch Learning [배치 학습]

배치 학습에서는 시스템이 점진적으로 학습할 수 없고, 가용한 데이터를 모두 써서 훈련시켜야 합니다. 이 방식은 시간과 자원을 많이 쓰므로 오프라인에서 수행됩니다.

ex) 시스템 훈련 → 제품 시스템에 적용 → 실행 (더 학습 X)

 

따라서 이를 Offline Learning이라고도 합니다.

이러한 경우 모델이 바뀌지 않기 때문에 시간이 갈수록 성능이 감소하며, 이를 Model Rot [모델 부패] 또는 Data Drift [데이터 드리프트] 라고 부릅니다.

 

배치 학습을 새로운 데이터에 대해 적용하려면 전체 데이터를 사용해 새로 훈련해야 합니다. 따라서 많은 시간과 컴퓨팅 자원이 필요하게 됩니다.

 

(2) Online Learning [온라인 학습]

온라인 학습에서는 데이터를 Mini Batch의 묶음 단위로 주입해 계속해서 훈련시킵니다. 

온라인 학습 과정

 

또, 온라인 학습을 이용하면 아주 큰 데이터셋으로도 훈련시킬 수 있습니다. (이를 Out-of-core Learning [외부 메모리 학습] 이라고 합니다.)

 

온라인 학습에서 중요한 파라미터는 변화하는 데이터에 얼마나 빠르게 적응할지를 정하는 Learning Rate입니다. Learning rate가 높으면 예전 데이터를 금방 잊고, 낮으면 느리게 학습하게 됩니다.

 

온라인 학습의 문제점은 시스템에 나쁜 데이터가 주입되었을 때 성능이 감소한다는 것입니다.

ex) 버그 or 시스템 속이는 행위로부터 나쁜 데이터 올 수 있음

이를 줄이기 위해 시스템을 모니터링해 성능이 감소하면 학습을중지시키거나 데이터를 모니터링해 비정상 데이터를 잡아낼 수 있습니다.

 

 

1.3.3 일반화 방식

ML 시스템은 예측을 하는 것이므로 새로운 데이터에서 일반화를 해야 합니다. 이러한 일반화 방식으로도 ML 시스템을 분류할 수 있습니다.

 

(1) Instance-based Learning [사례 기반 학습]

이 학습 기법은 단순히 기억하는 것입니다. 입력 데이터와 새로 들어온 데이터 사이의 Similarity [유사도]를 측정해 분류를 진행하게 됩니다.

사례 기반 학습 예시

 

(2) Model-based Learning [모델 기반 학습]

모델 기반 학습은 샘플들의 모델을 만들어 예측에 활용하는 것입니다. 예를 들어, 데이터들을 제일 잘 표현하는 식을 찾은 뒤 이를 통해 이후 값을 예측해낼 수 있습니다.

ex) Linear Regression

모델 기반 학습 예시

 

예를 들어 모델을 하나 만들어보겠습니다.

OECD 기준 1인당 GDP 데이터와 삶의 만족도 데이터를 이용해 돈과 행복 사이에 연관이 있는지, 그 수치는 어느 정도인지를 알아봅시다.

먼저, GDP 데이터와 삶의 만족도 데이터를 pandas를 이용해 불러온 뒤, 데이터(X)와 레이블(y)을 지정해줍니다. 이후 이를 산점도로 표현해보겠습니다.

import matplotlib.pyplot as plt
import pandas as pd
from sklearn.linear_model import LinearRegression

data_root = "https://github.com/ageron/data/raw/main/"
life_sat = pd.read_csv(data_root + "lifesat/lifesat.csv")

X = life_sat[["GDP per capita (USD)"]].values
y = life_sat[["Life satisfaction"]].values

life_sat.plot(kind = 'scatter', grid = True, x = "GDP per capita (USD)", y = "Life satisfaction")
plt.axis = [23_500, 62_500, 4, 9]
plt.show

 

그러자 다음과 같은 결과가 나왔습니다.

코드 실행 결과

 

대충 봐도 양의 상관관계를 띈다는 걸 알 수 있습니다. 이제 새로운 데이터(1인 당 GDP)가 입력되었을 때 예측(삶의 만족도)을 해주게 모델을 학습시켜야 합니다. 다시 말해, Linear Model을 하나 만들어야 합니다. 

 

현재 이 데이터는 총 2차원이므로 $ y = wx + b $라는 선형 함수로 모델링 할 수 있고, $w$, $b$라는 Model Parameter를 찾아내야 합니다. 이 model parameter에 따라 데이터들을 잘 표현하는지 아닌지가 결정되게 합니다. 데이터들을 잘 표현했는지 아닌지는 얼마나 데이터를 잘 나타내는지 측정하는 Utility Function [효용 함수] (혹은 Fitness Function [적합도 함수])이나 얼마나 데이터를 못 나타내는지 측정하는 Loss Function [비용 함수]를 통해 알아낼 수 있습니다.

보통 선형 회귀에서는 예측 값과 데이터의 실제 레이블 사이 거리를 재는 비용 함수를 사용하게 되고, 이 거리를 최대한 좁히려고 하게 됩니다.

 

따라서 선형 회귀 알고리즘을 통해 최적의 model parameter를 찾게 training하면 모델 생성이 완료됩니다.

이후 새로운 데이터 (2020년 키프로스의 1인당 GDP)을 집어넣어 결과까지 확인해보겠습니다.

model = LinearRegression()
model.fit(X, y)

X_new = [[37_655.2]]
print(model.predict(X_new))
[[6.30165767]]

 

모델을 학습시킨 후 새로운 데이터인 37655.2를 넣어주자 6.30165767이라는 삶의 만족도를 예측해주는 것을 볼 수 있습니다.

 

 

사례 기반 학습 알고리즘을 사용할수도 있는데,대표적으로 K-nearest Neighbors Regression이 있습니다. 이 회귀 기법을 사용하면 새로운 데이터와 가장 유사한 n개의 데이터들의 레이블을 통해 새로 들어온 데이터의 레이블을 알아내게 됩니다. 예를 들어, 키프로스의 1인 당 GDP 37655.2$와 가장 비슷한 3개의 나라(이스라엘, 리투아니아, 슬로베니아)의 삶의 만족도들을 평균내 6.33이라는 값을 예측할 수도 있습니다.


1.4 머신러닝의 주요 도전 과제

모델을 선택해 데이터로 훈련시키는 것이 ML의 주 작업이기 때문에 '나쁜 모델'이나 '나쁜 데이터'에 의해 문제가 발생할 수 있습니다. 

 

1.4.1 나쁜 데이터

(1) 부족한 데이터

아직까지 머신러닝에는 수없이 많은 데이터가 필요합니다. 또, 데이터의 수에 따라 정확도가 기하급수적으로 차이나므로 데이터의 양은 굉장히 중요합니다.

데이터 양과 모델의 성능

 

(2) 대표성 없는 데이터

일반화를 잘 시키고 싶다면 훈련 데이터가 일반화하고자 하는 사례를 잘 대표해야 합니다. 

예를 들어, 앞서 실습한 선형 모델의 데이터에는 GDP가 23500$보다 적거나 62500$보다 큰 데이터가 존재하지 않습니다. 따라서 이를 추가하면 모델이 변경되어야 하거나, 선형 모델로 잘 작동하지 않을 수도 있습니다.

 

만약 샘플이 너무 작으면 우연에 의해 대표성이 없어지는 Sampling Noise [샘플링 잡음]가 발생할 수 있고, 큰 샘플이어도 추출을 잘못하면 대표성을 띄지 못하는 Sampling Bias [샘플링 편향]가 발생할 수 있습니다.

 

(3) 낮은 품질의 데이터

훈련 데이터가 오류, 이상치, 노이즈 등이 많다면 모델의 성능은 급격히 떨어집니다. 이러한 것을 방지하기 위해 데이터 정제 과정을 거치는 것이 중요합니다.

 

(4) 관련 없는 특성

훈련 데이터에 목적과 관련 있는 feature이 충분해야 시스템이 학습하기 좋습니다. 따라서 훈련에 사용할 좋은 특성을 찾는 것이 중요하고, 이를 Feature Engineering [특성 공학]이라 합니다. Feature Engineering에는 다음 과정들이 있습니다.

  • Feature Selection : 훈련에 가장 유용한 특성을 선택
  • Feature Extraction : 특성을 결합해 더 유용한 특성 제작 (ex : Dimensionality Reduction Algoruthm)
  • Data Collection : 새 데이터 수집해 새 특성 제작

 

1.4.2 나쁜 모델 (알고리즘)

(1) Overfitting [과대적합]

모델이 훈련 데이터에만 너무 잘 맞고, 새로운 데이터에 잘 맞지 않는 경우를 과대적합이 일어났다고 합니다. 이 경우 훈련 데이터에 대해서는 좋은 성능을 보이지만, 새로운 데이터가 들어오면 성능이 급격히 낮아집니다.

과적합의 예시

 

간단히 말해 모델이 너무 복잡하게 만들어질 경우 데이터들의 패턴을 너무 복잡하게 잡아내어 훈련 데이터에 대해서만 성능이 좋게 되는 겁니다. 노이즈가 섞인 패턴을 알아내는 거죠.

수학 문제집만 주구장창 돌렸더니 그 문제집은 잘 푸는데 실제 모의고사는 못 푸는 경우라고 생각하면 될 것 같습니다.

 

※ Regularization [정규화]

이러한 과적합을 막기 위해 Regularization이라는 것을 이용합니다. 모델은 단순하게 하기 위해 제약을 가하는 것입니다. 이는 훈련 데이터에 모델을 맞추기 위한 Degree of Freedom [자유도] 를 학습 알고리즘에 부여해 모델이 $w$, $b$ 등을 조절하게 합니다. 예를 들어, $w = 0$으로 강제하면 알고리즘에는 $b$ 하나의 자유도만 남게 되고 할 수 있는 건 직선을 올리거나 내리는 것밖에 없게 됩니다. 따라서 평균 근처에 직선을 두게 하는 식으로 규제를 가할 수 있는 거죠.

 

그리고 알고리즘이 $w$를 수정하게 하되 아주 작은 가중치만 갖게 하나다면 학습 알고리즘은 자유도 1과 2 사이 어딘가에 위치할 겁니다. 이는 자유도가 2인 모델보다는 단순하고, 자유도가 1인 모델보다는 복잡한 모델을 만들어 적절한 균형을 갖게 할 수 있습니다.

 

식을 이용해서 좀 더 깊이 파보겠습니다. 보통 모델의 Loss는 다음과 같이 계산합니다. (여기서 Loss [손실]는 모델의 예측 값과 실제 값의 차이로, Loss가 작을수록 모델의 정확도가 높아집니다.)

$$ L = Loss(y, \hat{y}) $$

 

그러나 정규화를 진행하면 Loss 식이 다음과 같이 변하게 됩니다.

$$ L = Loss(y, \hat{y}) + \lambda \cdot R(w) $$

$\lambda =$ 정규화 항 중요도 조정 하이퍼파라미터, $R(w) =$ 정규화 항, $w =$ 모델의 가중치

 

그리고 가중치 $w$를 너무 크게 되면 모델이 훈련 데이터 하나하나에 민감하게 반응해 지나치게 복잡한 패턴을 만들고, 과적합이 발생할 수 있기 때문에 $w$를 작게 해야 합니다.

만약 $\lambda$가 커지면 모델은 Loss를 최소화하기 위해 $R(w)$ 항을 최소화하려하고, 자연스럽게 $w$가 작아집니다. 반대로 만약 $\lambda$가 작아지면 상대적으로 $R(w)$ 항은 커지게 되고, $w$도 커집니다.

 

결론적으로 $\lambda$가 작아지면 $w$가 커져 더 복잡한 모델이 만들어지고, $\lambda$가 커지면 $w$가 작아져 과적합을 방지할 수 있습니다. 또 하이퍼파라미터가 너무 크거나 작아도 문제가 될 수 있기 때문에 이를 잘 tuning하는 것은 굉장히 중요합니다.

 

(2) Underfitting [과소적합]

과소적합은 과대적합의 반대 의미로, 모델이 데이터의 패턴 자체를 학습하지 못할 때 발생하게 됩니다. 모델이 너무 단순하다거나 데이터가 너무 적은 경우 등에 발생하게 됩니다.

과소적합의 예시

 

과소적합을 해결하기 위해선 앞서 말한 하이퍼파라미터를 작게 하는 등의 방법이 있습니다.


1.5 테스트와 검증

모델을 테스트하기 위한 가장 좋은 방법은 실제 서비스에 넣고 적용시켜보는 것이겠지만, 이는 리스크가 있으므로 보통 훈련 데이터를 train datatest data로 나누게 됩니다. 이후 train data로는 모델을 훈련하고, test data로는 모델을 테스트하게 됩니다. 

새로운 샘플에 대한 오차 비율을 Generalization Error [일반화 오차] (혹은 Out-of-Sample Error [외부 샘플 오차])라고 하며, test data에서 모델을 평가하면서 이 오차의 추정값을 얻습니다. 만약 train data에서 모델의 loss가 작지만 일반화 오차는 크다면 과대적합 되었다고 판단할 수 있습니다.

 

1.5.1 하이퍼파라미터 튜닝과 모델 선택

모델 평가는 간단히 test data를 이용하면 진행할 수 있습니다. 예를 들어 A 모델과 B 모델 중 갈등하고 있다면, 그냥 둘 다 test data로 테스트한 뒤 성능을 비교하면 됩니다.

 

또, 하이퍼파라미터 값 선택이 문제라면 하이퍼파라미터 값을 n개 만들어두고, n개의 다른 모델을 만들어 비교할 수도 있습니다. 그러나 이 경우 일반화 오차가 가장 작은 하이퍼파라미터 값을 적용해도 실제 서비스에서는 그렇지 않을 수 있습니다. 따라서 이를 해결하기 위해 보통 Holdout Validation [홀드아웃 검증]을 적용합니다. 홀드아웃 검증 과정을 간단히 설명하자면 다음과 같습니다. 

 

홀드아웃 검증 과정

 

먼저, train set의 일부를 떼내 valid set [검증 세트] (혹은 Development Set [개발 세트], Dev Set [데브 세트])를 만듭니다. 이후 train set을 이용해 모델이 데이터를 학습하고 최적의 가중치를 찾습니다. 그리고 valid set을 이용해 적합한 하이퍼파라미터 값을 조정해본 뒤 가장 높은 성능을 내는 모델을 선택합니다.

이 과정들이 다 끝나면 마지막으로 train set과 valid set을 합친 전체 훈련 세트에서 다시 훈련해 최종 모델을 만들고, 이를 test set에서 평가하여 일반화 오차를 측정합니다.

 

교차 검증 과정

 

그러나 이 과정은 검증 세트가 너무 작으면 모델이 정확히 평가되지 않을 수 있고, 검증 세트가 너무 크면 훈련 세트가 너무 작다는 문제가 있습니다. 따라서 이를 해결하기 위해 작은 검증 세트 여러 개를 사용해 반복적으로 Cross-Validataion [교차 검증]을 진행할 수 있습니다. 전체 train set을 $K$개의 subset으로 나누고 하나의 세트를 valid set으로, 나머지 $K-1$개의 세트를 train set으로 사용하는 것입니다. 이후 valid set를 바꿔가며 총 $K$번 반복하고 얻은 $K$개의 성능 평가를 평균내어 더 정확한 성능을 알아내는 것입니다.

 

1.5.2 데이터 불일치

쉽게 많은 양의 train data를 구하지만, 이 데이터가 실제 데이터와 완벽히 같지 않은 경우가 있을 수 있습니다.이런 경우 valid set와 test set만큼은 실제 데이터를 최대한 잘 대표해야하므로, 실제 데이터를 가장 잘 대표하는 자료들을 모아 valid set와 test set에 나눠야 합니다.

 

이에 대한 해결책으로 Train-Dev Set [훈련-개발 세트]를 만들 수 있습니다. train set의 일부를 떼어내 train-dev set로 만든 뒤 train set에서 훈련한 모델을 train-dev set에서 평가하는 것입니다. 만약 train-dev set에서 잘 작동한다면 valid set에서 다시 평가하고, 잘 작동하지 않는다면 과적합되었다고 평가하는 것입니다. 혹시 valid set에서 성능이 나쁘다면 데이터 전처리 등을 시도해볼 수 있습니다.


우선 오늘은 이렇게 '핸즈 온 머신러닝 3판' 1권 챕터 1 부분을 정리해봤습니다. 앞으로도 계속해서 진도를 나가보도록 하겠습니다.