본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 17. · 6 Views
Scikit-learn 시작하기 완벽 가이드
머신러닝 입문자를 위한 Scikit-learn 기초 가이드입니다. 설치부터 데이터 분리, train_test_split 활용까지 실무에 필요한 핵심 개념을 이북처럼 술술 읽히는 스타일로 배워봅니다.
목차
- Scikit-learn 소개
- sklearn 설치 및 임포트
- train_test_split() 사용법
- 학습/테스트 데이터 분리
- 분리 비율 설정
- random_state 의미
- stratify 옵션 활용
1. Scikit-learn 소개
김개발 씨는 데이터 분석팀으로 이제 막 발령받은 신입 개발자입니다. "머신러닝을 배워야 한다는데, 어디서부터 시작해야 할까요?" 선배 박시니어 씨가 웃으며 답합니다.
"Scikit-learn부터 시작하면 됩니다."
Scikit-learn은 파이썬에서 가장 많이 사용되는 머신러닝 라이브러리입니다. 마치 요리를 할 때 필요한 기본 도구가 담긴 조리 도구 세트와 같습니다.
분류, 회귀, 클러스터링 등 다양한 머신러닝 알고리즘을 간단한 코드 몇 줄로 사용할 수 있습니다.
다음 코드를 살펴봅시다.
# Scikit-learn으로 간단한 머신러닝 시작하기
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
# 붓꽃 데이터 로드
iris = load_iris()
X, y = iris.data, iris.target
# 모델 생성 및 학습
model = DecisionTreeClassifier()
model.fit(X, y)
# 예측 수행
predictions = model.predict(X[:5])
print(f"예측 결과: {predictions}")
김개발 씨는 입사 첫날부터 막막했습니다. 대학에서 파이썬은 배웠지만, 머신러닝은 이론으로만 들었을 뿐 실제로 코드를 작성해본 적이 없었기 때문입니다.
선배 박시니어 씨가 커피를 한 잔 건네며 말했습니다. "걱정하지 마세요.
저도 처음엔 그랬어요. Scikit-learn만 제대로 익히면 금방 따라잡을 수 있습니다." 그렇다면 Scikit-learn이란 정확히 무엇일까요?
쉽게 비유하자면, Scikit-learn은 마치 자동차 공장의 자동화 시스템과 같습니다. 과거에는 자동차를 만들기 위해 하나하나 수작업으로 조립해야 했지만, 자동화 시스템을 갖추면 버튼 몇 번으로 완성차가 나옵니다.
이처럼 Scikit-learn도 복잡한 머신러닝 알고리즘을 간단한 코드로 실행할 수 있게 해줍니다. Scikit-learn이 없던 시절에는 어땠을까요?
개발자들은 머신러닝 알고리즘을 직접 구현해야 했습니다. 선형 회귀 하나를 만들기 위해 수백 줄의 수학 공식을 코드로 옮겨야 했습니다.
더 큰 문제는 버그를 찾기도 어렵고, 성능 최적화도 직접 해야 한다는 점이었습니다. 프로젝트가 커질수록 이런 문제는 눈덩이처럼 불어났습니다.
바로 이런 문제를 해결하기 위해 Scikit-learn이 등장했습니다. Scikit-learn을 사용하면 검증된 알고리즘을 즉시 사용할 수 있습니다.
또한 일관된 인터페이스 덕분에 알고리즘을 바꾸는 것도 쉽습니다. 무엇보다 방대한 문서와 커뮤니티 지원이라는 큰 이점이 있습니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 import 부분을 보면 필요한 모듈을 가져오는 것을 알 수 있습니다.
load_iris()는 실습용 붓꽃 데이터셋을 로드합니다. 이 부분이 핵심입니다.
다음으로 DecisionTreeClassifier()로 모델을 생성하고, fit() 메서드로 학습을 진행합니다. 마지막으로 predict()를 통해 예측 결과가 반환됩니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 온라인 쇼핑몰에서 고객 이탈을 예측하는 시스템을 개발한다고 가정해봅시다.
고객의 구매 이력, 방문 빈도, 클릭 패턴 등의 데이터를 Scikit-learn으로 분석하면 "이 고객이 다음 달에 이탈할 확률"을 예측할 수 있습니다. 많은 기업에서 이런 패턴을 적극적으로 사용하고 있습니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 Scikit-learn이 만능이라고 생각하는 것입니다.
딥러닝이나 대규모 데이터 처리에는 TensorFlow나 PyTorch가 더 적합할 수 있습니다. 따라서 프로젝트 특성에 맞는 도구를 선택해야 합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.
"아, 생각보다 어렵지 않네요!" Scikit-learn을 제대로 이해하면 머신러닝의 세계로 쉽게 입문할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - Scikit-learn 공식 문서는 예제가 풍부하니 적극 활용하세요
- 처음엔 내장된 데이터셋(iris, digits 등)으로 연습하는 것이 좋습니다
- fit(), predict(), score() 세 가지 메서드만 알아도 기본은 합니다
2. sklearn 설치 및 임포트
"그런데 선배님, Scikit-learn을 어떻게 설치하나요?" 김개발 씨가 노트북을 열며 물었습니다. 박시니어 씨가 터미널을 열어주며 답합니다.
"pip 한 줄이면 끝나요. 정말 간단합니다."
Scikit-learn 설치는 pip 패키지 매니저를 통해 이루어집니다. 마치 스마트폰에서 앱을 다운받는 것처럼 간단합니다.
설치 후에는 import sklearn 또는 필요한 모듈만 선택적으로 임포트하여 사용할 수 있습니다.
다음 코드를 살펴봅시다.
# 터미널에서 실행: pip install scikit-learn
# 기본 임포트 방법
import sklearn
print(f"Scikit-learn 버전: {sklearn.__version__}")
# 필요한 모듈만 선택적으로 임포트
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
# 데이터셋 로드
from sklearn.datasets import load_wine
wine = load_wine()
print(f"데이터 shape: {wine.data.shape}")
김개발 씨는 설치부터 막혔습니다. "혹시 복잡한 설정이 필요한 건 아닐까?" 하는 걱정이 앞섰습니다.
대학 시절 텐서플로우를 설치하려다가 하루를 꼬박 날린 기억이 떠올랐기 때문입니다. 하지만 박시니어 씨는 여유로운 표정으로 말했습니다.
"Scikit-learn은 정말 쉬워요. 명령어 하나면 끝입니다." 설치 과정은 생각보다 훨씬 간단합니다.
쉽게 비유하자면, Scikit-learn 설치는 마치 편의점에서 즉석 식품을 사는 것과 같습니다. 복잡한 요리 과정 없이 포장만 뜯으면 바로 먹을 수 있습니다.
이처럼 pip 명령어 하나만 입력하면 모든 의존성 패키지가 자동으로 설치됩니다. 설치 전에 확인해야 할 것들이 있을까요?
파이썬 3.7 이상 버전이 설치되어 있는지 확인해야 합니다. 요즘 대부분의 개발 환경에서는 이미 설치되어 있지만, 혹시 모르니 python --version 명령어로 확인하는 것이 좋습니다.
또한 NumPy, SciPy 등의 의존성 패키지도 필요하지만, 이는 Scikit-learn 설치 시 자동으로 함께 설치됩니다. 이제 본격적으로 설치를 진행해봅시다.
터미널을 열고 pip install scikit-learn을 입력합니다. 몇 초에서 몇 분 정도 기다리면 설치가 완료됩니다.
인터넷 속도에 따라 시간이 다를 수 있지만, 대부분 1분 이내에 끝납니다. 설치가 완료되었다면 제대로 설치되었는지 확인해봐야 합니다.
파이썬 인터프리터나 주피터 노트북을 열고 import sklearn을 입력해봅니다. 에러가 발생하지 않는다면 성공입니다.
sklearn.__version__으로 설치된 버전도 확인할 수 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
첫 번째 줄의 주석은 터미널에서 실행할 명령어를 보여줍니다. 이 부분이 실제 설치를 담당합니다.
다음으로 import sklearn으로 전체 패키지를 임포트합니다. 하지만 실무에서는 필요한 모듈만 선택적으로 임포트하는 것이 더 효율적입니다.
마지막으로 load_wine()으로 샘플 데이터를 로드하여 정상 작동을 확인합니다. 실제 현업에서는 어떻게 활용할까요?
프로젝트 초기 단계에서는 보통 가상환경을 만들고 그 안에 Scikit-learn을 설치합니다. 예를 들어 고객 추천 시스템을 개발한다면, python -m venv myenv로 가상환경을 만들고, 그 안에서 필요한 라이브러리들을 설치합니다.
이렇게 하면 프로젝트마다 독립적인 환경을 유지할 수 있습니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 sklearn과 scikit-learn을 헷갈리는 것입니다. 설치할 때는 pip install scikit-learn이지만, 코드에서 임포트할 때는 import sklearn입니다.
이 차이를 기억하지 못해 에러가 발생하는 경우가 많습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
설치를 완료한 김개발 씨는 신기한 표정으로 말했습니다. "정말 1분도 안 걸렸어요!" Scikit-learn 설치는 정말 간단하지만, 가상환경을 사용하는 등 올바른 방법을 익히는 것이 중요합니다.
여러분도 지금 바로 설치해보세요.
실전 팁
💡 - 가상환경(venv, conda)을 사용하여 프로젝트별로 독립적인 환경을 구성하세요
- 설치할 때는 scikit-learn, 임포트할 때는 sklearn입니다
- 주피터 노트북을 사용한다면
!pip install scikit-learn으로 노트북 안에서도 설치 가능합니다
3. train test split() 사용법
첫 머신러닝 모델을 만들어본 김개발 씨는 뿌듯했습니다. 하지만 박시니어 씨가 코드를 보더니 고개를 가로저었습니다.
"이렇게 하면 제대로 된 평가가 안 돼요. train_test_split을 사용해야 합니다."
**train_test_split()**은 데이터를 학습용과 테스트용으로 나누는 함수입니다. 마치 시험 문제를 준비할 때 연습 문제와 실전 문제를 따로 준비하는 것과 같습니다.
이 함수를 사용하면 모델의 실제 성능을 정확하게 평가할 수 있습니다.
다음 코드를 살펴봅시다.
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
# 데이터 로드
iris = load_iris()
X, y = iris.data, iris.target
# 데이터를 학습용과 테스트용으로 분리
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 학습 및 평가
model = DecisionTreeClassifier()
model.fit(X_train, y_train) # 학습 데이터로 학습
score = model.score(X_test, y_test) # 테스트 데이터로 평가
print(f"정확도: {score:.2f}")
김개발 씨는 의아했습니다. 모델을 만들고 정확도도 99%가 나왔는데, 왜 문제라는 걸까요?
박시니어 씨가 화이트보드에 그림을 그리며 설명하기 시작했습니다. "문제집으로 공부한 학생이 같은 문제집으로 시험을 본다면 어떻게 될까요?
당연히 100점이겠죠. 하지만 그게 실력일까요?" train_test_split의 필요성은 바로 여기에 있습니다.
쉽게 비유하자면, train_test_split은 마치 요리사 자격증 시험과 같습니다. 연습할 때는 레시피를 보며 요리를 만들지만, 실제 시험에서는 레시피 없이 요리해야 합니다.
이처럼 모델도 학습할 때 본 데이터와 다른 데이터로 평가해야 진짜 실력을 알 수 있습니다. 데이터를 나누지 않으면 어떤 문제가 생길까요?
모델이 학습 데이터를 그대로 암기해버리는 과적합(overfitting) 문제가 발생합니다. 마치 시험 문제와 답을 통째로 외운 학생처럼, 새로운 데이터가 들어오면 제대로 예측하지 못합니다.
실제 서비스에 적용했을 때 성능이 급격히 떨어지는 이유가 바로 이것입니다. 바로 이런 문제를 해결하기 위해 train_test_split을 사용합니다.
train_test_split을 사용하면 데이터를 자동으로 섞어서 나눠줍니다. 또한 원하는 비율로 손쉽게 분할할 수 있습니다.
무엇보다 같은 결과를 재현할 수 있도록 random_state 설정이 가능하다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 train_test_split() 함수에 X와 y를 전달합니다. 이 부분이 핵심입니다.
test_size=0.2는 전체 데이터의 20%를 테스트용으로 사용한다는 의미입니다. 다음으로 random_state=42는 랜덤 시드를 고정하여 항상 같은 결과를 얻을 수 있게 합니다.
마지막으로 네 개의 변수로 분리된 데이터를 받습니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 신용카드 사기 탐지 시스템을 개발한다고 가정해봅시다. 과거 거래 데이터를 train_test_split으로 나눈 후, 학습 데이터로 모델을 훈련시킵니다.
그리고 테스트 데이터로 "이 모델이 실제로 새로운 사기를 잘 찾아낼까?"를 검증합니다. 금융권에서는 이런 검증 과정을 매우 엄격하게 진행합니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 데이터를 나눈 후 전처리를 하는 것입니다.
정규화나 스케일링은 학습 데이터만 보고 진행해야 하며, 그 기준을 테스트 데이터에 적용해야 합니다. 순서를 바꾸면 **데이터 누수(data leakage)**가 발생하여 잘못된 평가 결과가 나옵니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 설명을 들은 김개발 씨는 자신의 코드를 다시 보며 말했습니다.
"아, 그래서 실제 서비스에서는 잘 안 됐구나!" train_test_split을 제대로 사용하면 신뢰할 수 있는 모델을 만들 수 있습니다. 여러분도 반드시 데이터를 나눠서 평가하는 습관을 들이세요.
실전 팁
💡 - 일반적으로 test_size는 0.2(20%) 또는 0.3(30%)을 사용합니다
- random_state를 고정하면 코드 실행 때마다 같은 결과를 얻을 수 있습니다
- 데이터가 적다면 교차 검증(cross-validation)을 고려하세요
4. 학습/테스트 데이터 분리
"선배님, 그런데 학습 데이터와 테스트 데이터를 왜 꼭 나눠야 하나요?" 김개발 씨가 궁금한 표정으로 물었습니다. 박시니어 씨는 지난주 장애 사고 보고서를 꺼내며 답했습니다.
"바로 이 사고 때문이에요."
학습 데이터와 테스트 데이터의 분리는 머신러닝에서 가장 기본적이면서도 중요한 원칙입니다. 마치 학생이 문제집으로 공부하고 다른 문제로 시험을 보는 것처럼, 모델도 학습한 데이터와 다른 데이터로 평가해야 합니다.
이를 통해 과적합을 방지하고 실제 성능을 정확하게 측정할 수 있습니다.
다음 코드를 살펴봅시다.
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
import numpy as np
# 유방암 데이터 로드
data = load_breast_cancer()
X, y = data.data, data.target
# 학습:테스트 = 80:20으로 분리
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
print(f"전체 데이터: {len(X)}개")
print(f"학습 데이터: {len(X_train)}개 ({len(X_train)/len(X)*100:.1f}%)")
print(f"테스트 데이터: {len(X_test)}개 ({len(X_test)/len(X)*100:.1f}%)")
박시니어 씨가 보여준 보고서에는 충격적인 내용이 적혀 있었습니다. 개발 환경에서는 95% 정확도를 보이던 모델이 실제 서비스에서는 60%밖에 나오지 않았다는 것입니다.
"무슨 일이 있었던 거예요?" 김개발 씨가 놀란 표정으로 물었습니다. 박시니어 씨는 한숨을 쉬며 답했습니다.
"전임자가 데이터를 제대로 나누지 않았어요." 데이터 분리의 중요성은 아무리 강조해도 지나치지 않습니다. 쉽게 비유하자면, 데이터 분리는 마치 운전면허 시험과 같습니다.
학원에서 연습한 코스와 실제 시험 코스가 같다면, 그저 암기만 해도 합격할 수 있습니다. 하지만 실제로 운전을 잘하는지는 알 수 없습니다.
이처럼 모델도 새로운 데이터를 얼마나 잘 처리하는지가 진짜 실력입니다. 데이터를 제대로 나누지 않으면 어떤 일이 벌어질까요?
첫 번째 문제는 과적합입니다. 모델이 학습 데이터의 특성과 노이즈까지 모두 외워버립니다.
두 번째 문제는 성능 과대평가입니다. 개발 단계에서는 좋아 보이지만, 실제 사용자 데이터에는 제대로 작동하지 않습니다.
세 번째 문제는 비즈니스 리스크입니다. 잘못된 예측으로 인해 고객 신뢰를 잃거나 금전적 손실이 발생할 수 있습니다.
올바른 데이터 분리 방법은 무엇일까요? 가장 기본적인 방법은 홀드아웃 방식입니다.
전체 데이터를 학습용과 테스트용으로 한 번 나누는 것입니다. 일반적으로 70:30이나 80:20 비율을 많이 사용합니다.
데이터가 충분히 많다면 이 방법만으로도 충분합니다. 하지만 데이터가 부족하다면 어떻게 해야 할까요?
**교차 검증(cross-validation)**을 사용합니다. 데이터를 여러 조각으로 나눠서, 각 조각을 한 번씩 테스트 데이터로 사용하는 방식입니다.
예를 들어 5-폴드 교차 검증이라면, 데이터를 5등분해서 5번 학습하고 평가합니다. 이렇게 하면 적은 데이터로도 신뢰할 수 있는 평가가 가능합니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 유방암 데이터셋을 로드합니다.
이 데이터는 569개의 샘플로 구성되어 있습니다. train_test_split()으로 데이터를 나누면, 80%인 약 455개는 학습용으로, 20%인 약 114개는 테스트용으로 분리됩니다.
print 문으로 실제 개수를 확인하면 제대로 나뉘었는지 검증할 수 있습니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 이커머스 회사에서 상품 추천 시스템을 개발한다고 가정해봅시다. 지난 6개월간의 구매 데이터를 학습용으로 사용하고, 가장 최근 1개월 데이터를 테스트용으로 사용합니다.
이렇게 하면 "미래의 구매 패턴을 얼마나 잘 예측할까?"를 검증할 수 있습니다. 실제로 많은 기업들이 시간 기반으로 데이터를 나눕니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 테스트 데이터를 학습 과정에서 몰래 사용하는 것입니다.
예를 들어 특성 선택이나 하이퍼파라미터 튜닝을 할 때 테스트 데이터를 보면 안 됩니다. 이렇게 하면 데이터 누수가 발생하여 성능이 부풀려집니다.
테스트 데이터는 정말 마지막 최종 평가에만 사용해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
장애 보고서를 본 김개발 씨는 진지한 표정으로 말했습니다. "이제 왜 그렇게 중요한지 알겠어요." 학습 데이터와 테스트 데이터를 제대로 분리하는 것은 신뢰할 수 있는 머신러닝 모델의 첫걸음입니다.
여러분도 이 원칙을 반드시 지키세요.
실전 팁
💡 - 테스트 데이터는 절대 학습에 사용하지 마세요 (데이터 누수 방지)
- 시계열 데이터는 시간 순서대로 나눠야 합니다 (미래 데이터로 과거를 예측하면 안 됨)
- 검증 데이터(validation set)를 추가로 만들어 하이퍼파라미터 튜닝에 사용하세요
5. 분리 비율 설정
데이터 분리의 중요성을 깨달은 김개발 씨가 다음 질문을 던졌습니다. "그런데 선배님, 학습 데이터와 테스트 데이터를 몇 대 몇으로 나누는 게 좋나요?" 박시니어 씨가 노트북 화면을 보여주며 답합니다.
"상황에 따라 다르지만, 일반적인 가이드라인이 있습니다."
분리 비율은 전체 데이터 중 얼마를 학습에, 얼마를 테스트에 사용할지 결정하는 것입니다. 마치 예산을 배분하는 것처럼, 학습과 평가 사이의 균형을 찾아야 합니다.
일반적으로 70:30, 80:20, 90:10 비율을 많이 사용하며, 데이터의 양과 프로젝트 특성에 따라 조절합니다.
다음 코드를 살펴봅시다.
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
# 샘플 데이터 생성
X, y = make_classification(n_samples=1000, n_features=20, random_state=42)
# 다양한 분리 비율 테스트
test_sizes = [0.1, 0.2, 0.3, 0.4]
for test_size in test_sizes:
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=test_size, random_state=42
)
model = LogisticRegression()
model.fit(X_train, y_train)
score = model.score(X_test, y_test)
print(f"Test size {test_size*100:.0f}% - 학습: {len(X_train)}개, 테스트: {len(X_test)}개, 정확도: {score:.3f}")
박시니어 씨가 보여준 화면에는 여러 프로젝트의 데이터 분리 비율이 정리되어 있었습니다. 어떤 프로젝트는 80:20, 어떤 프로젝트는 90:10을 사용하고 있었습니다.
"이렇게 제각각인데, 어떻게 정하는 건가요?" 김개발 씨가 혼란스러운 표정으로 물었습니다. 박시니어 씨가 차근차근 설명하기 시작했습니다.
분리 비율을 정하는 것은 생각보다 중요한 결정입니다. 쉽게 비유하자면, 분리 비율은 마치 군대에서 병력을 배치하는 것과 같습니다.
훈련소에 너무 많은 병력을 배치하면 실전 부대가 약해지고, 반대로 훈련소 병력이 부족하면 제대로 훈련받지 못한 병사들이 전장에 나가게 됩니다. 이처럼 학습과 테스트의 균형을 잘 맞춰야 합니다.
분리 비율을 잘못 정하면 어떤 문제가 생길까요? 학습 데이터가 너무 적으면 모델이 충분히 학습하지 못합니다.
마치 교과서를 한 페이지만 보고 시험을 보는 것과 같습니다. 반대로 테스트 데이터가 너무 적으면 평가 결과를 신뢰하기 어렵습니다.
동전을 두세 번만 던져서 앞면이 나올 확률을 추정하는 것과 비슷합니다. 그렇다면 어떤 기준으로 비율을 정해야 할까요?
가장 중요한 기준은 전체 데이터의 양입니다. 데이터가 10만 개라면 90:10으로 나눠도 테스트 데이터가 1만 개나 되므로 충분합니다.
하지만 데이터가 100개밖에 없다면 80:20으로 나누면 테스트 데이터가 20개밖에 안 되어 평가가 불안정합니다. 일반적인 가이드라인은 다음과 같습니다.
데이터가 1만 개 이상이라면 80:20이나 90:10을 사용합니다. 데이터가 1천 개 정도라면 70:30이나 80:20이 적절합니다.
데이터가 수백 개밖에 없다면 단순 분리보다는 5-폴드나 10-폴드 교차 검증을 사용하는 것이 좋습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 make_classification()으로 1000개의 샘플 데이터를 생성합니다. 이 부분이 실험 환경을 만듭니다.
다음으로 for 문으로 여러 분리 비율을 테스트합니다. 각 비율마다 모델을 학습하고 정확도를 측정하여, 어떤 비율이 가장 적절한지 확인할 수 있습니다.
마지막으로 결과를 출력하여 비교합니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 스타트업에서 새로운 서비스를 시작할 때, 초기에는 데이터가 적습니다. 이때는 70:30 비율로 나누고 교차 검증을 함께 사용합니다.
시간이 지나 데이터가 수만 개로 쌓이면, 90:10으로 바꿔서 더 많은 데이터로 학습시킵니다. 실제로 많은 기업들이 데이터 규모에 따라 비율을 조정합니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 무조건 80:20을 고집하는 것입니다.
책이나 강의에서 80:20을 많이 사용한다고 해서, 모든 상황에 적용하면 안 됩니다. 데이터 규모, 클래스 불균형, 시간 제약 등을 고려하여 프로젝트에 맞는 비율을 선택해야 합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 설명을 들은 김개발 씨는 고개를 끄덕이며 말했습니다.
"그럼 우리 프로젝트는 데이터가 5000개 정도니까 80:20이 적당하겠네요!" 분리 비율은 고정된 답이 없습니다. 상황에 맞게 판단하는 것이 중요합니다.
여러분도 프로젝트 특성을 고려하여 적절한 비율을 선택하세요.
실전 팁
💡 - 데이터가 많을수록 테스트 비율을 줄여도 됩니다 (90:10, 95:5도 가능)
- 데이터가 적다면 교차 검증으로 보완하세요
- 실무에서는 학습:검증:테스트 = 60:20:20으로 3분할하는 경우도 많습니다
6. random state 의미
김개발 씨가 같은 코드를 두 번 실행했는데 결과가 달랐습니다. "이상하네, 왜 정확도가 계속 바뀌죠?" 박시니어 씨가 코드를 보더니 바로 원인을 찾았습니다.
"random_state를 설정하지 않았네요."
random_state는 데이터를 섞을 때 사용하는 랜덤 시드입니다. 마치 주사위를 던지기 전에 시작 위치를 정해두는 것과 같습니다.
이 값을 고정하면 코드를 여러 번 실행해도 항상 같은 결과를 얻을 수 있어, 실험의 재현성을 보장합니다.
다음 코드를 살펴봅시다.
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
iris = load_iris()
X, y = iris.data, iris.target
# random_state를 고정하지 않은 경우
print("random_state 미설정:")
for i in range(3):
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
model = DecisionTreeClassifier()
model.fit(X_train, y_train)
print(f" 실행 {i+1}: 정확도 {model.score(X_test, y_test):.3f}")
# random_state를 고정한 경우
print("\nrandom_state=42 설정:")
for i in range(3):
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = DecisionTreeClassifier(random_state=42)
model.fit(X_train, y_train)
print(f" 실행 {i+1}: 정확도 {model.score(X_test, y_test):.3f}")
김개발 씨는 당황했습니다. 어제 만든 모델의 정확도가 93%였는데, 오늘 다시 실행하니 89%가 나왔습니다.
"코드는 하나도 안 바꿨는데 왜 이러죠?" 박시니어 씨가 웃으며 답했습니다. "랜덤성 때문이에요.
train_test_split이 데이터를 무작위로 섞거든요." random_state는 재현성을 보장하는 핵심 도구입니다. 쉽게 비유하자면, random_state는 마치 네비게이션의 출발 지점과 같습니다.
같은 출발점에서 같은 경로를 따라가면 항상 같은 목적지에 도착합니다. 하지만 출발점이 매번 바뀐다면, 같은 경로를 따라가도 다른 곳에 도착할 수 있습니다.
이처럼 random_state를 고정하면 항상 같은 방식으로 데이터가 섞입니다. random_state를 설정하지 않으면 어떤 문제가 생길까요?
첫 번째 문제는 재현 불가능입니다. 어제 좋은 결과가 나왔어도 오늘 다시 실행하면 다른 결과가 나옵니다.
두 번째 문제는 디버깅 어려움입니다. 버그를 찾으려고 해도 매번 결과가 달라서 원인을 특정하기 힘듭니다.
세 번째 문제는 협업 곤란입니다. 같은 코드를 팀원이 실행해도 다른 결과가 나와 혼란이 생깁니다.
그렇다면 random_state는 어떤 값을 사용해야 할까요? 사실 값 자체는 중요하지 않습니다.
0을 써도 되고, 42를 써도 되고, 123을 써도 됩니다. 중요한 것은 고정하는 것입니다.
머신러닝 커뮤니티에서는 관례적으로 42를 많이 사용합니다. 이는 "은하수를 여행하는 히치하이커를 위한 안내서"라는 소설에서 유래한 것으로, 특별한 의미는 없지만 많은 개발자들이 사용하고 있습니다.
random_state는 어디에 설정해야 할까요? train_test_split뿐만 아니라 많은 머신러닝 알고리즘도 랜덤성을 사용합니다.
DecisionTreeClassifier, RandomForestClassifier 등도 random_state 파라미터를 가지고 있습니다. 완벽한 재현성을 위해서는 이런 모든 곳에 random_state를 설정해야 합니다.
위의 코드를 한 줄씩 살펴보겠습니다. 첫 번째 for 문에서는 random_state를 설정하지 않습니다.
이 부분이 매번 다른 결과를 만듭니다. 세 번 실행하면 정확도가 다르게 나타납니다.
두 번째 for 문에서는 random_state=42를 설정합니다. 다음으로 모델에도 random_state를 설정합니다.
마지막으로 세 번 실행해도 항상 같은 정확도가 나타납니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 팀 프로젝트에서 여러 명이 같은 모델을 개선한다고 가정해봅시다. A 개발자가 92% 정확도를 달성했다고 보고하면, B 개발자가 같은 코드로 재현할 수 있어야 합니다.
random_state를 고정하면 "정말 개선된 건지, 운이 좋았던 건지"를 명확히 판단할 수 있습니다. 실제로 많은 기업에서 코드 리뷰 시 random_state 설정을 필수로 요구합니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 random_state에 지나치게 의존하는 것입니다.
특정 random_state에서만 좋은 성능이 나온다면, 그것은 우연일 가능성이 높습니다. 따라서 최종 평가에서는 여러 random_state 값으로 테스트하여 안정성을 확인해야 합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. random_state를 42로 설정한 김개발 씨는 안도의 표정을 지었습니다.
"이제 코드가 안정적이네요!" random_state를 설정하는 것은 작은 습관이지만, 재현 가능한 머신러닝을 위해 반드시 필요합니다. 여러분도 항상 random_state를 설정하는 습관을 들이세요.
실전 팁
💡 - 관례적으로 random_state=42를 많이 사용합니다
- 모든 랜덤 과정(데이터 분리, 모델 학습 등)에 일관되게 설정하세요
- 최종 평가 시에는 여러 random_state로 테스트하여 안정성을 확인하세요
7. stratify 옵션 활용
모델을 돌려본 김개발 씨가 이상한 점을 발견했습니다. "선배님, 테스트 데이터에 특정 클래스가 너무 적게 들어갔어요." 박시니어 씨가 고개를 끄덕이며 답합니다.
"그럴 땐 stratify 옵션을 사용하면 됩니다."
stratify 옵션은 데이터를 나눌 때 각 클래스의 비율을 유지하는 기능입니다. 마치 설문조사에서 남녀 비율을 맞춰서 표본을 추출하는 것과 같습니다.
특히 클래스 불균형이 있는 데이터에서 필수적으로 사용해야 하는 옵션입니다.
다음 코드를 살펴봅시다.
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
import numpy as np
# 와인 데이터 로드 (3개 클래스)
wine = load_wine()
X, y = wine.data, wine.target
print("전체 데이터의 클래스 분포:")
unique, counts = np.unique(y, return_counts=True)
for cls, count in zip(unique, counts):
print(f" 클래스 {cls}: {count}개 ({count/len(y)*100:.1f}%)")
# stratify 없이 분리
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
print("\nstratify 없이 분리한 테스트 데이터:")
unique, counts = np.unique(y_test, return_counts=True)
for cls, count in zip(unique, counts):
print(f" 클래스 {cls}: {count}개 ({count/len(y_test)*100:.1f}%)")
# stratify 사용하여 분리
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42, stratify=y
)
print("\nstratify=y로 분리한 테스트 데이터:")
unique, counts = np.unique(y_test, return_counts=True)
for cls, count in zip(unique, counts):
print(f" 클래스 {cls}: {count}개 ({count/len(y_test)*100:.1f}%)")
김개발 씨가 만든 이탈 고객 예측 모델은 겉보기엔 좋았습니다. 정확도가 95%나 나왔기 때문입니다.
하지만 박시니어 씨가 자세히 들여다보니 문제가 있었습니다. "테스트 데이터를 보세요.
이탈 고객이 단 2명밖에 없네요." 박시니어 씨가 화면을 가리키며 말했습니다. "이렇게는 제대로 평가할 수 없어요." stratify 옵션의 필요성은 바로 이런 상황에서 드러납니다.
쉽게 비유하자면, stratify는 마치 케이크를 자를 때 각 조각에 딸기가 골고루 들어가게 하는 것과 같습니다. 딸기가 위쪽에만 몰려 있다면, 그냥 자르면 어떤 조각에는 딸기가 많고 어떤 조각에는 없을 수 있습니다.
stratify를 사용하면 각 조각에 딸기가 비슷하게 분배됩니다. stratify를 사용하지 않으면 어떤 문제가 생길까요?
특히 클래스 불균형 상황에서 심각합니다. 예를 들어 정상 거래가 95%, 사기 거래가 5%인 데이터를 무작위로 나누면, 운이 나쁠 경우 테스트 데이터에 사기 거래가 하나도 없을 수 있습니다.
그러면 사기 탐지 성능을 전혀 평가할 수 없습니다. 또한 학습 데이터와 테스트 데이터의 분포가 달라져서 잘못된 결론을 내릴 수 있습니다.
stratify는 어떻게 작동할까요? train_test_split에 stratify=y 파라미터를 추가하면, 각 클래스의 비율을 계산하여 학습 데이터와 테스트 데이터에 같은 비율로 분배합니다.
예를 들어 전체 데이터에서 클래스 A가 60%, B가 30%, C가 10%라면, 학습 데이터와 테스트 데이터 모두에서 같은 비율을 유지합니다. 언제 stratify를 사용해야 할까요?
분류 문제에서는 기본적으로 사용하는 것이 좋습니다. 특히 클래스 불균형이 있다면 필수입니다.
하지만 회귀 문제에서는 stratify를 사용할 수 없습니다. 타겟 값이 연속적이기 때문입니다.
또한 데이터가 매우 많고 균형이 잘 잡혀 있다면, stratify 없이도 큰 문제는 없습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 와인 데이터셋을 로드합니다. 이 데이터는 3개 클래스로 구성되어 있으며, 각 클래스의 개수가 다릅니다.
np.unique()로 각 클래스의 개수를 확인합니다. 이 부분이 전체 분포를 보여줍니다.
다음으로 stratify 없이 분리하면 비율이 조금 달라질 수 있습니다. 마지막으로 stratify=y를 사용하면 원본과 같은 비율로 정확하게 분리됩니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 질병 진단 모델을 개발한다고 가정해봅시다.
건강한 사람이 90%, 환자가 10%인 데이터에서 stratify를 사용하지 않으면, 테스트 데이터에 환자가 너무 적게 들어갈 수 있습니다. 그러면 "환자를 얼마나 잘 찾아내는가"를 제대로 평가할 수 없습니다.
의료 분야에서는 이런 평가가 생명과 직결되므로, stratify를 반드시 사용합니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 stratify를 맹목적으로 사용하는 것입니다. 시계열 데이터처럼 시간 순서가 중요한 경우, stratify를 사용하면 미래 데이터로 과거를 예측하는 문제가 생길 수 있습니다.
이런 경우에는 시간 순서대로 나눠야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
stratify를 적용한 김개발 씨는 결과를 보며 감탄했습니다. "이제 모든 클래스가 골고루 들어갔네요!" stratify 옵션은 작은 파라미터 하나지만, 공정한 평가를 위해 매우 중요합니다.
여러분도 분류 문제에서는 항상 stratify를 고려하세요.
실전 팁
💡 - 분류 문제에서는 기본적으로 stratify=y를 사용하세요
- 클래스가 극단적으로 불균형하다면 반드시 사용해야 합니다
- 시계열 데이터에서는 stratify보다 시간 순서 분리가 우선입니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Helm 마이크로서비스 패키징 완벽 가이드
Kubernetes 환경에서 마이크로서비스를 효율적으로 패키징하고 배포하는 Helm의 핵심 기능을 실무 중심으로 학습합니다. Chart 생성부터 릴리스 관리까지 체계적으로 다룹니다.
보안 아키텍처 구성 완벽 가이드
프로젝트의 보안을 처음부터 설계하는 방법을 배웁니다. AWS 환경에서 VPC부터 WAF, 암호화, 접근 제어까지 실무에서 바로 적용할 수 있는 보안 아키텍처를 단계별로 구성해봅니다.
AWS Organizations 완벽 가이드
여러 AWS 계정을 체계적으로 관리하고 통합 결제와 보안 정책을 적용하는 방법을 실무 스토리로 쉽게 배워봅니다. 초보 개발자도 바로 이해할 수 있는 친절한 설명과 실전 예제를 제공합니다.
AWS KMS 암호화 완벽 가이드
AWS KMS(Key Management Service)를 활용한 클라우드 데이터 암호화 방법을 초급 개발자를 위해 쉽게 설명합니다. CMK 생성부터 S3, EBS 암호화, 봉투 암호화까지 실무에 필요한 모든 내용을 담았습니다.
AWS Secrets Manager 완벽 가이드
AWS에서 데이터베이스 비밀번호, API 키 등 민감한 정보를 안전하게 관리하는 Secrets Manager의 핵심 개념과 실무 활용법을 배워봅니다. 초급 개발자도 쉽게 따라할 수 있도록 실전 예제와 함께 설명합니다.