[혼공머신] 1주차: AI 입문과 데이터 전처리 실습 후기

‘혼자 공부하는 머신러닝 + 딥러닝 개정판’ 스터디 1주차 학습을 마쳤습니다.
이번 1주차 학습은 교재의 Chapter 01 ‘나의 첫 머신러닝’과 Chapter 02 ‘데이터 다루기’를 중심으로 진행되었습니다. 기초 개념부터 실제 코드 실습까지, 머신러닝의 핵심 원리를 차근차근 익히는 유익한 시간이었습니다.
Chapter 01. 나의 첫 머신러닝
첫 챕터에서는 인공지능, 머신러닝, 딥러닝의 기본 개념을 이해하고, 실제 머신러닝 프로그램을 구현하는 과정을 실습했습니다.
기본 개념 및 실습 환경
인공지능(AI), 머신러닝(Machine Learning), 딥러닝(Deep Learning)의 정의와 관계를 학습했습니다. 구글 코랩(Google Colab)을 활용하여 별도 설치 없이 웹에서 코딩 및 실습 환경을 구축할 수 있어 편리했습니다.
첫 머신러닝 구현: 생선 분류 문제
도미와 빙어 데이터를 활용하여 머신러닝 모델이 두 생선을 어떻게 구분하는지 실습했습니다.
먼저, 두 생선의 길이와 무게 데이터를 시각화했습니다.
import matplotlib.pyplot as plt
# 도미 데이터
bream_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 30.0, 30.7, 31.0, 31.0,
31.5, 32.0, 32.0, 32.0, 33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0,
35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 39.5, 41.0, 41.0]
bream_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 390.0, 450.0, 500.0, 475.0, 500.0,
500.0, 340.0, 600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 685.0, 620.0, 680.0,
700.0, 725.0, 720.0, 714.0, 850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0]
# 빙어 데이터
smelt_length = [9.8, 10.5, 10.6, 11.0, 11.2, 11.3, 11.8, 11.8, 12.0, 12.2, 12.4, 13.0, 14.3, 15.0]
smelt_weight = [6.7, 7.5, 7.0, 9.7, 9.8, 8.7, 10.0, 9.9, 9.8, 12.2, 13.4, 12.2, 19.7, 19.9]
# 두 생선 데이터 시각화
plt.scatter(bream_length, bream_weight)
plt.scatter(smelt_length, smelt_weight)
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
시각화 결과, 도미와 빙어의 분포가 명확히 구분됨을 확인했습니다.
이 데이터를 KNeighborsClassifier
모델에 넣어 학습시켰습니다.
from sklearn.neighbors import KNeighborsClassifier
length = bream_length + smelt_length
weight = bream_weight + smelt_weight
fish_data = [[l, w] for l, w in zip(length, weight)]
fish_target = [1] * 35 + [0] * 14
kn = KNeighborsClassifier()
kn.fit(fish_data, fish_target)
print(kn.score(fish_data, fish_target))
모델은 100% 정확도로 생선을 분류했습니다. 새로운 생선(길이 30cm, 무게 600g)에 대한 예측도 시도했습니다.
print(kn.predict([[30, 600]]))
예측 결과는 도미였습니다. 다만, n_neighbors
하이퍼파라미터를 너무 크게 설정하면 정확도가 낮아질 수 있음을 확인하며, 모델 설정의 중요성을 깨달았습니다.
Chapter 02. 데이터 다루기
두 번째 챕터에서는 머신러닝 모델 성능에 결정적인 영향을 미치는 데이터의 중요성을 깊이 있게 다루었습니다.
훈련 세트와 테스트 세트 분리
모델의 일반화 성능을 평가하기 위해 데이터를 훈련 세트와 테스트 세트로 분리하는 과정이 필수적입니다. NumPy
와 train_test_split
함수를 사용하여 데이터를 준비하고 분리했습니다. stratify
옵션을 통해 클래스 비율을 유지하며 무작위로 분리하여 샘플링 편향을 방지했습니다.
import numpy as np
from sklearn.model_selection import train_test_split
fish_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 30.0, 30.7, 31.0, 31.0,
31.5, 32.0, 32.0, 32.0, 33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0,
35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 39.5, 41.0, 41.0, 9.8,
10.5, 10.6, 11.0, 11.2, 11.3, 11.8, 11.8, 12.0, 12.2, 12.4, 13.0, 14.3, 15.0]
fish_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 390.0, 450.0, 500.0, 475.0, 500.0,
500.0, 340.0, 600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 685.0, 620.0, 680.0,
700.0, 725.0, 720.0, 714.0, 850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0, 6.7,
7.5, 7.0, 9.7, 9.8, 8.7, 10.0, 9.9, 9.8, 12.2, 13.4, 12.2, 19.7, 19.9]
fish_data = np.column_stack((fish_length, fish_weight))
fish_target = np.concatenate((np.ones(35), np.zeros(14)))
train_input, test_input, train_target, test_target = train_test_split(
fish_data, fish_target, stratify=fish_target, random_state=42)
print(train_input.shape, test_input.shape)
kn = KNeighborsClassifier()
kn.fit(train_input, train_target)
print(kn.score(test_input, test_target))
이 과정을 통해 모델이 편향되지 않게 학습하고 평가될 수 있음을 확인했습니다.
데이터 전처리: 스케일의 중요성
데이터 전처리의 필요성을 실감했습니다. 특히 특성 간의 스케일 차이가 모델 성능에 미치는 영향을 탐구했습니다. 길이 25cm, 무게 150g인 새로운 생선 예측 시, K-최근접 이웃 모델은 이를 도미로 잘못 예측했습니다. 이는 길이(cm)와 무게(g)의 스케일 차이가 커서 무게 특성이 거리 계산에 지배적인 영향을 미쳤기 때문입니다.
이 문제를 해결하기 위해 특성 스케일링(Feature Scaling), 특히 표준화(Standardization)를 적용했습니다. 표준화는 각 특성의 평균을 0, 표준편차를 1로 조정하여 모든 특성이 동일한 스케일을 갖게 합니다.
# 훈련 세트 표준화
mean = np.mean(train_input, axis=0)
std = np.std(train_input, axis=0)
train_scaled = (train_input - mean) / std
# 새로운 데이터 및 테스트 세트도 동일하게 표준화
new_scaled = ([25, 150] - mean) / std
test_scaled = (test_input - mean) / std
# 표준화된 데이터로 모델 재훈련 및 평가
kn.fit(train_scaled, train_target)
print(f"표준화된 데이터로 학습 후 테스트 세트 정확도: {kn.score(test_scaled, test_target)}")
print(f"표준화된 새로운 데이터 예측 결과: {kn.predict([new_scaled])}") # 출력: array([0]) (빙어)
표준화를 적용하자 모델은 새로운 생선을 정확하게 빙어(0)로 예측했습니다. 이는 데이터 전처리가 머신러닝 모델의 성능과 예측 정확도에 얼마나 중요한 영향을 미치는지 명확하게 보여주었습니다.
1주차를 마치며
‘혼자 공부하는 머신러닝 + 딥러닝 개정판’ 1주차 학습을 통해 인공지능의 기본 개념부터 모델 구축, 평가, 그리고 데이터의 중요성 및 전처리 방법에 이르기까지 폭넓은 지식을 습득했습니다. 이론 학습과 실습 코드를 병행하며 머신러닝의 핵심 원리를 효과적으로 이해할 수 있었습니다.
기본 숙제(필수): 코랩 실습 화면 캡처하기

추가 숙제(선택): Ch.02(02-1) 확인 문제(p.90) 풀고, 설명하기
1. 머신러닝 알고리즘의 한 종류로서 샘플의 입력과 타깃(정답)을 알고 있을 때 사용할 수 있는 학습 방법은 무엇인가요.
① 지도 학습
② 비지도 학습
③ 차원 축소
④ 강화 학습
- 정답 : 1. 지도학습 (교재 71p. 지도 학습은 정답(타깃)이 있으니 알고리즘이 정답을 맞히는 것을 학습합니다.
2. 훈련 세트와 베스트 세트가 잘못 만들어져 전체 데이터를 대표하지 못하는 현상을 무엇이라고 부르나요?
① 샘플링 오류
② 샘플링 실수
③ 샘플링 편차
④ 샘플링 편향
- 정답 : 4. 샘플링 편향 (77p. 일반적으로 훈련 세트와 테스트 세트에 샘플이 골고루 섞여 있지 않으면 샘플링이 한쪽으로 치우쳤다는 의미로 샘플링 편향 이라고 부릅니다.
3. 사이킷런은 입력 데이터(배열)가 어떻게 구성되어 있을 것으로 기대하나요?
① 행 : 특성, 열 : 샘플
② 행 : 샘플, 열 : 특성
③ 행 : 특성, 열 : 타깃
④ 행 : 타깃, 열 : 특성
- 정답 : 2. 행 : 샘플, 열 : 특성 (79p. 49개의 행(샘플)과 2개의 열(특성)을 쉽게 확인할 수 있습니다.)
4. 다음 중 배열 arr에서 두 번째 원소에서부터 다섯 원째 원소까지 선택하기 위해 올바르게 슬라이싱 연산자를 사용한 것은 무엇인가요?
① arr[2:5]
② arr[2:6]
③ arr[1:5]
④ arr[1:6]
- 정답 : 3 (74p. 인덱스 0부터 시작하고 마지막 인덱스 원소는 포함하지 않는다.)