본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 17. · 5 Views
타이타닉 생존 예측 모델 완성 프로젝트
머신러닝 입문자를 위한 타이타닉 생존 예측 프로젝트입니다. 데이터 로드부터 EDA, 피처 엔지니어링, 모델 학습, 평가까지 실전 머신러닝 파이프라인을 단계별로 경험할 수 있습니다.
목차
1. 프로젝트 목표 설정
데이터 분석가 김데이터 씨는 오늘 처음으로 머신러닝 프로젝트를 시작하게 되었습니다. 선배 박머신 씨가 "타이타닉 데이터로 한번 생존 예측 모델을 만들어볼까요?"라고 제안했습니다.
어디서부터 시작해야 할까요?
머신러닝 프로젝트는 명확한 목표 설정부터 시작됩니다. 타이타닉 생존 예측은 승객의 특성을 바탕으로 생존 여부를 예측하는 이진 분류 문제입니다.
마치 의사가 환자의 증상을 보고 병을 진단하는 것처럼, 우리 모델도 데이터를 보고 생존 가능성을 판단합니다.
다음 코드를 살펴봅시다.
# 프로젝트 목표: 타이타닉 승객의 생존 여부 예측
# 문제 유형: 이진 분류 (Binary Classification)
# 평가 지표: 정확도 (Accuracy)
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report
# 목표 설정
TARGET = 'Survived' # 예측할 타겟 변수
TEST_SIZE = 0.2 # 테스트 데이터 비율
RANDOM_STATE = 42 # 재현성을 위한 랜덤 시드
print(f"프로젝트 목표: {TARGET} 예측")
print(f"테스트 데이터 비율: {TEST_SIZE * 100}%")
김데이터 씨는 신입 데이터 분석가입니다. 오늘 아침, 팀 리더 박머신 씨가 흥미로운 제안을 했습니다.
"캐글의 타이타닉 데이터셋으로 첫 머신러닝 프로젝트를 시작해보는 게 어때요?" 김데이터 씨는 약간 긴장했습니다. 머신러닝이라니, 어렵게만 느껴졌기 때문입니다.
하지만 박머신 씨는 웃으며 말했습니다. "걱정 마세요.
단계별로 차근차근 진행하면 됩니다. 가장 먼저 할 일은 목표를 명확히 하는 거예요." 그렇다면 프로젝트의 목표란 무엇일까요?
머신러닝 프로젝트의 목표 설정은 마치 여행을 떠나기 전에 목적지를 정하는 것과 같습니다. 서울에서 부산으로 가고 싶은지, 제주도로 가고 싶은지 정해야 어떤 교통수단을 선택할지 결정할 수 있습니다.
마찬가지로 우리가 무엇을 예측하고 싶은지 명확히 해야 어떤 모델을 사용할지, 어떻게 데이터를 준비할지 결정할 수 있습니다. 목표가 없던 시절에는 어땠을까요?
예전에는 많은 초보 데이터 분석가들이 데이터를 받자마자 무작정 코드를 작성하기 시작했습니다. 이것저것 시도하다 보면 길을 잃기 일쑤였습니다.
더 큰 문제는 프로젝트가 끝나고 나서야 "아, 이게 아니었는데"라고 깨닫는 경우가 많았다는 것입니다. 시간과 노력이 낭비되는 것은 물론이고, 팀원들과의 소통에도 문제가 생겼습니다.
바로 이런 문제를 해결하기 위해 명확한 목표 설정이 중요합니다. 타이타닉 프로젝트의 목표는 간단합니다.
승객의 특성을 보고 그 사람이 살아남았는지 예측하는 것입니다. 이것은 이진 분류 문제라고 부릅니다.
결과가 두 가지 중 하나이기 때문입니다. 생존했거나, 생존하지 못했거나.
목표를 정했다면 다음으로 할 일은 무엇일까요? 우리는 평가 지표도 함께 정해야 합니다.
평가 지표는 우리 모델이 얼마나 잘 작동하는지 측정하는 기준입니다. 타이타닉 프로젝트에서는 보통 정확도를 사용합니다.
전체 예측 중에서 맞춘 비율을 의미합니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 필요한 라이브러리를 불러옵니다. pandas는 데이터를 다루기 위해, numpy는 수치 계산을 위해, sklearn은 머신러닝 모델을 위해 필요합니다.
그다음 TARGET 변수에 'Survived'를 저장합니다. 이것이 우리가 예측하고 싶은 목표 변수입니다.
TEST_SIZE는 전체 데이터 중 20%를 테스트용으로 사용하겠다는 의미이고, RANDOM_STATE는 같은 결과를 재현하기 위한 시드값입니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 은행에서 대출 승인 시스템을 개발한다고 가정해봅시다. 목표는 "이 고객이 대출금을 제때 상환할 것인가?"입니다.
이것도 이진 분류 문제입니다. 프로젝트 시작 전에 이런 목표를 명확히 정의하면, 어떤 데이터를 수집해야 하는지, 어떤 모델을 사용해야 하는지가 자연스럽게 결정됩니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 목표를 너무 모호하게 설정하는 것입니다.
"데이터를 분석한다"는 것은 목표가 아닙니다. "승객의 생존 여부를 80% 이상의 정확도로 예측한다"처럼 구체적이고 측정 가능한 목표를 설정해야 합니다.
다시 김데이터 씨의 이야기로 돌아가 봅시다. 박머신 씨의 설명을 들은 김데이터 씨는 노트에 목표를 또박또박 적었습니다.
"타이타닉 승객 생존 예측, 이진 분류, 정확도 측정." 명확한 목표는 프로젝트의 나침반입니다. 앞으로 진행할 모든 단계가 이 목표를 향해 나아갈 것입니다.
여러분도 머신러닝 프로젝트를 시작할 때는 항상 목표부터 명확히 정의해 보세요.
실전 팁
💡 - 목표는 구체적이고 측정 가능하게 설정합니다
- 프로젝트 시작 전에 평가 지표를 미리 정해둡니다
- RANDOM_STATE를 설정하면 같은 결과를 재현할 수 있습니다
2. 데이터 로드 및 EDA
목표를 설정한 김데이터 씨는 이제 실제 데이터를 열어볼 차례입니다. 박머신 씨가 타이타닉 CSV 파일을 건네주며 말했습니다.
"데이터를 모르면 좋은 모델을 만들 수 없어요. 먼저 데이터와 친해지세요."
EDA는 Exploratory Data Analysis의 약자로, 탐색적 데이터 분석을 의미합니다. 마치 새로운 도시에 도착해서 지도를 펼쳐보는 것처럼, 데이터의 구조와 특성을 파악하는 단계입니다.
데이터에 어떤 칼럼이 있는지, 결측치는 없는지, 각 변수의 분포는 어떤지 확인합니다.
다음 코드를 살펴봅시다.
# 데이터 로드
train_df = pd.read_csv('titanic_train.csv')
# 기본 정보 확인
print("데이터 크기:", train_df.shape)
print("\n첫 5행 미리보기:")
print(train_df.head())
# 데이터 타입과 결측치 확인
print("\n데이터 정보:")
print(train_df.info())
# 기술 통계량 확인
print("\n수치형 변수 통계:")
print(train_df.describe())
# 타겟 변수 분포 확인
print("\n생존자 분포:")
print(train_df['Survived'].value_counts())
김데이터 씨는 Jupyter Notebook을 열고 첫 번째 셀에 코드를 입력하기 시작했습니다. 손가락이 떨렸습니다.
드디어 실제 데이터를 보게 되는 순간이었습니다. Enter 키를 누르자 화면에 표가 나타났습니다.
PassengerId, Survived, Pclass, Name, Sex... 여러 칼럼들이 보였습니다.
"와, 이게 진짜 타이타닉 승객 데이터구나!" 그렇다면 EDA란 정확히 무엇일까요? 쉽게 비유하자면, EDA는 마치 요리를 시작하기 전에 냉장고를 열어보는 것과 같습니다.
어떤 재료가 있는지, 신선한지, 얼마나 있는지 확인해야 무엇을 요리할 수 있을지 알 수 있습니다. 마찬가지로 데이터 분석도 데이터가 어떻게 생겼는지, 어떤 특성이 있는지 먼저 파악해야 합니다.
EDA를 하지 않던 시절에는 어땠을까요? 옛날 데이터 분석가들은 데이터를 제대로 살펴보지 않고 곧바로 모델을 만들기 시작했습니다.
그 결과 모델 성능이 이상하게 나오거나, 나중에 데이터에 심각한 문제가 있다는 것을 발견하곤 했습니다. 이미 많은 시간을 투자한 후였기에 처음부터 다시 시작해야 했습니다.
이런 실수를 반복하면서 "데이터를 먼저 이해하자"는 원칙이 생겨났습니다. 바로 이런 문제를 해결하기 위해 EDA가 필수 단계가 되었습니다.
EDA를 통해 우리는 세 가지 중요한 정보를 얻을 수 있습니다. 첫째, 데이터의 구조를 파악합니다.
몇 개의 행과 열이 있는지, 어떤 칼럼들이 있는지 확인합니다. 둘째, 결측치를 발견합니다.
비어있는 값들이 어디에 얼마나 있는지 확인합니다. 셋째, 데이터의 분포를 이해합니다.
각 변수가 어떤 범위의 값을 가지는지, 어떻게 분포되어 있는지 봅니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 pd.read_csv()로 CSV 파일을 불러옵니다. 이것이 가장 기본적인 데이터 로드 방법입니다.
그다음 shape 속성으로 데이터의 크기를 확인합니다. 행과 열의 개수가 출력됩니다.
head() 함수는 처음 5행을 보여줍니다. 데이터가 어떻게 생겼는지 빠르게 파악할 수 있습니다.
info() 메서드는 매우 유용합니다. 각 칼럼의 데이터 타입과 결측치가 아닌 값의 개수를 알려줍니다.
만약 전체 행이 891개인데 어떤 칼럼이 714개만 있다면, 177개의 결측치가 있다는 뜻입니다. describe() 메서드는 수치형 변수들의 통계량을 보여줍니다.
평균, 표준편차, 최솟값, 최댓값 등을 한눈에 확인할 수 있습니다. 마지막으로 value_counts()로 타겟 변수의 분포를 확인합니다.
생존자와 사망자가 각각 몇 명인지 알 수 있습니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 이커머스 회사에서 고객 이탈 예측 프로젝트를 진행한다고 가정해봅시다. EDA 단계에서 "최근 3개월 구매 데이터"라는 칼럼에 결측치가 70%나 있다는 것을 발견할 수 있습니다.
이 정보는 매우 중요합니다. 해당 칼럼을 사용할지 말지, 또는 어떻게 처리할지 초기에 결정할 수 있기 때문입니다.
하지만 주의할 점도 있습니다. 초보자들이 흔히 하는 실수는 EDA를 대충 하고 넘어가는 것입니다.
"데이터가 있네, 좋아"하고 바로 모델링으로 넘어가면 나중에 큰 문제를 만날 수 있습니다. 반대로 EDA에 너무 많은 시간을 쓰는 것도 문제입니다.
적절한 균형을 찾아야 합니다. 다시 김데이터 씨의 이야기로 돌아가 봅시다.
데이터를 살펴본 김데이터 씨는 흥미로운 사실을 발견했습니다. "Age 칼럼에 결측치가 꽤 많네요!" 박머신 씨가 고개를 끄덕였습니다.
"잘 봤어요. 바로 그런 걸 찾아내는 게 EDA의 목적이에요." EDA는 데이터 분석의 첫걸음이자 가장 중요한 단계입니다.
데이터를 제대로 이해해야 좋은 모델을 만들 수 있습니다. 여러분도 항상 EDA부터 시작하는 습관을 들이세요.
실전 팁
💡 - info()로 결측치를 빠르게 확인할 수 있습니다
- describe()는 이상치를 발견하는 데 유용합니다
- 타겟 변수의 분포가 불균형한지 꼭 확인하세요
3. 피처 엔지니어링 수행
데이터를 살펴본 김데이터 씨에게 박머신 씨가 질문을 던졌습니다. "Name 칼럼을 보면 Mr., Mrs., Miss 같은 호칭이 있죠?
이것도 유용한 정보가 될 수 있을까요?" 김데이터 씨는 고개를 갸우뚱했습니다.
피처 엔지니어링은 원본 데이터에서 새로운 특성을 만들어내는 작업입니다. 마치 요리사가 재료를 손질하고 양념을 만드는 것처럼, 모델이 더 잘 학습할 수 있도록 데이터를 가공합니다.
기존 칼럼을 조합하거나 변환해서 더 의미 있는 정보를 추출하는 것이 핵심입니다.
다음 코드를 살펴봅시다.
# 호칭 추출
train_df['Title'] = train_df['Name'].str.extract(' ([A-Za-z]+)\.', expand=False)
# 가족 크기 생성
train_df['FamilySize'] = train_df['SibSp'] + train_df['Parch'] + 1
# 혼자 탑승 여부
train_df['IsAlone'] = (train_df['FamilySize'] == 1).astype(int)
# 나이 구간 생성
train_df['AgeGroup'] = pd.cut(train_df['Age'], bins=[0, 12, 18, 35, 60, 100],
labels=['Child', 'Teen', 'Adult', 'Middle', 'Senior'])
# 요금 구간 생성
train_df['FareGroup'] = pd.qcut(train_df['Fare'], q=4, labels=['Low', 'Medium', 'High', 'VeryHigh'])
print("새로운 피처 생성 완료!")
print(train_df[['Name', 'Title', 'FamilySize', 'IsAlone']].head())
김데이터 씨는 박머신 씨의 질문에 대답하지 못했습니다. Name 칼럼은 그저 이름일 뿐인데, 거기서 무슨 정보를 얻을 수 있을까요?
박머신 씨는 웃으며 화면을 가리켰습니다. "이름을 자세히 보세요.
'Braund, Mr. Owen Harris', 'Cumings, Mrs.
John Bradley'... 보이시죠?
Mr., Mrs., Miss 같은 호칭이 있어요. 이게 단순한 호칭일까요, 아니면 생존율과 관련이 있을까요?" 그렇다면 피처 엔지니어링이란 정확히 무엇일까요?
쉽게 비유하자면, 피처 엔지니어링은 마치 금광에서 금을 캐는 것과 같습니다. 흙더미처럼 보이는 원석 데이터에서 반짝이는 정보를 찾아내는 작업입니다.
때로는 여러 재료를 섞어서 새로운 것을 만들어내기도 합니다. 밀가루와 물과 소금으로 빵을 만드는 것처럼 말입니다.
피처 엔지니어링이 없던 시절에는 어땠을까요? 초기 머신러닝 연구자들은 원본 데이터를 그대로 모델에 넣었습니다.
성능이 잘 나오지 않으면 더 복잡한 모델을 사용하거나 파라미터를 조정했습니다. 하지만 종종 간단한 새 특성 하나가 복잡한 모델보다 더 큰 성능 향상을 가져온다는 것을 발견했습니다.
"데이터가 모델보다 중요하다"는 격언이 생겨난 이유입니다. 바로 이런 경험을 통해 피처 엔지니어링이 핵심 기술이 되었습니다.
피처 엔지니어링으로 할 수 있는 일은 다양합니다. 첫째, 기존 칼럼에서 정보를 추출할 수 있습니다.
Name에서 Title을 뽑아내는 것이 그 예입니다. 둘째, 여러 칼럼을 조합할 수 있습니다.
SibSp(형제자매 수)와 Parch(부모자식 수)를 더해서 FamilySize를 만드는 것처럼요. 셋째, 연속형 변수를 구간으로 나눌 수 있습니다.
Age를 Child, Teen, Adult 같은 카테고리로 변환하는 것입니다. 위의 코드를 한 줄씩 살펴보겠습니다.
첫 번째 줄은 정규표현식을 사용해서 Name에서 호칭을 추출합니다. ' ([A-Za-z]+).'는 "공백 다음에 알파벳이 오고 점으로 끝나는 패턴"을 찾습니다.
이렇게 하면 Mr., Mrs., Miss 같은 호칭을 자동으로 뽑아낼 수 있습니다. 다음으로 FamilySize를 계산합니다.
SibSp와 Parch를 더하고 1을 더합니다. 1은 본인을 의미합니다.
혼자 탑승한 사람은 1이 되고, 5인 가족이면 5가 됩니다. IsAlone은 혼자 탑승했는지 여부를 나타냅니다.
FamilySize가 1이면 True가 되고, 이를 정수로 변환하면 1이 됩니다. 그렇지 않으면 0입니다.
이런 이진 변수는 모델이 학습하기 쉽습니다. pd.cut()은 연속형 변수를 지정한 구간으로 나눕니다.
Age를 0-12, 12-18, 18-35, 35-60, 60-100으로 나누고 각각 Child, Teen, Adult, Middle, Senior라는 레이블을 붙입니다. pd.qcut()은 비슷한데, 구간을 수동으로 지정하는 대신 데이터를 동일한 크기의 그룹으로 나눕니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 부동산 가격 예측 프로젝트를 진행한다고 가정해봅시다.
원본 데이터에는 "건물 면적"과 "대지 면적"이 있습니다. 여기서 "건물 면적 / 대지 면적"이라는 새로운 특성을 만들 수 있습니다.
이것은 용적률을 나타내며, 가격과 높은 상관관계를 가질 수 있습니다. 이런 도메인 지식을 활용한 피처 엔지니어링이 모델 성능을 크게 향상시킵니다.
하지만 주의할 점도 있습니다. 피처 엔지니어링을 하다 보면 너무 많은 특성을 만들고 싶은 유혹에 빠집니다.
하지만 특성이 많다고 항상 좋은 것은 아닙니다. 차원의 저주라는 문제가 생길 수 있습니다.
또한 훈련 데이터에만 맞는 특성을 만들면 과적합의 위험이 있습니다. 새로운 특성을 만들 때는 항상 "이게 정말 일반적으로 유용할까?"를 자문해야 합니다.
다시 김데이터 씨의 이야기로 돌아가 봅시다. 코드를 실행한 김데이터 씨는 감탄했습니다.
"와, Mr.이 있는 사람들의 생존율이 확실히 낮네요!" 박머신 씨가 웃었습니다. "그렇죠.
남성의 생존율이 낮았던 역사적 사실을 데이터가 보여주는 거예요." 피처 엔지니어링은 창의성이 필요한 작업입니다. 데이터를 다양한 각도에서 바라보고, 숨겨진 패턴을 찾아내는 능력이 중요합니다.
여러분도 도메인 지식과 창의성을 발휘해서 유용한 특성을 만들어 보세요.
실전 팁
💡 - 정규표현식으로 텍스트에서 정보를 추출할 수 있습니다
- 여러 칼럼을 조합하면 새로운 인사이트를 얻을 수 있습니다
- 연속형 변수를 구간으로 나누면 비선형 관계를 포착할 수 있습니다
4. 데이터 분리 및 전처리
새로운 특성들을 만든 김데이터 씨는 이제 본격적으로 모델을 학습시킬 준비를 해야 합니다. 박머신 씨가 말했습니다.
"모델을 학습시키기 전에 데이터를 훈련용과 테스트용으로 나눠야 해요. 그리고 결측치와 범주형 변수도 처리해야 하고요."
데이터 분리는 전체 데이터를 훈련 세트와 테스트 세트로 나누는 작업입니다. 전처리는 결측치를 채우고, 범주형 변수를 숫자로 변환하며, 스케일을 조정하는 등 모델이 학습할 수 있는 형태로 데이터를 변환하는 과정입니다.
마치 음식을 먹기 좋게 손질하는 것과 같습니다.
다음 코드를 살펴봅시다.
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.impute import SimpleImputer
# 결측치 처리 - 나이는 중앙값으로, 선실은 최빈값으로
age_imputer = SimpleImputer(strategy='median')
train_df['Age'] = age_imputer.fit_transform(train_df[['Age']])
cabin_imputer = SimpleImputer(strategy='most_frequent')
train_df['Embarked'] = cabin_imputer.fit_transform(train_df[['Embarked']])
# 범주형 변수 인코딩
le = LabelEncoder()
train_df['Sex'] = le.fit_transform(train_df['Sex'])
train_df['Embarked'] = le.fit_transform(train_df['Embarked'])
# 특성과 타겟 분리
features = ['Pclass', 'Sex', 'Age', 'Fare', 'FamilySize', 'IsAlone']
X = train_df[features]
y = train_df['Survived']
# 훈련/테스트 분리
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 스케일링
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
print(f"훈련 데이터: {X_train.shape}, 테스트 데이터: {X_test.shape}")
김데이터 씨는 또다시 고개를 갸우뚱했습니다. "왜 데이터를 나눠야 하나요?
전체 데이터로 학습시키면 더 좋지 않을까요?" 박머신 씨는 이번에도 좋은 비유를 들려주었습니다. "학생이 시험 문제를 미리 다 외우면 시험에서 100점을 받겠죠.
하지만 그게 진짜 실력일까요? 새로운 문제가 나오면 못 풀 거예요.
모델도 마찬가지예요." 그렇다면 데이터 분리가 왜 필요할까요? 쉽게 비유하자면, 데이터 분리는 마치 학생이 공부할 때 연습 문제와 모의고사를 나누는 것과 같습니다.
연습 문제로 개념을 익히고, 모의고사로 실력을 테스트합니다. 모의고사 문제를 미리 보면 안 되겠죠?
마찬가지로 모델도 훈련 데이터로 학습하고, 테스트 데이터로 성능을 평가해야 합니다. 데이터를 나누지 않던 시절에는 어땠을까요?
초기 머신러닝 연구자들은 전체 데이터로 모델을 학습시키고, 같은 데이터로 성능을 평가했습니다. 결과는 놀라웠습니다.
정확도가 99%가 넘었습니다! 하지만 실제 현장에 배포하자 성능이 형편없었습니다.
모델이 훈련 데이터를 암기했을 뿐, 일반화하지 못했던 것입니다. 이런 문제를 과적합이라고 부릅니다.
바로 이런 문제를 방지하기 위해 데이터 분리가 필수가 되었습니다. 데이터를 나누는 것 외에도 해야 할 일이 많습니다.
첫째, 결측치 처리입니다. 머신러닝 모델은 빈 칸을 싫어합니다.
결측치를 평균이나 중앙값으로 채우거나, 최빈값으로 채울 수 있습니다. 둘째, 범주형 변수 인코딩입니다.
'male', 'female' 같은 문자열을 모델은 이해하지 못합니다. 0과 1 같은 숫자로 변환해야 합니다.
위의 코드를 한 줄씩 살펴보겠습니다. SimpleImputer는 결측치를 채우는 도구입니다.
strategy='median'은 중앙값으로 채우라는 의미입니다. Age 같은 수치형 변수는 평균이나 중앙값을 사용하는 것이 일반적입니다.
strategy='most_frequent'는 최빈값, 즉 가장 자주 나타나는 값으로 채웁니다. Embarked 같은 범주형 변수에 적합합니다.
LabelEncoder는 범주형 변수를 숫자로 변환합니다. 'male'은 0, 'female'은 1이 됩니다.
하지만 주의할 점이 있습니다. LabelEncoder는 순서가 없는 범주형 변수에는 적합하지 않을 수 있습니다.
그런 경우 OneHotEncoder를 사용해야 합니다. train_test_split()은 데이터를 무작위로 섞어서 나눕니다.
test_size=0.2는 전체의 20%를 테스트용으로 사용한다는 의미입니다. random_state=42는 같은 결과를 재현하기 위한 시드값입니다.
StandardScaler는 각 특성의 스케일을 표준화합니다. 평균을 0, 표준편차를 1로 만듭니다.
왜 이게 필요할까요? Age는 0에서 80 사이의 값을 가지는데, Fare는 0에서 500 이상의 값을 가질 수 있습니다.
스케일이 다르면 일부 모델이 제대로 학습하지 못합니다. 중요한 점은 fit_transform()은 훈련 데이터에만 사용하고, 테스트 데이터에는 transform()만 사용한다는 것입니다.
테스트 데이터의 정보가 훈련에 섞이면 안 되기 때문입니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 신용카드 사기 탐지 시스템을 개발한다고 가정해봅시다. 과거 거래 데이터로 모델을 훈련시킵니다.
하지만 이 모델을 실제로 배포하기 전에, 최근 한 달의 데이터를 테스트 세트로 남겨두고 성능을 평가합니다. 이렇게 해야 실제 환경에서도 잘 작동할지 알 수 있습니다.
하지만 주의할 점도 있습니다. 초보자들이 흔히 하는 실수는 전처리를 잘못된 순서로 하는 것입니다.
예를 들어 전체 데이터에 스케일링을 먼저 하고, 그다음에 훈련/테스트를 나누면 데이터 누수가 발생합니다. 테스트 데이터의 정보가 훈련 과정에 영향을 미치게 되는 것입니다.
반드시 데이터를 먼저 나누고, 훈련 데이터로만 전처리 파라미터를 학습해야 합니다. 다시 김데이터 씨의 이야기로 돌아가 봅시다.
전처리를 마친 김데이터 씨는 화면을 뿌듯하게 바라보았습니다. "이제 모델을 학습시킬 준비가 됐네요!" 박머신 씨가 격려했습니다.
"맞아요. 데이터 준비가 80%, 모델링은 20%라는 말이 있어요." 데이터 분리와 전처리는 지루해 보이지만 가장 중요한 단계입니다.
이 단계를 제대로 하지 않으면 아무리 좋은 모델을 사용해도 좋은 결과를 얻을 수 없습니다. 여러분도 전처리에 충분한 시간을 투자하세요.
실전 팁
💡 - 결측치는 변수의 특성에 따라 적절한 방법으로 채웁니다
- 전처리 파라미터는 반드시 훈련 데이터로만 학습합니다
- 스케일링은 거리 기반 모델에서 특히 중요합니다
5. 여러 모델 학습 및 비교
드디어 모델을 학습시킬 시간입니다. 김데이터 씨는 긴장했습니다.
"어떤 모델을 사용해야 할까요?" 박머신 씨가 답했습니다. "한 가지만 시도하지 말고 여러 모델을 비교해보세요.
각 모델마다 장단점이 있으니까요."
모델 학습은 준비된 데이터로 여러 머신러닝 알고리즘을 훈련시키는 단계입니다. 로지스틱 회귀, 랜덤 포레스트, XGBoost 등 다양한 모델을 시도해보고, 각각의 성능을 비교합니다.
마치 여러 요리 방법을 시도해서 가장 맛있는 것을 찾는 것과 같습니다.
다음 코드를 살펴봅시다.
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, classification_report
# 여러 모델 정의
models = {
'Logistic Regression': LogisticRegression(random_state=42),
'Random Forest': RandomForestClassifier(n_estimators=100, random_state=42),
'Gradient Boosting': GradientBoostingClassifier(n_estimators=100, random_state=42),
'SVM': SVC(random_state=42)
}
# 각 모델 학습 및 평가
results = {}
for model_name, model in models.items():
# 모델 학습
model.fit(X_train_scaled, y_train)
# 예측
y_pred = model.predict(X_test_scaled)
# 정확도 계산
accuracy = accuracy_score(y_test, y_pred)
results[model_name] = accuracy
print(f"\n{model_name}")
print(f"정확도: {accuracy:.4f}")
print(classification_report(y_test, y_pred))
# 최고 성능 모델
best_model = max(results, key=results.get)
print(f"\n최고 성능 모델: {best_model} ({results[best_model]:.4f})")
김데이터 씨는 코드를 작성하면서 궁금했습니다. "모델이 이렇게 많은데, 왜 하나만 쓰지 않고 여러 개를 시도해야 하나요?" 박머신 씨는 재미있는 비유를 들려주었습니다.
"등산을 생각해보세요. 산에 오르는 방법은 여러 가지입니다.
케이블카, 등산로, 암벽 등반... 어떤 게 가장 빠를까요?
산마다 다르죠. 마찬가지로 데이터마다 잘 맞는 모델이 다릅니다." 그렇다면 왜 여러 모델을 비교해야 할까요?
쉽게 비유하자면, 모델 비교는 마치 여러 열쇠로 문을 열어보는 것과 같습니다. 어떤 자물쇠에는 A 열쇠가 맞고, 다른 자물쇠에는 B 열쇠가 맞습니다.
미리 어떤 열쇠가 맞을지 알 수 없으니, 여러 개를 시도해봐야 합니다. 머신러닝도 마찬가지입니다.
데이터의 특성에 따라 어떤 모델이 잘 작동할지 미리 알 수 없습니다. 한 가지 모델만 사용하던 시절에는 어땠을까요?
옛날 연구자들은 자신이 익숙한 한두 가지 모델만 고집했습니다. "나는 선형 회귀 전문가야"라고 하며 모든 문제에 선형 회귀를 적용했습니다.
당연히 성능이 좋지 않은 경우가 많았습니다. 나중에 다른 연구자가 다른 모델을 시도해보니 성능이 크게 향상되는 경우가 많았습니다.
이런 경험이 쌓이면서 "여러 모델을 비교하는 것이 표준"이 되었습니다. 바로 이런 이유로 모델 비교가 필수 단계가 되었습니다.
우리가 시도할 모델들을 하나씩 살펴보겠습니다. 로지스틱 회귀는 가장 기본적인 분류 모델입니다.
단순하지만 해석하기 쉽고 빠릅니다. 랜덤 포레스트는 여러 결정 트리를 조합한 앙상블 모델입니다.
과적합에 강하고 성능이 좋습니다. 그래디언트 부스팅은 약한 모델들을 순차적으로 개선해나가는 방식입니다.
보통 가장 높은 성능을 보입니다. SVM은 데이터를 고차원 공간으로 매핑해서 분류하는 모델입니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 딕셔너리로 모델들을 정의합니다.
키는 모델 이름, 값은 모델 객체입니다. 이렇게 하면 반복문으로 여러 모델을 쉽게 처리할 수 있습니다.
for 반복문으로 각 모델을 순회합니다. model.fit()으로 모델을 학습시킵니다.
이것이 핵심입니다. 모델은 X_train과 y_train의 패턴을 학습합니다.
학습이 끝나면 model.predict()로 테스트 데이터에 대한 예측을 수행합니다. accuracy_score()는 정확도를 계산합니다.
전체 예측 중 맞춘 비율입니다. classification_report()는 더 자세한 정보를 제공합니다.
정밀도, 재현율, F1 점수 등을 클래스별로 보여줍니다. 마지막으로 max()와 key=results.get을 사용해서 가장 높은 정확도를 가진 모델을 찾습니다.
이것이 우리가 선택할 최고 성능 모델입니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 이메일 스팸 필터를 개발한다고 가정해봅시다. 먼저 나이브 베이즈, 로지스틱 회귀, 랜덤 포레스트, 뉴럴 네트워크 등 다양한 모델을 시도합니다.
각 모델의 정확도뿐 아니라 추론 속도도 측정합니다. 실시간으로 작동해야 하는 시스템이라면 정확도가 조금 낮더라도 빠른 모델을 선택할 수 있습니다.
이처럼 현업에서는 성능과 속도, 해석 가능성 등을 종합적으로 고려합니다. 하지만 주의할 점도 있습니다.
초보자들이 흔히 하는 실수는 정확도만 보고 모델을 선택하는 것입니다. 하지만 정확도가 전부가 아닙니다.
데이터가 불균형하다면 F1 점수나 AUC를 봐야 합니다. 예를 들어 생존자가 10%, 사망자가 90%인 상황에서 모든 사람을 사망자로 예측하면 정확도가 90%가 나옵니다.
하지만 이건 좋은 모델이 아닙니다. 다시 김데이터 씨의 이야기로 돌아가 봅시다.
결과를 본 김데이터 씨는 놀랐습니다. "랜덤 포레스트가 82% 정확도로 가장 높네요!" 박머신 씨가 웃었습니다.
"좋아요. 하지만 그래디언트 부스팅도 81%로 아주 근소한 차이예요.
두 모델 중 어떤 게 더 안정적인지도 확인해봐야 합니다." 여러 모델을 비교하는 것은 데이터 과학의 핵심입니다. 한 가지 방법만 고집하지 말고, 다양한 접근을 시도해보세요.
때로는 예상치 못한 모델이 가장 좋은 결과를 낼 수 있습니다.
실전 팁
💡 - 간단한 모델부터 시작해서 점진적으로 복잡한 모델을 시도합니다
- 정확도 외에 F1 점수, AUC 등 다른 지표도 확인합니다
- 모델의 학습 시간과 추론 속도도 고려해야 합니다
6. 최적 모델 선택
여러 모델을 비교한 김데이터 씨는 이제 최종 모델을 선택해야 합니다. 박머신 씨가 조언했습니다.
"랜덤 포레스트가 가장 높은 정확도를 보였지만, 하이퍼파라미터를 튜닝하면 더 좋아질 수 있어요. 한번 해볼까요?"
최적 모델 선택은 여러 후보 중에서 최고 성능을 내는 모델을 고르고, 하이퍼파라미터 튜닝을 통해 성능을 극대화하는 단계입니다. 마치 악기를 조율해서 가장 아름다운 소리를 내는 것처럼, 모델의 설정값을 조정해서 최고 성능을 끌어냅니다.
다음 코드를 살펴봅시다.
from sklearn.model_selection import GridSearchCV, cross_val_score
# 랜덤 포레스트 하이퍼파라미터 그리드
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [5, 10, 15, None],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
}
# 그리드 서치
rf_model = RandomForestClassifier(random_state=42)
grid_search = GridSearchCV(rf_model, param_grid, cv=5, scoring='accuracy', n_jobs=-1)
grid_search.fit(X_train_scaled, y_train)
# 최적 파라미터
print("최적 하이퍼파라미터:", grid_search.best_params_)
print("최고 교차 검증 점수:", grid_search.best_score_)
# 최적 모델로 테스트
best_rf_model = grid_search.best_estimator_
y_pred_best = best_rf_model.predict(X_test_scaled)
final_accuracy = accuracy_score(y_test, y_pred_best)
print(f"\n최종 테스트 정확도: {final_accuracy:.4f}")
김데이터 씨는 고개를 갸우뚱했습니다. "하이퍼파라미터가 뭔가요?
처음 듣는 용어인데요." 박머신 씨는 천천히 설명하기 시작했습니다. "모델에는 두 가지 종류의 파라미터가 있어요.
하나는 모델이 데이터로부터 자동으로 학습하는 파라미터입니다. 다른 하나는 우리가 직접 설정해줘야 하는 하이퍼파라미터입니다." 그렇다면 하이퍼파라미터 튜닝이란 정확히 무엇일까요?
쉽게 비유하자면, 하이퍼파라미터 튜닝은 마치 라디오의 주파수를 맞추는 것과 같습니다. 다이얼을 조금씩 돌리면서 가장 선명한 소리가 나오는 지점을 찾습니다.
너무 왼쪽으로 돌려도 안 되고, 너무 오른쪽으로 돌려도 안 됩니다. 딱 맞는 지점을 찾아야 합니다.
머신러닝 모델도 마찬가지입니다. 하이퍼파라미터를 조정하면서 최고 성능을 내는 조합을 찾아야 합니다.
하이퍼파라미터를 튜닝하지 않던 시절에는 어땠을까요? 초기 연구자들은 기본값을 그대로 사용하거나, 경험과 직관에 의존해서 값을 설정했습니다.
"음, 이 정도면 되겠지?"라고 추측했습니다. 당연히 최적의 성능을 내기 어려웠습니다.
어떤 경우에는 하이퍼파라미터를 잘못 설정해서 모델이 제대로 학습하지 못하기도 했습니다. 체계적인 방법이 필요했습니다.
바로 이런 문제를 해결하기 위해 그리드 서치가 등장했습니다. 그리드 서치는 가능한 모든 조합을 시도해보는 방법입니다.
n_estimators를 50, 100, 200으로 시도하고, max_depth를 5, 10, 15, None으로 시도한다면, 총 몇 가지 조합이 가능할까요? 3 × 4 = 12가지입니다.
실제로는 더 많은 하이퍼파라미터가 있으니 조합의 수는 훨씬 많아집니다. 그리드 서치는 이 모든 조합을 시도해서 가장 좋은 것을 찾아줍니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 param_grid라는 딕셔너리를 정의합니다.
키는 하이퍼파라미터 이름이고, 값은 시도할 값들의 리스트입니다. n_estimators는 랜덤 포레스트의 트리 개수입니다.
많을수록 성능이 좋아지지만 시간도 오래 걸립니다. max_depth는 각 트리의 최대 깊이입니다.
None은 제한이 없다는 의미입니다. GridSearchCV 객체를 만듭니다.
CV는 Cross Validation의 약자입니다. cv=5는 5-폴드 교차 검증을 의미합니다.
데이터를 5개로 나누고, 4개로 학습하고 1개로 검증하는 과정을 5번 반복합니다. 이렇게 하면 더 신뢰할 수 있는 평가를 얻을 수 있습니다.
n_jobs=-1은 모든 CPU 코어를 사용하라는 의미입니다. 그리드 서치는 시간이 오래 걸리므로 병렬 처리가 중요합니다.
fit()을 호출하면 모든 조합을 시도합니다. 시간이 걸릴 수 있습니다.
끝나면 best_params_에 최적의 조합이 저장됩니다. best_estimator_에는 그 조합으로 학습된 모델이 저장됩니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 추천 시스템을 개발한다고 가정해봅시다.
초기 모델의 정확도가 75%입니다. 괜찮지만 더 개선하고 싶습니다.
하이퍼파라미터 튜닝을 통해 78%로 향상시킬 수 있습니다. 3%의 차이가 작아 보이지만, 실제로는 수천 명의 사용자 경험을 개선하는 것입니다.
이것이 하이퍼파라미터 튜닝의 가치입니다. 하지만 주의할 점도 있습니다.
초보자들이 흔히 하는 실수는 너무 많은 조합을 시도하는 것입니다. 하이퍼파라미터가 5개이고 각각 10개의 값을 시도한다면, 총 100,000개의 조합을 시도해야 합니다.
이것은 현실적이지 않습니다. 먼저 중요한 하이퍼파라미터를 선별하고, 적절한 범위를 설정해야 합니다.
또한 랜덤 서치를 사용하면 무작위로 일부 조합만 시도해서 시간을 절약할 수 있습니다. 다시 김데이터 씨의 이야기로 돌아가 봅시다.
그리드 서치가 끝나자 김데이터 씨는 결과를 확인했습니다. "와, 정확도가 84%로 올라갔어요!" 박머신 씨가 웃으며 말했습니다.
"잘했어요. 하이퍼파라미터 튜닝으로 2%를 개선한 거예요." 최적 모델 선택은 머신러닝 프로젝트의 마지막 단계입니다.
여러 모델을 비교하고, 최고의 모델을 선택하고, 하이퍼파라미터를 튜닝해서 성능을 극대화합니다. 이 과정을 거치면 자신 있게 모델을 배포할 수 있습니다.
실전 팁
💡 - 중요한 하이퍼파라미터부터 튜닝을 시작합니다
- 시간이 부족하면 랜덤 서치를 사용합니다
- 교차 검증으로 더 신뢰할 수 있는 평가를 얻을 수 있습니다
7. 최종 예측 및 결과 분석
최적 모델을 찾은 김데이터 씨는 이제 마지막 단계를 앞두고 있습니다. 박머신 씨가 말했습니다.
"이제 실제 테스트 데이터로 예측을 수행하고, 결과를 분석해봅시다. 어떤 특성이 중요했는지도 확인할 수 있어요."
최종 예측은 학습된 모델로 새로운 데이터의 결과를 예측하는 단계입니다. 결과 분석은 모델이 어떻게 작동하는지 이해하기 위해 특성 중요도, 혼동 행렬 등을 확인하는 과정입니다.
마치 요리를 완성한 후 맛을 보고 어떤 재료가 가장 큰 역할을 했는지 평가하는 것과 같습니다.
다음 코드를 살펴봅시다.
from sklearn.metrics import confusion_matrix, roc_curve, auc
import matplotlib.pyplot as plt
# 최종 예측
final_predictions = best_rf_model.predict(X_test_scaled)
probabilities = best_rf_model.predict_proba(X_test_scaled)[:, 1]
# 혼동 행렬
cm = confusion_matrix(y_test, final_predictions)
print("혼동 행렬:")
print(cm)
print(f"\n진짜 양성: {cm[1,1]}, 거짓 양성: {cm[0,1]}")
print(f"진짜 음성: {cm[0,0]}, 거짓 음성: {cm[1,0]}")
# 특성 중요도
feature_importance = pd.DataFrame({
'feature': features,
'importance': best_rf_model.feature_importances_
}).sort_values('importance', ascending=False)
print("\n특성 중요도:")
print(feature_importance)
# 결과 저장
results_df = pd.DataFrame({
'PassengerId': range(1, len(final_predictions) + 1),
'Survived': final_predictions
})
results_df.to_csv('titanic_predictions.csv', index=False)
print("\n예측 결과가 저장되었습니다!")
김데이터 씨는 설렜습니다. 드디어 모델이 실제로 예측을 수행하는 모습을 보게 될 것입니다.
"이제 정말 끝나는 건가요?" 박머신 씨는 고개를 끄덕였습니다. "거의 다 왔어요.
하지만 마지막 단계가 의외로 중요해요. 결과를 제대로 분석하지 않으면 모델을 신뢰할 수 없으니까요." 그렇다면 결과 분석이란 정확히 무엇일까요?
쉽게 비유하자면, 결과 분석은 마치 시험을 본 후 틀린 문제를 복습하는 것과 같습니다. 단순히 점수만 보는 게 아니라, 어떤 유형의 문제를 틀렸는지, 왜 틀렸는지 분석합니다.
그래야 다음에 더 잘할 수 있습니다. 머신러닝도 마찬가지입니다.
모델이 어디서 실수하는지, 어떤 특성이 중요한지 이해해야 합니다. 결과 분석을 하지 않던 시절에는 어땠을까요?
예전 데이터 과학자들은 정확도만 확인하고 끝냈습니다. "85% 정확도네, 좋아!"하고 바로 배포했습니다.
하지만 실제 환경에서 문제가 생겼습니다. 어떤 경우에는 모델이 특정 그룹에서만 형편없는 성능을 보였습니다.
나중에 분석해보니 데이터가 편향되어 있었거나, 중요한 특성을 놓쳤다는 것을 알게 되었습니다. 이런 실수를 반복하면서 "결과를 철저히 분석하자"는 원칙이 생겼습니다.
바로 이런 문제를 방지하기 위해 결과 분석이 필수가 되었습니다. 결과 분석에서 가장 중요한 도구 중 하나가 혼동 행렬입니다.
이것은 모델의 예측을 네 가지 카테고리로 분류합니다. 진짜 양성은 생존자를 생존자로 올바르게 예측한 경우입니다.
진짜 음성은 사망자를 사망자로 올바르게 예측한 경우입니다. 거짓 양성은 사망자를 생존자로 잘못 예측한 경우이고, 거짓 음성은 생존자를 사망자로 잘못 예측한 경우입니다.
또 다른 중요한 도구는 특성 중요도입니다. 랜덤 포레스트 같은 트리 기반 모델은 각 특성이 예측에 얼마나 기여했는지 알려줄 수 있습니다.
예를 들어 Sex가 가장 중요한 특성이고, Age가 두 번째로 중요하다면, 성별과 나이가 생존 예측에 큰 영향을 미친다는 것을 알 수 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
predict()는 최종 예측을 수행합니다. 0 또는 1의 값을 반환합니다.
predict_proba()는 확률을 반환합니다. 각 클래스에 속할 확률을 알 수 있습니다.
[:, 1]은 클래스 1(생존)의 확률만 가져옵니다. confusion_matrix()는 혼동 행렬을 만듭니다.
2×2 배열이 반환됩니다. [0,0]은 진짜 음성, [0,1]은 거짓 양성, [1,0]은 거짓 음성, [1,1]은 진짜 양성입니다.
feature_importances_ 속성은 각 특성의 중요도를 담고 있습니다. 모든 값을 합하면 1이 됩니다.
중요도가 높을수록 그 특성이 예측에 크게 기여한 것입니다. 마지막으로 결과를 CSV 파일로 저장합니다.
to_csv()는 데이터프레임을 파일로 저장하는 함수입니다. index=False는 인덱스를 저장하지 않는다는 의미입니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 대출 승인 모델을 개발했다고 가정해봅시다.
결과를 분석하던 중 거짓 음성 비율이 높다는 것을 발견했습니다. 즉, 대출금을 잘 갚을 사람을 거절하는 경우가 많다는 것입니다.
이것은 비즈니스 기회를 놓치는 것입니다. 반대로 거짓 양성이 높다면 대출금을 못 갚을 사람을 승인하는 것이므로 손실이 발생합니다.
이런 분석을 통해 모델의 임계값을 조정하거나, 추가 특성을 수집하는 등의 개선 방안을 찾을 수 있습니다. 하지만 주의할 점도 있습니다.
초보자들이 흔히 하는 실수는 특성 중요도를 과신하는 것입니다. 특성 중요도는 모델에 따라 다르게 계산됩니다.
또한 상관관계가 높은 특성들이 있으면 중요도가 분산됩니다. 따라서 특성 중요도는 참고 자료로 활용하되, 절대적인 진리로 받아들이지 말아야 합니다.
다시 김데이터 씨의 이야기로 돌아가 봅시다. 특성 중요도를 본 김데이터 씨는 흥미로운 점을 발견했습니다.
"Sex가 압도적으로 중요하네요. 다음이 Fare, Age 순이고요." 박머신 씨가 설명했습니다.
"맞아요. 타이타닉호에서는 '여성과 어린이 먼저'라는 원칙이 있었거든요.
모델이 역사적 사실을 데이터에서 학습한 거예요." 김데이터 씨는 뿌듯했습니다. 처음으로 머신러닝 프로젝트를 완성했습니다.
데이터 로드부터 전처리, 모델 학습, 평가, 결과 분석까지 모든 단계를 경험했습니다. 최종 예측과 결과 분석은 프로젝트의 마무리이자 새로운 시작입니다.
여기서 얻은 인사이트를 바탕으로 모델을 개선하고, 새로운 가설을 세우고, 더 나은 프로젝트를 진행할 수 있습니다. 여러분도 첫 머신러닝 프로젝트를 완성해보세요.
타이타닉은 시작일 뿐입니다.
실전 팁
💡 - 혼동 행렬로 모델의 실수 패턴을 파악할 수 있습니다
- 특성 중요도는 도메인 지식과 함께 해석해야 합니다
- 결과를 시각화하면 인사이트를 발견하기 쉽습니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (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의 핵심 개념과 실무 활용법을 배워봅니다. 초급 개발자도 쉽게 따라할 수 있도록 실전 예제와 함께 설명합니다.