Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

21 머신러닝 소개

Updated: 29 apr 2026

컴퓨터에 위키백과 문서를 단순히 저장한다고 해서 컴퓨터가 똑똑해지는 것은 아니다. 반면 머신러닝을 이용해 그 문서들을 학습시키면, 스스로 패턴을 파악하여 주어진 문제를 해결하는 능력을 갖추게 된다.

21.1머신러닝 모델

21.1.1전통적 프로그래밍

전통적인 프로그래밍은 일정한 과정을 따라 진행된다. 먼저 문제 연구 단계에서 해결해야 할 문제를 분석하고, 이를 해결할 수 있는 알고리즘을 연구한다. 다음으로 규칙 작성 단계에서는 연구된 알고리즘을 실제 코드로 구현한다. 이후에는 평가 단계가 이어지는데, 이 단계에서는 구현된 프로그램을 테스트하여 올바르게 작동하는지 확인한다. 테스트를 통과하면 프로그램은 실전 배치된다. 그러나 테스트에 실패할 경우, 발생한 오차를 분석한 뒤 다시 문제 연구 단계로 돌아가 알고리즘을 수정하고 개선하는 과정을 반복한다.

예를 들어, 전통적인 프로그래밍 방식으로 구현된 스팸 메일 분류기는 특정 단어가 이메일 제목에 포함되면 스팸으로 처리하도록 규칙을 작성한다. 개발자는 직접 코드에 조건문을 넣어 “제목에 ‘무료’, ‘당첨’, ‘신용카드 정보’, ‘광고’ 등이 있으면 스팸으로 분류하라”는 규칙을 명시한다.

if "무료" in subject or "당첨" in subject or "신용카드 정보" in subject:
    label = "spam"
else:
    label = "ham"

이처럼 규칙을 코드로 작성해두면 초기에는 잘 작동한다. 하지만 프로그램이 실제로 운영된 이후 새로운 스팸 단어가 등장하면 기존 규칙만으로는 제대로 분류하지 못한다. 따라서 개발자가 매번 새로운 규칙을 추가하거나 수정해야 하며, 이로 인해 유지 보수가 매우 어렵다.

21.1.2머신러닝 프로그래밍

스팸으로 지정된 메일에 ‘무료’, ‘당첨’, ‘신용카드 정보’, ‘광고’, ‘투^^자’, ‘무❤료’ 등의 표현이 자주 등장하는 경우 새로운 메일에 그런 표현이 사용되면 자동으로 스팸으로 분류하도록 스스로 학습하는 프로그램인 머신러닝 모델을 작성한다.

스팸 메일 분류 머신러닝 모델의 학습은 스팸 메일과 아닌 메일의 구분법을 학습하기 위해 다량의 스팸 메일과 스팸이 아닌 메일로 구성된 훈련셋을 활용한다. 학습이 완료된 스팸 메일 분류 머신러닝 모델은 새로운 이메일에 대해 학습된 정보를 이용하여 스팸인지 아닌지 판별한다.

머신러닝 모델 훈련 자동화

머신러닝 모델이 주어진 데이터로부터 필요한 정보를 학습하도록 하는 과정이 모델 훈련이다. 모델 훈련은 머신러닝 파이프라인 또는 MLOps(Machine Learning Operations, 머신러닝 운영) 기법 등을 활용하여 자동화할 수 있다. 예를 들어, MLOps는 기존에 학습되지 않은 새로운 종류의 스팸 메일이 많이 신고되는 경우 신고된 스팸 메일의 내용을 분석한 다음에 스팸 메일 분류 모델을 새로운 훈련셋에 대한 훈련을 자동화하는 데에 활용될 수 있다.

머신러닝 프로그래밍의 장점

머신러닝 프로그래밍은 전통적인 규칙 기반 접근 방식으로는 유지보수가 어렵거나 해결하기 힘든 문제들을 보다 효율적으로 다룰 수 있게 한다. 예를 들어, 스팸 메일 분류기는 수많은 규칙을 직접 작성해야 하는데, 머신러닝을 활용하면 이러한 복잡한 규칙을 자동으로 학습하여 훨씬 간단하게 구현할 수 있다.

또한 음성 인식처럼 전통적인 방식으로는 지나치게 복잡한 문제도 머신러닝을 통해 해결할 수 있다. 머신러닝 모델은 새로운 환경과 데이터에 쉽게 적응할 수 있어 변화하는 상황에서도 유연하게 대응할 수 있는 시스템을 개발할 수 있다.

마지막으로, 머신러닝은 복잡한 문제와 방대한 데이터를 분석하여 기존 방식으로는 얻기 어려운 깊은 통찰을 제공한다. 이는 빅데이터 시대에 특히 중요한 장점으로, 데이터 속에 숨겨진 패턴과 의미를 발견하는 데 큰 도움을 준다.

21.1.3머신러닝 활용 사례

아래 그림은 다양한 분야에서 활용되고 있는 머신러닝 기술의 대표적인 활용 사례들을 시각적으로 정리한 인포그래픽입니다.

21.1.4머신러닝 모델 유형

아래 표는 머신러닝 모델을 학습 유형과 과제에 따라 구분한다.

학습 유형과제
지도 학습회귀
자기 지도 학습분류
준지도 학습군집화
비지도 학습차원 축소
강화 학습이상치 탐지
신규 데이터 탐지

이 강의노트에서는 지도 학습으로 회귀와 분류 모델을 훈련시키는 모델을 살펴본다.

21.2선형 회귀 모델 훈련

21.2.1삶의 만족도 데이터셋

OECD(경제협력개발기구) 국가의 구매력 기준 1인당 GDPGDP per capita와 해당 국가 국민의 삶의 만족도Life Satisfaction 사이의 관계를 머신러닝 모델을 활용하여 확인한다.

GDP는 국내 총생산Gross Domestic Product의 줄임말이며, 한 나라의 국경 안에서 일정한 기간 동안 생산된 모든 최종 생산물(재화와 서비스)의 시장 가치의 총합을 의미한다. 1인당 GDP(GDP per capita)는 특정 국가의 국내 총생산(GDP)을 총인구수로 나눈 값이며, 한 나라의 국민 평균 생활 수준이나 전반적인 경제적 부를 비교할 때 활용되는 대표적인 지표로 사용된다.

머신러닝 모델 훈련을 위해 2020년 기준으로 OECD 회원국 40개 국가와 비회원국 3개 국가 등 총 40개 국가를 대상으로 조사된 국가별 1인당 GDP와 삶의 만족도 데이터를 활용한다.

지역OECD 회원국기타
유럽오스트리아, 벨기에, 체코, 덴마크, 에스토니아, 핀란드,
프랑스, 독일, 그리스, 헝가리, 아이슬란드, 아일랜드,
이탈리아, 라트비아, 리투아니아, 룩셈부르크, 네덜란드,
노르웨이, 폴란드, 포르투갈, 슬로바키아, 슬로베니아,
스페인, 스웨덴, 스위스, 튀르키예, 영국
브라질
북미캐나다, 미국, 멕시코러시아
아시아-태평양일본, 한국, 호주, 뉴질랜드남아프리카공화국
중남미칠레, 콜롬비아
중동이스라엘

필수 라이브러리 불러오기

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

plt.rc('font', size=12)
plt.rc('axes', labelsize=14, titlesize=14)
plt.rc('legend', fontsize=12)
plt.rc('xtick', labelsize=10)
plt.rc('ytick', labelsize=10)

삶의 만족도 데이터셋 다운로드

data_root = "https://github.com/codingalzi/code-workout-ml/raw/master/notebooks/datasets/"

lifesat_full = pd.read_csv(data_root + "lifesat/lifesat_full.csv")
lifesat_full.head()
Loading...

국가명을 행 인덱스로 지정한다.

lifesat_full = lifesat_full.set_index("Country")
lifesat_full
Loading...

2020년도 기준 37개 OECD 회원국과 함께 3개 국가가 추가된 총 40개 국가의 데이터로 구성된 데이터프레임이 생성되었다. 포함된 두 개의 특성(변수) 모두 부동소수점 자료형이며 결측치는 없다.

lifesat_full.info()
<class 'pandas.DataFrame'>
Index: 40 entries, South Africa to Luxembourg
Data columns (total 2 columns):
 #   Column                Non-Null Count  Dtype  
---  ------                --------------  -----  
 0   GDP per capita (USD)  40 non-null     float64
 1   Life satisfaction     40 non-null     float64
dtypes: float64(2)
memory usage: 1.2 KB

1인당 GDP와 삶의 만족도 두 특성 변수의 기초 통계량은 다음과 같다.

lifesat_full.describe()
Loading...

21.2.2훈련셋 지정

훈련 목적

머신러닝 모델을 훈련시키려면 먼저 훈련의 목적을 명확히 해야 한다. 여기서는 다음 두 가지 목표를 달성하고자 한다.

첫째, 국가의 1인당 GDP가 증가할수록 해당 국가 국민의 삶의 만족도가 선형적으로 높아진다는 가정 하에 1인당 GDP가 알려진 국가의 삶의 만족도를 예측하는 선형 회귀 모델linear regression model을 훈련시킨다.

둘째, 머신러닝 모델을 훈련시킬 때 발생할 수 있는 과대적합 문제를 설명하기 위해 고의로 8개 국가의 데이터를 데이터셋에서 제외시키고 훈련 시킬 때와 그렇지 않을 때를 비교한다.

제외 대상 국가 지정

1인당 GDP가 하위 10% 또는 상위 10% 구간에 포함되는 국가들을 제외 대상으로 지정된다.

gdppc_col = "GDP per capita (USD)"
lifesat_col = "Life satisfaction"

min_gdp = lifesat_full[gdppc_col].quantile(0.1)
max_gdp = lifesat_full[gdppc_col].quantile(0.9)

gdp_mask = (lifesat_full[gdppc_col] >= min_gdp) & (lifesat_full[gdppc_col] <= max_gdp)
lifesat = lifesat_full[gdp_mask]
lifesat.info()
<class 'pandas.DataFrame'>
Index: 32 entries, Chile to United States
Data columns (total 2 columns):
 #   Column                Non-Null Count  Dtype  
---  ------                --------------  -----  
 0   GDP per capita (USD)  32 non-null     float64
 1   Life satisfaction     32 non-null     float64
dtypes: float64(2)
memory usage: 1011.0 bytes

40개 국가 중에서 다음 8개 국가가 제외되었다.

excluded_countries = lifesat_full[~ gdp_mask]
excluded_countries
Loading...

21.2.3데이터 탐색

아래 코드는 1인당 GDP 기준 하위 10%에서 상위 10% 사이의 국가들을 대상으로 1인당 GDP와 삶의 만족도의 관계를 산점도로 보여준다. 국가의 1인당 GDP가 증가할 수록 삶의 만족도가 선형적linear으로 증가하는 경향이 보인다.

lifesat.plot(kind='scatter', figsize=(7, 5), grid=True, x=gdppc_col, y=lifesat_col)

# 축별로 축 limits 설정
min_life_sat = 4
max_life_sat = 9
plt.axis([min_gdp-1000, max_gdp+1000, min_life_sat, max_life_sat])

plt.show()
<Figure size 700x500 with 1 Axes>

두 특성 변수의 피어슨 상관계수가 0.77 정도로 매우 높은 편이다.

lifesat.corr()
Loading...

21.2.4선형 회귀 모델

국가의 1인당 GDP와 삶의 만족도 사이의 선형 상관관계를 학습하는 모델은 선형 회귀 모델linear regression model이다.

여기서 말하는 선형 회귀 모델은 특정 국가의 1인당 GDP가 주어졌을 때 다음과 같은 일차 방정식을 이용하여 해당 국가의 삶의 만족도를 예측(계산)하는 알고리즘(프로그램)을 의미한다.

삶의 만족도=θ0+(1인당 GDP)θ1\text{삶의 만족도} = \theta_0 + (\text{1인당 GDP}) \cdot \theta_1

선형 회귀 모델의 성능 평가

선형 회귀 모델의 성능은 1차 방정식에 사용된 절편 θ0\theta_0와 기울기 θ1\theta_1에 의해 결정된다.

예를 들어, 아래 그래프는 1인당 GDP와 삶의 만족도 사이의 선형 관계를 적절하지 않게 모델링하는 세 가지 선형 회귀 모델을 보여준다.

  • 빨강선 모델: 전혀 학습되지 않은 모델이다.

  • 초록선 모델: 양의 선형 상관관계를 음의 선형 상관관계로 완전히 잘못 학습한 모델이다.

  • 파랑선 모델: 1인당 GDP와 삶의 만족도 사이의 변화 경향을 나름 잘 반영하지만, y-축 절편 θ0\theta_0가 조금 작아서 예측값이 전반적으로 낮게 계산된다.

lifesat.plot(kind='scatter', figsize=(7, 5), grid=True, x=gdppc_col, y=lifesat_col)

X_range = np.linspace(min_gdp, max_gdp, 1000)

w1, w2 = 4.2, 0
plt.plot(X_range, w1 + w2 * 1e-5 * X_range, "r")
plt.text(40_000, 4.9, fr"$\theta_0 = {w1}$", color="r")
plt.text(40_000, 4.4, fr"$\theta_1 = {w2}$", color="r")

w1, w2 = 10, -9
plt.plot(X_range, w1 + w2 * 1e-5 * X_range, "g")
plt.text(26_000, 8.5, fr"$\theta_0 = {w1}$", color="g")
plt.text(26_000, 8.0, fr"$\theta_1 = {w2} \times 10^{{-5}}$", color="g")

w1, w2 = 3, 8
plt.plot(X_range, w1 + w2 * 1e-5 * X_range, "b")
plt.text(48_000, 8.5, fr"$\theta_0 = {w1}$", color="b")
plt.text(48_000, 8.0, fr"$\theta_1 = {w2} \times 10^{{-5}}$", color="b")

plt.axis([min_gdp, max_gdp, min_life_sat, max_life_sat])

plt.show()
<Figure size 700x500 with 1 Axes>

21.2.5회귀 모델 훈련

선형 회귀 모델이 정확한 예측값을 계산하려면 두 개의 파라미터인 절편 θ0\theta_0와 기울기 θ1\theta_1이 적절해야 한다. 이전 그래프에서 빨강선 모델과 초록선 모델은 두 파라미터 모두 부적절했다. 반면에 파랑선 모델은 기울기 파라미터는 적절해 보였지만 절편 파라미터가 부적절했다.

머신러닝 모델의 훈련은 θ0\theta_0θ1\theta_1처럼 적절한 예측값 계산에 필요한 최적의 파라미터들을 데이터셋 학습을 통해 찾아가는 과정이을 가리킨다.

지도 학습

머신러닝 모델을 지도 학습 방식으로 훈련시키려면 훈련셋을 입력 데이터셋과 타깃셋으로 구분해야 한다. 입력 데이터는 모델이 학습해야 하는 대상이고, 반면에 타깃은 모델이 예측해야 하는 값이다. 이처럼 예측해야 하는 값이 정해진 모델을 학습시키는 방법이 지도 학습supervised learning이다.

scikit-learn 모델의 입력 데이터셋과 타깃셋

scikit-learn(사이킷런)은 머신러닝 전용 파이썬 라이브러리이며, 머신러닝 훈련에 필요한 다양한 모델과 도구를 제공한다. 사이킷런 모델 훈련을 위한 입력 데이터셋과 타깃셋은 모두 데이터프레임 또는 넘파이 2차원 어레이로 지정되어야 한다. 여기서는 데이터프레임을 사용한다.

1인당 GDP가 주어졌을 때 해당 국가의 삶의 만족도를 예측하는 선형 회귀 모델을 훈련시켜야 하기에 입력 데이터셋과 타깃셋은 다음과 지정된다.

입력 데이터셋

32개 국가의 1인당 GDP를 포함하는 데이터프레임으로 지정한다. 참고로 입력 데이터셋을 훈련셋으로 부르기도 하며, 여기서도 혼용해서 사용한다.

X = lifesat[["GDP per capita (USD)"]]

타깃셋

32개 국가의 삶의 만족도 특성만 포함하는 데이터프레임으로 지정한다.

y = lifesat[["Life satisfaction"]]

선형 회귀 모델 지정

사이킷런의 선형 회귀 모델은 사이킷런 라이브러의 linear_model 모듈에 포함된 LinearRegression 클래스의 인스턴스로 지정한다.

  • sklearn.linear_model: 사이킷런 라이브러리의 선형 회귀 모델 관련 모듈

  • LinearRegression: 선형 회귀 모델의 클래스

from sklearn.linear_model import LinearRegression

oecd_linear_model = LinearRegression()

oecd_linear_model는 아직 훈련이 되지 않은 선형 회귀 모델을 가리키며, 앞서 지정한 훈련셋(입력 데이터셋)과 타깃셋을 이용하여 훈련을 진행하면서 삶의 만족도 예측에 필요한 파라미터(절편과 기울기)를 학습한다.

모델 훈련

사이킷런의 모델 클래스로 지정된 머신러닝 모델의 fit() 메서드를 훈련셋과 타깃셋을 인자로 하면서 호출하면 지도 학습 방식으로 훈련을 시작하며, 적절한 파라미터를 찾으면 훈련이 종료된다.

oecd_linear_model.fit(X, y)
Loading...

fit() 메서드의 반환값은 없다. 대신 훈련 과정에서 학습된 정보를 객체 내부에 속성attribute으로 저장한다.

예를 들어, 입력 데이터셋에 포함된 32개 국가의 1인당 GDP와 해당 국가의 삶의 만족도 사이의 선형 상관관계를 1차 함수로 최대한 적절하게 묘사하기 위해 훈련을 통해 학습한 절편 θ0\theta_0와 기울기 θ1\theta_1가 훈련이 완료된 모델 내부에 각각 intercept_coef_ 속성으로 저장된다.

  • 1차 함수 절편 (θ0\theta_0)

oecd_linear_model.intercept_
array([4.15601279])
  • 1차 함수 기울기 (θ1\theta_1)

oecd_linear_model.coef_
array([[5.81338356e-05]])

절편은 1차원 어레이로, 기울기는 2차원 어레이로 지정된다. 자세한 이유는 나중에 설명하며, 여기서는 어레이에 포함된 값들을 인덱싱하여 1인당 GDP와 삶의 만족도 사이의 관계를 1차 함수 그래프로 그리는 데에 활용한다.

선형 회귀 모델의 예측 함수 그래프

아래 코드는 머신러닝 모델이 훈련을 통해 학습한 절편과 기울기를 갖는 직선의 그래프를 데이터 산점도와 함께 그린다. 모델이 훈련을 통해 훈련셋으로부터 학습한 1인당 GDP와 삶의 만족도 사이의 선형 관계가 매우 적절함을 눈으로 확인할 수 있다.

선형 회귀 모델이 데이터 학습을 통해 어떻게 적절한 절편과 기울기를 학습하는지, 또 그렇게 훈련된 절편과 기울기가 최선인지 여부를 어떻게 판단하는지에 대해서는 앞으로 자세히 다룰 예정이다.

# 산점도 그리기: x축은 1인당 GDP, y축은 삶의 만족도
lifesat.plot(kind='scatter', figsize=(7, 5), grid=True, x=gdppc_col, y=lifesat_col)

# 모델이 학습한 절편과 기울기 (인덱싱 적용)
theta_0, theta_1 = oecd_linear_model.intercept_[0], oecd_linear_model.coef_[0, 0]

# 선형 회귀 모델의 예측선(직선) 그리기
X_range = np.linspace(min_gdp, max_gdp, 1000) # x축 범위에 대한 1000개의 점 생성
y_range = theta_0 + theta_1 * X_range         # 각 x값에 대한 예측된 y값 계산
plt.plot(X_range, y_range, "b")

# 그래프 내에 절편과 기울기 표기
plt.text(min_gdp + 22_000, max_life_sat - 1.1, fr"$\theta_0 = {theta_0:.2f}$", color="b")
plt.text(min_gdp + 22_000, max_life_sat - 0.6, fr"$\theta_1 = {theta_1 * 1e5:.2f} \times 10^{{-5}}$", color="b")

# 축 범위 설정
plt.axis([min_gdp, max_gdp, min_life_sat, max_life_sat])

# 그래프 출력
plt.show()
<Figure size 700x500 with 1 Axes>

훈련된 모델 활용

oecd_linear_model은 한 국가의 1인당 GDP가 주어졌을 때 해당 국가 국민의 삶의 만족도를 예측하도록 훈련되었다. 훈련된 모델의 예측값 계산은 모델의 predict() 메서드가 담당한다.

모델을 활용한 예측은 훈련할 때 사용된 훈련셋 데이터에 한정되지 않는다. 예를 들어, 아래 코드는 앞서 훈련셋에서 제외된 8개 국가들의 1인당 GDP를 인자로 지정하여 predict() 메서드를 호출하여 8개 국가의 삶의 만족도를 예측한다.

excluded_countries
Loading...
X_new = excluded_countries[["GDP per capita (USD)"]]
predicted_life_satisfaction = oecd_linear_model.predict(X_new)
predicted_life_satisfaction
array([[ 4.82258638], [ 4.93741833], [ 4.97360604], [ 5.19589635], [ 7.85250525], [ 8.131978 ], [ 9.36997587], [10.56591679]])

정보를 보다 명확하게 전달하기 위해 데이터프레임으로 변환한다.

pd.DataFrame(predicted_life_satisfaction, 
             index=excluded_countries.index,
             columns=["Predicted Life Satisfaction"])
Loading...

모델 훈련으로 정해진 절편과 기울기를 사용하는 1차 함수 f(x)=θ0+θ1xf(x) = \theta_0 + \theta_1 \cdot x를 이용하여 f(x)f(x)를 계산해도 동일한 결과가 나온다.

def linear_model_predict(gdp_per_capita):
    return oecd_linear_model.intercept_[0] + oecd_linear_model.coef_[0, 0] * gdp_per_capita
linear_model_predict(X_new)
Loading...

21.2.6과대적합

머신러닝 알고리즘을 훈련시키다보면 다양한 어려움에 부딪힌다. 여기서는 선형 회귀 모델이 훈련셋에 민감하게 반응하는 과대적합 현상을 살펴 본다.

앞서 제외시킨 8개 국가의 데이터를 포함해서 선형 회귀 모델을 훈련시켜 보자. 제외된 8개 국가는 1인당 GDP가 하위 10% 또는 상위 10% 구간에 포함되는 국가들이며 다음과 같다.

excluded_countries
Loading...

새로운 선형 회귀 모델 훈련

제외되었던 8개 국가를 훈련셋에 포함시키면 훈련은 처음부터 다시 시작해야 한다. 무엇보다도 입력 데이텃과 타깃셋을 새롭게 지정해야 한다.

  • 훈련셋

Xfull = lifesat_full[[gdppc_col]]
  • 타깃셋

yfull = lifesat_full[[lifesat_col]]
  • 새로운 선형회귀 모델 지정 후 훈련

from sklearn.linear_model import LinearRegression

oecd_linear_model_full = LinearRegression()
oecd_linear_model_full.fit(Xfull, yfull)
Loading...

아래 코드는 8개 국가를 제외 했을 때의 선형 회귀 모델(파랑 점선)과 포함시켰을 때의 선형 회귀 모델(검정 실선)의 그래프를 동시에 그린다. 두 모델이 상당히 다름을 확인할 수 있다.

# 40개 국가 산점도
lifesat_full.plot(kind='scatter', figsize=(7, 5), x=gdppc_col, y=lifesat_col, grid=True)

# 32개 국가 대상으로 훈련된 선형 회귀 모델
X_range = np.linspace(0, 115_000, 1000)
plt.plot(X_range, theta_0 + theta_1 * X_range, "b:", label="Excluding 8 countries")

# 40개 국가 대상으로 훈련된 선형 회귀 모델
theta_0_full, theta_1_full = oecd_linear_model_full.intercept_[0], oecd_linear_model_full.coef_[0][0]
plt.plot(X_range, theta_0_full + theta_1_full * X_range, "k", label="Incuding 8 countries")

# 제외된 8개 국가의 실제 데이터 포인트를 빨간색 사각형으로 표시
for i, country in enumerate(excluded_countries.index):
    pos_data_x, pos_data_y = excluded_countries.loc[country]
    # 범례에 한 번만 표시되도록 label을 첫 번째 요소에만 추가합니다.
    label = "Excluded 8 countries" if i == 0 else None
    plt.plot(pos_data_x, pos_data_y, "rs", label=label)

plt.axis([0, 115_000, min_life_sat, max_life_sat])
plt.legend()
plt.show()
<Figure size 700x500 with 1 Axes>

결론적으로, 8개 국가를 포함하는 경우와 그렇지 않은 경우에는 상당히 다른 선형 회귀 모델이 훈련된다. 이처럼 모델 훈련 결과가 훈련에 사용된 데이터셋에 민감하게 반응하는 현상을 과대적합overfitting이라 한다.

21.3연습문제

머신러닝 모델의 훈련은 내부에서 모든 데이터를 어레이로 처리한다. 새로운 데이터셋(sc_weir.csv)을 바탕으로 승촌보의 방류량(Discharge)을 이용해 클로로필-A(Chl-a) 수치를 예측하는 선형회귀 모델을 데이터프레임 없이 넘파이 어레이만을 활용하여 훈련시켜보자.

문제 1

data/sc_weir.csv 파일을 np.loadtxt() 또는 np.genfromtxt()를 사용하여 불러와 2차원 넘파이 어레이 sc_weir_arr에 저장하라. 단, 첫 번째 행(헤더)은 데이터에서 제외해야 한다.

답:

np.loadtxt() 함수와 skiprows=1, delimiter=',' 옵션을 사용하여 데이터를 불러올 수 있다.

import numpy as np

# 데이터 로딩
data_path = 'data/sc_weir.csv'
sc_weir_arr = np.loadtxt(data_path, delimiter=',', skiprows=1)
sc_weir_arr[:5]
array([[51., 25.], [51., 25.], [53., 24.], [53., 24.], [54., 22.]])

방류량과 클로로필-A 두 개의 특성으로 구성된 데이터 샘플 100개로 구성된 데이터셋을 훈련셋으로 사용한다.

sc_weir_arr.shape
(100, 2)

문제 2

sc_weir_arr에서 훈련을 위한 입력 데이터셋 X와 타깃셋 y를 지정하라.

  • X: 인덱스가 1인 열 (Discharge, 방류량), 사이킷런 선형회귀 모델에 맞춰 2차원 배열 형태로 지정해야 한다.

  • y: 인덱스가 0인 열 (Chl-a, 클로로필-A), 1차원 배열 형태로 지정한다.

답:

인덱싱으로 독립변수 X를 추출할 때 모델 입력에 맞춰 [:, 1:2] 와 같이 2차원으로 슬라이싱한다. y[:, 0]으로 1차원 배열로 둔다.

# X: 방류량(2차원 배열), y: Chl-a(1차원 배열)
X = sc_weir_arr[:, 1:2]
y = sc_weir_arr[:, 0]

print(f"X shape: {X.shape}, y shape: {y.shape}")
X shape: (100, 1), y shape: (100,)

문제 3

scikit-learnLinearRegression 모델 객체를 생성하고, 위에서 구한 Xy 데이터를 사용하여 모델을 훈련시켜라.

답:

모델 객체를 생성한 후 fit() 메서드를 호출하여 훈련한다.

from sklearn.linear_model import LinearRegression

# 모델 선택
model = LinearRegression()

# 모델 훈련
model.fit(X, y)
Loading...

문제 4

만약 방류량이 30.5인 경우, 훈련된 모델을 이용하여 클로로필-A 수치를 예측하라.

답:

predict() 메서드에 넘겨주는 입력 데이터도 반드시 모델이 훈련받았던 데이터 형태인 2차원 어레이로 지정해야 한다.

# 새로운 샘플 인스턴스 (2차원 배열)
X_new = np.array([[30.5]])

# 모델 예측
y_predicted = model.predict(X_new)

print("예측된 클로로필-A 수치:", y_predicted[0])
예측된 클로로필-A 수치: 68.26636150834923