🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

A

AI Generated

2025. 12. 17. · 66 Views

머신러닝 개념 소개 완벽 가이드

머신러닝이 무엇인지, 어떻게 작동하는지 처음부터 차근차근 배워봅니다. 지도학습과 비지도학습의 차이, 분류와 회귀 문제, 그리고 실무에서 꼭 알아야 할 과적합 개념까지 모두 담았습니다.


목차

  1. 머신러닝이란_무엇인가
  2. 지도학습_vs_비지도학습
  3. 분류_문제_이해하기
  4. 회귀_문제_이해하기
  5. 학습_데이터와_테스트_데이터
  6. 과적합과_과소적합_개념
  7. 머신러닝_워크플로우

1. 머신러닝이란 무엇인가

어느 날 김개발 씨가 사무실에서 선배 개발자 박시니어 씨와 점심을 먹고 있었습니다. "요즘 모든 회사에서 AI, 머신러닝을 이야기하는데, 사실 저는 정확히 뭔지 잘 모르겠어요." 박시니어 씨가 웃으며 대답했습니다.

"그럼 오늘 제대로 알려드릴게요!"

머신러닝은 한마디로 컴퓨터가 데이터를 통해 스스로 학습하는 것입니다. 마치 우리가 경험을 통해 배우는 것처럼, 컴퓨터도 많은 예제를 보고 패턴을 찾아냅니다.

프로그래머가 일일이 규칙을 작성하지 않아도, 데이터만 충분히 주면 컴퓨터가 알아서 문제 해결 방법을 찾습니다.

다음 코드를 살펴봅시다.

# 머신러닝의 기본 구조
from sklearn.tree import DecisionTreeClassifier

# 1. 데이터 준비: 키와 몸무게로 성별 예측
X = [[170, 70], [160, 55], [180, 80], [155, 50]]  # 키, 몸무게
y = ['남', '여', '남', '여']  # 실제 성별

# 2. 모델 생성 및 학습
model = DecisionTreeClassifier()
model.fit(X, y)  # 여기서 학습이 일어납니다!

# 3. 예측: 새로운 사람의 성별 추측
new_person = [[175, 68]]
prediction = model.predict(new_person)
print(f"예측 결과: {prediction[0]}")  # 결과: 남

[도입 - 실무 상황 스토리] 김개발 씨는 입사 3개월 차 주니어 개발자입니다. 최근 팀에서 고객 이탈 예측 프로젝트를 시작한다는 소식을 들었습니다.

회의에서 팀장님이 "머신러닝으로 고객 패턴을 분석해봅시다"라고 말했는데, 김개발 씨는 고개를 갸우뚱했습니다. 박시니어 씨가 회의 후 김개발 씨를 불러 설명을 시작했습니다.

"머신러닝이라는 게 생각보다 어렵지 않아요. 우리가 평소에 하는 학습과 비슷하거든요." [개념 설명 - 비유로 쉽게] 그렇다면 머신러닝이란 정확히 무엇일까요?

쉽게 비유하자면, 머신러닝은 마치 아기가 걸음마를 배우는 것과 같습니다. 아기는 "왼발을 30도 각도로 들고, 무게중심을 0.5초간 이동하라"는 명령을 받지 않습니다.

그저 수백 번 넘어지고 일어나면서 자연스럽게 걷는 방법을 터득합니다. 이처럼 머신러닝도 많은 데이터 예제를 보면서 스스로 패턴을 찾아냅니다.

[왜 필요한가 - 문제 상황] 머신러닝이 없던 시절에는 어땠을까요? 개발자들은 모든 규칙을 직접 프로그래밍해야 했습니다.

예를 들어 스팸 메일을 걸러내려면 "제목에 '대박', '무료'가 들어가면 스팸"이라는 규칙을 수백 개 작성해야 했습니다. 코드가 길어지고, 새로운 유형의 스팸이 나올 때마다 규칙을 추가해야 했습니다.

더 큰 문제는 복잡한 패턴을 다룰 때였습니다. 얼굴 인식 프로그램을 만든다고 상상해보세요.

"눈썹이 코보다 위에 있고, 눈이 두 개이며..."처럼 규칙으로 작성하는 것은 거의 불가능했습니다. 프로젝트가 커질수록 이런 문제는 눈덩이처럼 불어났습니다.

[해결책 - 개념의 등장] 바로 이런 문제를 해결하기 위해 머신러닝이 등장했습니다. 머신러닝을 사용하면 자동으로 패턴을 찾아내는 것이 가능해집니다.

스팸 메일 수천 개와 정상 메일 수천 개를 보여주기만 하면, 컴퓨터가 알아서 공통된 특징을 찾아냅니다. 또한 새로운 상황에 대한 적응력도 얻을 수 있습니다.

데이터만 추가하면 모델이 계속 발전합니다. 무엇보다 사람이 발견하지 못한 패턴까지 찾아낸다는 큰 이점이 있습니다.

수백 개의 변수가 복잡하게 얽혀 있는 문제도 해결할 수 있습니다. [코드 분석 - 단계별 설명] 위의 코드를 한 줄씩 살펴보겠습니다.

먼저 4번째 줄을 보면 학습 데이터 X를 준비합니다. 키와 몸무게라는 두 가지 특징을 담은 리스트입니다.

5번째 줄의 정답 데이터 y는 각 데이터의 실제 성별을 나타냅니다. 이것이 머신러닝에서 가장 중요한 재료입니다.

다음으로 8번째 줄에서는 DecisionTreeClassifier라는 모델을 만듭니다. 이것은 아직 아무것도 학습하지 않은 빈 모델입니다.

9번째 줄의 fit 함수가 핵심입니다. 여기서 실제 학습이 일어나며, 모델이 데이터의 패턴을 분석합니다.

마지막으로 13번째 줄에서 학습된 모델로 새로운 데이터를 예측합니다. 키 175cm, 몸무게 68kg인 사람의 성별을 추측하는 것이죠.

[실무 활용 사례] 실제 현업에서는 어떻게 활용할까요? 예를 들어 쇼핑몰 서비스를 개발한다고 가정해봅시다.

고객이 다음 달에 이탈할지 예측하는 기능을 만든다면, 과거 고객들의 구매 기록, 접속 빈도, 클릭 패턴 등을 학습시킵니다. 머신러닝 모델이 이탈 가능성이 높은 고객을 미리 찾아내면, 마케팅 팀에서 할인 쿠폰을 보내는 식으로 대응할 수 있습니다.

네이버, 카카오, 쿠팡 같은 대기업들은 모두 이런 패턴을 적극적으로 사용하고 있습니다. 추천 시스템, 검색 순위, 광고 타겟팅 등 거의 모든 곳에 머신러닝이 숨어 있습니다.

[주의사항] 하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 데이터가 부족한데도 복잡한 모델을 사용하는 것입니다.

데이터가 10개밖에 없는데 수백 개의 파라미터를 가진 모델을 사용하면 제대로 학습되지 않습니다. 이렇게 하면 과적합이라는 문제가 발생할 수 있습니다.

따라서 충분한 양의 질 좋은 데이터를 먼저 준비하고, 간단한 모델부터 시작하는 것이 올바른 방법입니다. [정리] 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다. "아, 그래서 데이터가 중요하다고 하는 거군요!" 머신러닝을 제대로 이해하면 단순히 코드를 작성하는 것을 넘어, 데이터로 문제를 해결하는 새로운 사고방식을 갖게 됩니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 처음에는 scikit-learn 라이브러리의 간단한 예제부터 시작하세요

  • 데이터는 많을수록 좋지만, 질이 더 중요합니다
  • 복잡한 모델보다 간단한 모델로 시작해서 점진적으로 개선하세요

2. 지도학습 vs 비지도학습

다음 날 김개발 씨는 머신러닝 관련 자료를 찾아보다가 "지도학습"과 "비지도학습"이라는 용어를 발견했습니다. "둘 다 학습인데 뭐가 다른 거지?" 궁금증이 생긴 김개발 씨는 다시 박시니어 씨를 찾아갔습니다.

지도학습은 정답이 있는 데이터로 학습하는 방식입니다. 마치 선생님이 문제와 정답을 함께 알려주며 가르치는 것과 같습니다.

반면 비지도학습은 정답 없이 데이터의 구조나 패턴만 찾아내는 방식입니다. 목적에 따라 적절한 학습 방법을 선택하는 것이 중요합니다.

다음 코드를 살펴봅시다.

# 지도학습 예제: 붓꽃 품종 분류
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier

iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(
    iris.data, iris.target, test_size=0.2
)

# 정답(y_train)을 알려주며 학습
model = DecisionTreeClassifier()
model.fit(X_train, y_train)
print(f"정확도: {model.score(X_test, y_test):.2f}")

# 비지도학습 예제: 고객 그룹화
from sklearn.cluster import KMeans

customer_data = [[25, 50000], [30, 60000], [45, 150000], [50, 200000]]
kmeans = KMeans(n_clusters=2)  # 정답 없이 2개 그룹으로 나눔
kmeans.fit(customer_data)
print(f"그룹: {kmeans.labels_}")  # 자동으로 그룹 분류

[도입 - 실무 상황 스토리] 김개발 씨가 회사에서 새로운 프로젝트를 맡게 되었습니다. 고객 데이터를 분석하는 업무인데, 팀장님이 "지도학습과 비지도학습 중 어떤 걸 쓸지 생각해보세요"라고 말씀하셨습니다.

김개발 씨는 고민에 빠졌습니다. 점심시간에 박시니어 씨를 만나 고민을 털어놓았습니다.

"둘의 차이를 알아야 선택할 수 있을 텐데요." 박시니어 씨가 커피를 한 모금 마시며 설명을 시작했습니다. [개념 설명 - 비유로 쉽게] 그렇다면 지도학습비지도학습은 정확히 어떻게 다를까요?

쉽게 비유하자면, 지도학습은 마치 학교 수업과 같습니다. 선생님이 "이 문제의 답은 5입니다"라고 정답을 알려주면서 문제 푸는 방법을 가르칩니다.

학생은 많은 문제와 정답을 보면서 패턴을 익히고, 나중에 비슷한 문제가 나오면 풀 수 있게 됩니다. 반면 비지도학습은 퍼즐 조각을 맞추는 것과 비슷합니다.

완성된 그림(정답)은 보여주지 않지만, 비슷한 색깔이나 모양의 조각들을 스스로 찾아 그룹으로 묶습니다. 정답이 무엇인지는 모르지만, 데이터 사이의 유사성이나 구조를 발견하는 것이죠.

[지도학습의 특징] 지도학습에서는 반드시 정답 레이블이 필요합니다. 예를 들어 스팸 메일 분류기를 만든다면, 수천 개의 메일과 함께 "이것은 스팸", "이것은 정상"이라는 정답을 함께 제공해야 합니다.

모델은 이 정답을 보면서 "스팸 메일은 이런 특징이 있구나"를 학습합니다. 정답을 만드는 작업을 레이블링이라고 하는데, 이것이 생각보다 많은 시간과 비용이 듭니다.

사람이 일일이 메일을 읽고 스팸 여부를 표시해야 하기 때문입니다. 하지만 정확도가 높은 모델을 만들 수 있다는 장점이 있습니다.

[비지도학습의 특징] 비지도학습은 정답 없이 데이터의 숨겨진 구조를 찾습니다. 쇼핑몰 고객 데이터가 있다고 가정해봅시다.

나이, 구매 금액, 방문 빈도 등의 정보는 있지만, "이 고객은 VIP", "이 고객은 일반"이라는 레이블은 없습니다. 비지도학습 알고리즘은 비슷한 패턴을 가진 고객들을 자동으로 묶어줍니다.

"20대 저가 구매층", "40대 고가 구매층"처럼 자연스럽게 그룹이 나뉘는 것을 확인할 수 있습니다. 레이블링 작업이 필요 없어 비용이 적게 들지만, 결과를 해석하는 것은 사람의 몫입니다.

[코드 분석 - 지도학습] 위의 지도학습 코드를 살펴보겠습니다. 6번째 줄의 train_test_split 함수는 데이터를 학습용과 테스트용으로 나눕니다.

80%는 학습에 사용하고 20%는 나중에 성능을 확인하는 데 사용합니다. 12번째 줄에서 fit 함수를 호출할 때 X_train과 y_train을 함께 전달하는 것이 핵심입니다.

정답을 알려주면서 학습시키는 것이죠. 13번째 줄에서는 테스트 데이터로 정확도를 측정합니다.

모델이 본 적 없는 데이터를 얼마나 잘 맞추는지 확인하는 과정입니다. [코드 분석 - 비지도학습] 비지도학습 코드는 조금 다릅니다.

20번째 줄의 KMeans는 가장 유명한 클러스터링 알고리즘입니다. n_clusters=2는 데이터를 2개의 그룹으로 나누라는 의미입니다.

21번째 줄을 보면 fit 함수에 데이터만 전달합니다. 정답이 없기 때문입니다.

22번째 줄의 labels_를 출력하면 [0, 0, 1, 1]처럼 각 데이터가 어느 그룹에 속하는지 알 수 있습니다. 하지만 "0번 그룹이 젊은 층"이라는 해석은 사람이 데이터를 보고 판단해야 합니다.

[실무 활용 사례] 실제 프로젝트에서는 어떻게 선택할까요? 지도학습은 예측이 목표일 때 사용합니다.

"이 고객이 이탈할까?", "이 거래가 사기일까?", "이 환자가 병에 걸렸을까?"처럼 명확한 답을 원할 때 적합합니다. 금융권의 대출 심사, 의료 진단 보조 시스템 등이 대표적입니다.

비지도학습은 탐색이 목표일 때 유용합니다. "우리 고객들은 어떤 그룹으로 나뉠까?", "비정상적인 패턴은 없을까?"처럼 데이터의 구조를 파악하고 싶을 때 사용합니다.

마케팅 세분화, 이상 거래 탐지 등에 활용됩니다. [주의사항] 실무에서 흔히 하는 실수가 있습니다.

무조건 지도학습이 좋다고 생각하는 것입니다. 정답 데이터를 만드는 데 몇 달이 걸릴 수도 있습니다.

때로는 비지도학습으로 빠르게 인사이트를 얻는 것이 더 현명한 선택입니다. 반대로 비지도학습 결과를 맹신하는 것도 위험합니다.

알고리즘이 찾아낸 그룹이 비즈니스 관점에서 의미 있는지는 사람이 판단해야 합니다. [정리] 박시니어 씨의 설명을 들은 김개발 씨가 환하게 웃었습니다.

"그러니까 정답이 있으면 지도학습, 없으면 비지도학습이군요!" "맞아요. 하지만 실제로는 둘을 조합해서 사용하는 경우도 많아요." 박시니어 씨가 덧붙였습니다.

김개발 씨는 이제 프로젝트에서 어떤 방법을 선택할지 감이 잡혔습니다.

실전 팁

💡 - 정답 데이터가 있다면 무조건 지도학습부터 시도하세요

  • 비지도학습 결과는 반드시 도메인 전문가와 함께 해석하세요
  • 프로젝트 초기에는 비지도학습으로 데이터를 탐색한 후, 지도학습으로 정교화하는 것도 좋은 전략입니다

3. 분류 문제 이해하기

어느 날 김개발 씨가 팀 회의에 참석했습니다. 팀장님이 "이번 프로젝트는 분류 문제를 다룹니다"라고 말씀하셨는데, 정확히 무엇을 의미하는지 헷갈렸습니다.

회의 후 박시니어 씨에게 물어보기로 했습니다.

분류 문제는 데이터를 미리 정해진 범주로 나누는 작업입니다. 마치 과일을 사과, 배, 포도로 분류하는 것처럼 명확한 카테고리가 있습니다.

스팸 메일 걸러내기, 이미지 속 동물 인식하기, 질병 진단하기 등이 모두 분류 문제입니다. 결과가 숫자가 아닌 범주라는 것이 핵심입니다.

다음 코드를 살펴봅시다.

# 이진 분류: 대출 승인 여부 예측
from sklearn.ensemble import RandomForestClassifier
import numpy as np

# 데이터: [나이, 연봉(만원), 신용점수]
X_train = [
    [25, 3000, 650],  # 승인
    [35, 5000, 720],  # 승인
    [22, 2000, 580],  # 거절
    [45, 8000, 800],  # 승인
]
y_train = ['승인', '승인', '거절', '승인']

# 모델 학습
model = RandomForestClassifier(random_state=42)
model.fit(X_train, y_train)

# 새로운 신청자 예측
new_applicant = [[30, 4500, 700]]
result = model.predict(new_applicant)
print(f"대출 심사 결과: {result[0]}")

[도입 - 실무 상황 스토리] 김개발 씨가 소속된 팀에서 새로운 프로젝트를 시작했습니다. 은행 앱에서 대출 신청자를 자동으로 심사하는 기능을 만드는 것이었습니다.

기존에는 직원이 일일이 서류를 검토했지만, 이제 AI가 1차 판단을 하게 됩니다. "이게 바로 분류 문제예요." 박시니어 씨가 설명했습니다.

김개발 씨는 여전히 회귀 문제와 뭐가 다른지 궁금했습니다. [개념 설명 - 비유로 쉽게] 그렇다면 분류 문제란 정확히 무엇일까요?

쉽게 비유하자면, 분류는 마치 우체국 직원이 편지를 분류하는 것과 같습니다. 서울행, 부산행, 제주행처럼 미리 정해진 박스가 있고, 편지를 보고 어느 박스에 넣을지 결정합니다.

편지를 "서울과 부산의 중간쯤"에 넣는 것은 말이 안 됩니다. 반드시 하나의 박스를 선택해야 합니다.

머신러닝에서도 마찬가지입니다. 승인 또는 거절, 스팸 또는 정상, 개 또는 고양이처럼 명확히 구분되는 범주 중 하나를 선택하는 것이 분류 문제의 본질입니다.

[이진 분류와 다중 분류] 분류 문제는 크게 두 가지로 나뉩니다. 이진 분류는 두 개의 범주 중 하나를 선택하는 것입니다.

예/아니오, 참/거짓, 합격/불합격처럼 선택지가 둘뿐입니다. 대출 승인 여부, 스팸 메일 판별, 질병 유무 판단 등이 대표적입니다.

실무에서 가장 자주 마주치는 유형이기도 합니다. 다중 분류는 세 개 이상의 범주 중에서 선택합니다.

뉴스 기사를 정치/경제/스포츠/연예로 분류하거나, 붓꽃을 세 가지 품종으로 구분하는 것이 예시입니다. 이진 분류보다 복잡하지만 원리는 같습니다.

[왜 중요한가] 분류 문제는 실생활에서 정말 많이 사용됩니다. 여러분이 매일 사용하는 이메일의 스팸 필터, 그것이 바로 분류 문제입니다.

병원에서 X-ray 이미지를 보고 폐렴 여부를 판단하는 AI 시스템도 분류 문제입니다. 은행에서 이상 거래를 탐지하는 것, SNS에서 욕설 댓글을 자동으로 걸러내는 것도 모두 분류입니다.

통계에 따르면 실무 머신러닝 프로젝트의 60% 이상이 분류 문제를 다룬다고 합니다. 그만큼 보편적이고 중요한 주제입니다.

[코드 분석 - 단계별 설명] 위의 코드를 자세히 살펴보겠습니다. 6번째 줄부터 10번째 줄까지는 학습 데이터를 준비합니다.

각 신청자의 나이, 연봉, 신용점수를 특징으로 사용합니다. 11번째 줄의 y_train이 핵심입니다.

각 데이터가 어느 범주에 속하는지 정답을 담고 있습니다. 15번째 줄의 RandomForestClassifier는 분류에 특화된 강력한 알고리즘입니다.

수십 개의 결정 트리를 만들어 투표로 결정하는 앙상블 기법을 사용합니다. 16번째 줄에서 학습이 일어나며, 모델은 "연봉이 높고 신용점수가 높으면 승인"같은 패턴을 찾아냅니다.

19번째 줄에서 새로운 신청자의 데이터를 넣으면, 20번째 줄에서 predict 함수가 '승인' 또는 '거절'이라는 범주를 반환합니다. 숫자가 아닌 카테고리가 나온다는 점을 주목하세요.

[실무 활용 사례] 실제 프로젝트에서 분류 문제는 어떻게 쓰일까요? 쿠팡이나 네이버 쇼핑 같은 이커머스 플랫폼에서는 상품 리뷰가 긍정인지 부정인지 자동으로 분류합니다.

수백만 개의 리뷰를 사람이 일일이 읽을 수 없기 때문입니다. 분류 모델이 "이 리뷰는 불만 사항을 담고 있음"을 판단하면, 고객 서비스 팀에 자동으로 전달됩니다.

의료 분야에서는 더 중요합니다. 피부 사진을 찍으면 양성 종양인지 악성 종양인지 분류해주는 앱도 있습니다.

물론 최종 판단은 의사가 하지만, 1차 스크리닝 도구로 유용하게 쓰입니다. [평가 방법] 분류 모델이 잘 작동하는지 어떻게 확인할까요?

가장 기본적인 지표는 정확도입니다. 전체 예측 중에서 맞춘 비율을 의미합니다.

하지만 정확도만으로는 부족할 때가 많습니다. 예를 들어 암 진단에서는 "암인데 정상이라고 판단하는 실수"가 "정상인데 암이라고 판단하는 실수"보다 훨씬 심각합니다.

이럴 때는 정밀도, 재현율, F1 점수 같은 지표를 함께 봅니다. 상황에 따라 어떤 실수가 더 치명적인지 고려해야 합니다.

[주의사항] 초보자들이 흔히 하는 실수가 있습니다. 불균형 데이터를 간과하는 것입니다.

예를 들어 스팸 메일이 1%밖에 안 되는 데이터로 학습하면, 모델이 "전부 정상 메일"이라고 찍어도 99% 정확도가 나옵니다. 겉보기에는 잘 작동하는 것 같지만 실제로는 쓸모없는 모델입니다.

이런 경우 데이터를 오버샘플링하거나 가중치를 조정하는 기법을 사용해야 합니다. [정리] 박시니어 씨의 설명을 들은 김개발 씨가 끄덕였습니다.

"그러니까 결과가 범주로 나오면 분류 문제고, 숫자로 나오면 회귀 문제인 거죠?" "정확해요!" 박시니어 씨가 웃으며 답했습니다. 김개발 씨는 이제 자신 있게 프로젝트를 시작할 수 있을 것 같았습니다.

실전 팁

💡 - 데이터가 불균형하다면 stratify 옵션을 사용해 train_test_split을 하세요

  • 이진 분류에서는 predict_proba로 확률값을 확인하면 더 많은 정보를 얻을 수 있습니다
  • 정확도만 보지 말고 혼동 행렬(confusion matrix)을 그려보세요

4. 회귀 문제 이해하기

며칠 후 김개발 씨는 새로운 업무를 받았습니다. 아파트 매물 정보를 보고 가격을 예측하는 모델을 만드는 것이었습니다.

"이건 분류 문제가 아닌 것 같은데..." 박시니어 씨에게 물어보니 "회귀 문제"라는 답이 돌아왔습니다.

회귀 문제는 연속적인 숫자 값을 예측하는 작업입니다. 마치 온도계가 정확한 온도를 측정하는 것처럼, 구체적인 수치를 예측합니다.

집값 예측, 주식 가격 예측, 내일 기온 예측 등이 회귀 문제입니다. 분류와 달리 결과가 연속된 실수값이라는 것이 핵심입니다.

다음 코드를 살펴봅시다.

# 회귀 문제: 아파트 가격 예측
from sklearn.linear_model import LinearRegression

# 데이터: [면적(평), 층수, 역세권(분)]
X_train = [
    [32, 5, 3],   # 5억
    [45, 15, 1],  # 7억
    [28, 3, 10],  # 4억
    [60, 20, 2],  # 10억
]
y_train = [5.0, 7.0, 4.0, 10.0]  # 실제 가격(억원)

# 모델 학습: 선형 회귀
model = LinearRegression()
model.fit(X_train, y_train)

# 새로운 아파트 가격 예측
new_apt = [[40, 10, 5]]
predicted_price = model.predict(new_apt)
print(f"예상 가격: {predicted_price[0]:.2f}억원")

# 각 특징의 중요도 확인
print(f"계수: {model.coef_}")  # 면적, 층수, 역세권의 가중치

[도입 - 실무 상황 스토리] 김개발 씨가 부동산 앱 개발 프로젝트에 투입되었습니다. 사용자가 아파트 정보를 입력하면 적정 가격을 알려주는 기능을 만들어야 했습니다.

처음에는 가격대를 "저가", "중가", "고가"로 분류하려고 했습니다. 박시니어 씨가 코드를 보더니 고개를 저었습니다.

"분류가 아니라 회귀 문제로 접근해야 해요. 정확한 금액을 예측해야죠." [개념 설명 - 비유로 쉽게] 그렇다면 회귀 문제란 정확히 무엇일까요?

쉽게 비유하자면, 회귀는 마치 저울로 무게를 재는 것과 같습니다. "무겁다" 또는 "가볍다"가 아니라 "정확히 3.7kg"이라는 구체적인 숫자를 알려줍니다.

키를 측정할 때도 "큰 편"이 아니라 "173.5cm"라고 정확히 말합니다. 머신러닝의 회귀 문제도 마찬가지입니다.

범주가 아닌 연속된 숫자를 예측하는 것이 목표입니다. 5억 또는 6억이 아니라 5.7억원처럼 소수점까지 포함한 값을 얻을 수 있습니다.

[분류와의 차이] 분류와 회귀는 언제 구분할까요? 핵심은 결과값의 성격입니다.

"합격/불합격"처럼 몇 가지 범주 중 하나라면 분류입니다. "87점"처럼 연속된 숫자라면 회귀입니다.

같은 학생 성적이라도 "A/B/C/D/F 등급 예측"은 분류이고, "0~100점 예측"은 회귀입니다. 실무에서 헷갈릴 때는 이렇게 생각하세요.

예측값 사이에 중간값이 의미가 있나요? 합격과 불합격 사이에 중간은 없습니다. 하지만 5억과 6억 사이에는 5.5억이 존재합니다.

중간값이 의미 있다면 회귀 문제입니다. [선형 회귀의 원리] 가장 기본적인 회귀 알고리즘은 선형 회귀입니다.

중학교 때 배운 일차함수를 기억하시나요? y = ax + b에서 최적의 a와 b를 찾는 것이 선형 회귀의 핵심입니다.

데이터를 가장 잘 설명하는 직선(또는 평면)을 그리는 것이죠. 예를 들어 "아파트 가격 = 0.1 × 면적 + 0.05 × 층수 - 0.1 × 역세권 거리"같은 식을 찾아냅니다.

실제로는 더 복잡하지만 기본 아이디어는 이렇습니다. [코드 분석 - 단계별 설명] 위의 코드를 자세히 분석해보겠습니다.

5번째 줄부터 9번째 줄까지는 특징 데이터입니다. 면적, 층수, 역세권 거리라는 세 가지 요소를 숫자로 표현했습니다.

10번째 줄의 y_train이 중요한데, 분류와 달리 실수값을 담고 있습니다. '승인', '거절'같은 범주가 아니라 5.0, 7.0같은 연속된 숫자입니다.

14번째 줄의 LinearRegression은 선형 회귀 모델입니다. 가장 간단하지만 강력한 회귀 알고리즘입니다.

15번째 줄에서 학습이 일어나며, 각 특징과 가격의 관계를 수학적으로 계산합니다. 19번째 줄의 predict 결과를 보면 6.23억원처럼 소수점이 있는 값이 나옵니다.

이것이 회귀의 특징입니다. 23번째 줄의 coef_는 각 특징의 가중치를 보여줍니다.

면적이 1평 늘어날 때 가격이 얼마나 오르는지 알 수 있습니다. [실무 활용 사례] 실제 비즈니스에서는 어떻게 활용될까요?

온라인 쇼핑몰에서는 내일 예상 매출액을 회귀 모델로 예측합니다. 요일, 날씨, 이벤트 여부 등을 입력하면 구체적인 금액이 나옵니다.

이를 바탕으로 재고를 준비하고 직원을 배치합니다. 제조업에서는 설비 수명을 예측합니다.

기계의 진동, 온도, 가동 시간 등을 보고 "앞으로 147시간 후 고장날 것"이라고 미리 알려줍니다. 갑작스러운 생산 중단을 막을 수 있습니다.

스타트업에서는 **사용자 생애 가치(LTV)**를 예측합니다. 신규 가입자의 행동 패턴을 보고 "이 사용자가 평생 쓸 금액은 12만원"이라고 계산합니다.

마케팅 예산을 효율적으로 배분하는 데 도움이 됩니다. [평가 방법] 회귀 모델의 성능은 어떻게 측정할까요?

분류처럼 "맞다/틀리다"로 판단할 수 없습니다. 실제값이 5억인데 4.8억으로 예측했다면 틀린 걸까요?

얼마나 틀렸는지가 중요합니다. 가장 많이 쓰는 지표는 **평균 제곱 오차(MSE)**와 **결정 계수(R²)**입니다.

MSE는 예측값과 실제값의 차이를 제곱해서 평균 낸 것입니다. 작을수록 좋습니다.

R²는 모델이 데이터를 얼마나 잘 설명하는지 나타내며, 1에 가까울수록 우수합니다. [주의사항] 회귀 문제에서 주의할 점이 있습니다.

이상치에 매우 민감합니다. 실수로 아파트 가격을 500억원으로 잘못 입력한 데이터가 하나만 있어도 모델 전체가 망가질 수 있습니다.

데이터 전처리 단계에서 이상치를 제거하거나, 로버스트 회귀 같은 알고리즘을 사용해야 합니다. 또한 선형 관계가 없는 데이터에 선형 회귀를 쓰면 성능이 나쁩니다.

변수 간 관계가 복잡하다면 다항 회귀, 랜덤 포레스트 회귀 같은 알고리즘을 고려하세요. [정리] 박시니어 씨가 김개발 씨의 코드를 보고 고개를 끄덕였습니다.

"이제 제대로 이해했네요. 범주가 아니라 연속된 값을 예측하는 거죠?" "맞아요.

회귀는 '얼마나'를 예측하는 문제예요." 김개발 씨는 이제 집값 예측 모델을 자신 있게 만들 수 있게 되었습니다.

실전 팁

💡 - 데이터를 표준화(StandardScaler)하면 선형 회귀의 성능이 좋아집니다

  • 예측값이 음수가 나오지 않게 하려면 predict 후 max(0, value)로 처리하세요
  • 시각화로 실제값 vs 예측값을 그려보면 모델의 문제를 쉽게 발견할 수 있습니다

5. 학습 데이터와 테스트 데이터

김개발 씨가 첫 머신러닝 모델을 완성했습니다. 학습 데이터로 테스트했더니 정확도가 100%나 나왔습니다.

기쁜 마음에 박시니어 씨에게 보여주자, 예상 밖의 반응이 돌아왔습니다. "이건 제대로 된 평가가 아니에요."

학습 데이터는 모델을 가르치는 데 사용하는 데이터입니다. 테스트 데이터는 학습이 끝난 후 성능을 평가하는 데 사용합니다.

마치 학생이 공부할 때 쓴 문제집과 실제 시험 문제가 달라야 하는 것처럼, 두 데이터는 반드시 분리해야 합니다. 이렇게 해야 모델의 진짜 실력을 알 수 있습니다.

다음 코드를 살펴봅시다.

# 데이터 분리의 중요성
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris

# 데이터 로드
iris = load_iris()
X, y = iris.data, iris.target

# 잘못된 방법: 전체 데이터로 학습하고 평가
model_wrong = DecisionTreeClassifier()
model_wrong.fit(X, y)
print(f"잘못된 평가: {model_wrong.score(X, y):.2f}")  # 1.00 (100%)

# 올바른 방법: 데이터 분리 (80% 학습, 20% 테스트)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

model_correct = DecisionTreeClassifier()
model_correct.fit(X_train, y_train)  # 학습 데이터로만 학습
print(f"올바른 평가: {model_correct.score(X_test, y_test):.2f}")  # 0.97

[도입 - 실무 상황 스토리] 김개발 씨가 자랑스럽게 결과를 보여주었습니다. "보세요!

정확도 100%예요!" 화면에는 완벽한 수치가 표시되어 있었습니다. 하지만 박시니어 씨의 표정은 밝지 않았습니다.

"학습할 때 쓴 데이터로 평가하셨네요?" 박시니어 씨가 물었습니다. "네, 그게 뭐가 문제인가요?" 김개발 씨는 이해가 되지 않았습니다.

박시니어 씨가 재미있는 예시를 들려주었습니다. [개념 설명 - 비유로 쉽게] 그렇다면 왜 데이터를 분리해야 할까요?

쉽게 비유하자면, 이것은 마치 시험을 준비하는 학생과 같습니다. 수학 문제집으로 공부한 학생이 같은 문제집의 문제로 시험을 본다면 어떨까요?

당연히 100점을 받을 것입니다. 하지만 그 학생이 진짜 수학을 잘하는지는 알 수 없습니다.

문제를 외웠을 뿐일 수도 있으니까요. 진짜 실력을 알려면 한 번도 보지 못한 새로운 문제를 풀어봐야 합니다.

머신러닝도 똑같습니다. 모델이 학습할 때 본 데이터로 평가하면 의미가 없습니다.

새로운 데이터에서도 잘 작동하는지 확인해야 합니다. [왜 중요한가] 실무에서는 이것이 더욱 치명적입니다.

김개발 씨가 만든 모델이 회사 서비스에 배포되었다고 가정해봅시다. 개발 단계에서는 100% 정확했지만, 실제 고객 데이터에서는 60%밖에 못 맞춥니다.

고객 불만이 쏟아지고, 서비스 신뢰도가 떨어집니다. 이런 문제를 미리 발견하려면 테스트 데이터가 필수입니다.

실제로 많은 AI 스타트업이 이런 실수로 실패했습니다. 데모에서는 완벽했는데 현장에서는 형편없는 성능을 보인 것이죠.

이를 과적합 문제라고 하는데, 조금 뒤에 자세히 다루겠습니다. [데이터 분리 비율] 그렇다면 얼마나 나눠야 할까요?

가장 일반적인 비율은 80:20입니다. 전체 데이터의 80%를 학습에 사용하고, 20%를 테스트에 남겨둡니다.

데이터가 충분히 많다면 70:30이나 60:40도 괜찮습니다. 반대로 데이터가 매우 적다면 90:10을 쓰기도 합니다.

중요한 것은 테스트 데이터가 너무 적어서도, 너무 많아서도 안 된다는 점입니다. 너무 적으면 평가가 부정확하고, 너무 많으면 학습할 데이터가 부족해집니다.

프로젝트 상황에 맞게 조정하세요. [코드 분석 - 잘못된 방법] 11번째 줄부터 13번째 줄까지 잘못된 평가 방법을 보여줍니다.

전체 데이터 X, y로 모델을 학습시킨 후(12번째 줄), 같은 데이터로 평가합니다(13번째 줄). 결과는 당연히 거의 100%가 나옵니다.

모델이 이미 본 데이터니까요. 하지만 이것은 모델의 암기 능력만 측정한 것이지, 일반화 능력을 본 것이 아닙니다.

[코드 분석 - 올바른 방법] 16번째 줄의 train_test_split 함수가 핵심입니다. 이 함수는 데이터를 무작위로 섞어서 80%와 20%로 나눕니다.

random_state=42는 같은 방식으로 섞어지도록 하는 옵션입니다. 나중에 실험을 재현할 때 유용합니다.

20번째 줄에서 X_train과 y_train으로만 학습합니다. 테스트 데이터는 절대 보여주지 않습니다.

21번째 줄에서 X_test와 y_test로 평가하면 진짜 성능을 알 수 있습니다. 결과가 97%로 조금 낮아졌지만, 이것이 현실적인 수치입니다.

[검증 데이터의 등장] 실무에서는 한 단계 더 나아갑니다. 학습 데이터와 테스트 데이터만으로도 부족할 때가 있습니다.

모델을 개선하는 과정에서 테스트 데이터를 여러 번 보게 되면, 결국 테스트 데이터에 맞춰 조정하게 됩니다. 이를 방지하려고 검증 데이터를 추가로 분리합니다.

일반적으로 60% 학습, 20% 검증, 20% 테스트로 나눕니다. 학습 데이터로 훈련하고, 검증 데이터로 모델을 조정하고, 마지막에 딱 한 번만 테스트 데이터로 최종 평가합니다.

[교차 검증] 데이터가 부족할 때는 교차 검증을 사용합니다. 데이터를 5개 그룹으로 나눈 후, 4개로 학습하고 1개로 테스트하는 과정을 5번 반복합니다.

매번 다른 그룹을 테스트용으로 쓰는 것이죠. 5번의 결과를 평균 내면 더 신뢰할 수 있는 평가를 얻을 수 있습니다.

단점은 시간이 5배 걸린다는 것입니다. 데이터가 충분하다면 단순 분할로도 충분합니다.

[실무 활용 사례] 실제 프로젝트에서는 어떻게 관리할까요? 대부분의 회사는 데이터를 세 가지 버전으로 관리합니다.

학습용, 검증용, 테스트용을 완전히 분리해서 보관합니다. 특히 테스트 데이터는 프로젝트 막바지까지 절대 열어보지 않습니다.

마지막 최종 점검용으로만 사용합니다. 금융권이나 의료 분야에서는 더 엄격합니다.

테스트 데이터를 별도 팀에서 관리하고, 모델 개발자가 접근조차 할 수 없게 합니다. 이렇게 해야 공정한 평가가 가능합니다.

[주의사항] 데이터 분리할 때 흔한 실수가 있습니다. 시간 순서가 중요한 데이터를 무작위로 섞으면 안 됩니다.

예를 들어 주식 가격 예측 모델을 만든다면, 과거 데이터로 학습하고 미래 데이터로 테스트해야 합니다. 미래 데이터를 학습에 섞으면 현실에서는 불가능한 정보를 사용하는 것이 됩니다.

또한 중복 데이터를 조심하세요. 같은 데이터가 학습과 테스트에 모두 들어가면 의미가 없습니다.

데이터 전처리 단계에서 중복을 먼저 제거하세요. [정리] 박시니어 씨의 설명을 들은 김개발 씨가 모델을 다시 평가했습니다.

이번에는 테스트 데이터를 제대로 분리했고, 정확도는 97%가 나왔습니다. "100%보다 낮지만, 이게 진짜 성능이군요." "맞아요.

현실적인 수치를 아는 것이 더 중요해요." 박시니어 씨가 웃으며 답했습니다. 김개발 씨는 이제 제대로 된 평가 방법을 배웠습니다.

실전 팁

💡 - stratify 옵션을 사용하면 각 클래스 비율이 학습/테스트에 골고루 분포됩니다

  • 시계열 데이터는 TimeSeriesSplit을 사용하세요
  • 테스트 데이터는 프로젝트 끝까지 단 한 번만 사용하는 것이 원칙입니다

6. 과적합과 과소적합 개념

김개발 씨의 모델이 학습 데이터에서는 99% 정확도를 보였지만, 테스트 데이터에서는 65%밖에 나오지 않았습니다. "뭔가 잘못된 것 같은데..." 박시니어 씨가 김개발 씨의 화면을 보더니 바로 알아챘습니다.

"과적합이네요."

과적합은 모델이 학습 데이터를 너무 완벽하게 외워버린 상태입니다. 마치 시험 문제를 달달 외운 학생처럼, 본 적 없는 문제는 못 푸는 것과 같습니다.

반대로 과소적합은 모델이 너무 단순해서 패턴을 제대로 배우지 못한 상태입니다. 적절한 균형을 찾는 것이 머신러닝의 핵심입니다.

다음 코드를 살펴봅시다.

# 과적합과 과소적합 비교
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_moons

# 데이터 생성
X, y = make_moons(n_samples=200, noise=0.3, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

# 과소적합: 너무 단순한 모델
model_underfit = DecisionTreeClassifier(max_depth=1)
model_underfit.fit(X_train, y_train)
print(f"과소적합 - 학습: {model_underfit.score(X_train, y_train):.2f}")
print(f"과소적합 - 테스트: {model_underfit.score(X_test, y_test):.2f}")

# 과적합: 너무 복잡한 모델
model_overfit = DecisionTreeClassifier(max_depth=None)  # 제한 없음
model_overfit.fit(X_train, y_train)
print(f"과적합 - 학습: {model_overfit.score(X_train, y_train):.2f}")
print(f"과적합 - 테스트: {model_overfit.score(X_test, y_test):.2f}")

# 적절한 모델: 균형잡힌 복잡도
model_good = DecisionTreeClassifier(max_depth=5)
model_good.fit(X_train, y_train)
print(f"적절함 - 학습: {model_good.score(X_train, y_train):.2f}")
print(f"적절함 - 테스트: {model_good.score(X_test, y_test):.2f}")

[도입 - 실무 상황 스토리] 김개발 씨가 며칠 동안 공들여 만든 모델이었습니다. 학습 데이터에서는 거의 완벽한 성능을 보여서 자신감이 넘쳤습니다.

하지만 실제 서비스에 적용하자 성능이 급격히 떨어졌습니다. 사용자들의 불만이 쏟아졌고, 팀장님이 회의를 소집했습니다.

"개발 환경에서는 왜 잘 됐는데 실제로는 안 되는 거죠?" 김개발 씨는 말문이 막혔습니다. 박시니어 씨가 조용히 말했습니다.

"전형적인 과적합 문제예요." [개념 설명 - 비유로 쉽게] 그렇다면 과적합이란 정확히 무엇일까요? 쉽게 비유하자면, 과적합은 마치 시험 문제를 통째로 암기한 학생과 같습니다.

"1번 문제의 답은 3번, 2번 문제의 답은 1번"처럼 달달 외웠습니다. 똑같은 시험지가 나오면 100점을 받지만, 숫자나 문구가 조금만 바뀌어도 전혀 못 풉니다.

진짜 개념을 이해한 것이 아니라 문제 자체를 외운 것이기 때문입니다. 머신러닝 모델도 마찬가지입니다.

학습 데이터의 세세한 부분까지 전부 기억해버리면, 새로운 데이터에서는 제대로 작동하지 않습니다. 이것이 과적합의 본질입니다.

[과소적합이란] 반대로 과소적합도 문제입니다. 이번에는 공부를 너무 안 한 학생을 상상해보세요.

교과서 첫 페이지만 읽고 시험을 봅니다. 당연히 학습 문제도 못 풀고, 시험 문제도 못 풉니다.

모델이 너무 단순해서 데이터의 패턴을 제대로 배우지 못한 상태가 과소적합입니다. 과소적합은 학습 데이터에서도 성능이 나쁩니다.

테스트 데이터 성능도 당연히 나쁩니다. 모델이 아직 학습할 능력이 부족한 것이죠.

[과적합을 발견하는 방법] 어떻게 알 수 있을까요? 가장 확실한 신호는 학습 성능과 테스트 성능의 큰 차이입니다.

학습 데이터에서 99%인데 테스트 데이터에서 70%라면 과적합을 의심해야 합니다. 학습을 계속할수록 학습 성능은 올라가는데 테스트 성능은 떨어진다면 거의 확실합니다.

그래프로 그려보면 더 명확합니다. 학습 곡선과 검증 곡선의 간격이 점점 벌어지면 과적합이 진행되고 있다는 뜻입니다.

[코드 분석 - 과소적합] 11번째 줄의 max_depth=1은 결정 트리의 깊이를 1로 제한합니다. 너무 단순한 모델이라 복잡한 패턴을 배울 수 없습니다.

결과를 보면 학습 데이터에서도 75%, 테스트 데이터에서도 73%처럼 둘 다 성능이 낮습니다. 모델이 학습 능력 자체가 부족한 상태입니다.

[코드 분석 - 과적합] 17번째 줄의 max_depth=None은 제한을 두지 않는다는 뜻입니다. 트리가 엄청나게 깊어질 수 있고, 학습 데이터의 노이즈까지 전부 학습합니다.

결과는 학습 데이터에서 100%, 테스트 데이터에서 78%처럼 큰 차이가 납니다. 학습 데이터를 완벽하게 암기했지만 일반화에는 실패한 것입니다.

[코드 분석 - 적절한 모델] 23번째 줄의 max_depth=5가 균형잡힌 선택입니다. 충분히 복잡해서 패턴을 배울 수 있지만, 너무 복잡하지 않아 과적합을 피합니다.

결과는 학습 87%, 테스트 85%처럼 비슷한 수준입니다. 학습도 잘했고 일반화도 잘한 이상적인 상태입니다.

[과적합 해결 방법] 과적합을 막으려면 어떻게 해야 할까요? 첫 번째 방법은 더 많은 데이터를 모으는 것입니다.

데이터가 많을수록 모델이 암기하기 어렵고, 진짜 패턴을 배우게 됩니다. 하지만 현실적으로 데이터 수집이 어려울 때가 많습니다.

두 번째는 모델을 단순화하는 것입니다. 트리의 깊이를 제한하거나, 뉴럴 네트워크의 레이어를 줄입니다.

세 번째는 정규화를 사용하는 것입니다. 모델이 너무 복잡해지는 것을 수학적으로 방지합니다.

네 번째는 드롭아웃이나 조기 종료 같은 기법입니다. 학습 중간에 일부러 노드를 꺼버리거나, 성능이 더 이상 좋아지지 않으면 학습을 멈춥니다.

[실무 활용 사례] 실제 프로젝트에서는 어떻게 대처할까요? 대부분의 머신러닝 엔지니어는 검증 데이터를 주시하면서 학습합니다.

매 에포크마다 검증 성능을 기록하고, 성능이 떨어지기 시작하면 바로 중단합니다. 이를 조기 종료라고 합니다.

또한 교차 검증으로 여러 번 평가해서 과적합 여부를 확인합니다. 한 번의 운 좋은 결과를 믿지 않고, 평균적인 성능을 봅니다.

[주의사항] 초보자들이 흔히 하는 실수가 있습니다. 테스트 성능이 낮으면 무조건 과적합이라고 생각하는 것입니다.

과소적합일 수도 있습니다. 학습 성능도 함께 봐야 정확히 판단할 수 있습니다.

학습 성능도 낮으면 과소적합, 학습 성능만 높으면 과적합입니다. 또한 과적합을 두려워한 나머지 너무 단순한 모델만 쓰는 것도 문제입니다.

적절한 복잡도를 찾는 것이 핵심입니다. [정리] 박시니어 씨가 김개발 씨의 코드를 수정해주었습니다.

모델의 복잡도를 조절하고 조기 종료를 적용하자, 테스트 성능이 크게 개선되었습니다. "과적합과 과소적합의 균형을 찾는 것이 머신러닝의 본질이에요." 박시니어 씨의 말에 김개발 씨는 깊이 공감했습니다.

실전 팁

💡 - 학습 곡선을 그려보면 과적합 여부를 시각적으로 쉽게 파악할 수 있습니다

  • GridSearchCV로 여러 복잡도를 자동으로 테스트하세요
  • 과적합이 의심되면 데이터 증강(augmentation)을 시도해보세요

7. 머신러닝 워크플로우

김개발 씨가 처음부터 끝까지 머신러닝 프로젝트를 혼자 진행하게 되었습니다. "어디서부터 시작해야 하지?" 막막했습니다.

박시니어 씨가 노트에 순서도를 그려주며 설명을 시작했습니다.

머신러닝 워크플로우는 프로젝트를 진행하는 단계적 과정입니다. 문제 정의부터 데이터 수집, 전처리, 모델 학습, 평가, 배포까지 체계적인 순서가 있습니다.

각 단계를 건너뛰면 나중에 큰 문제가 생기므로, 순서를 지키는 것이 중요합니다. 실무에서는 이 과정을 여러 번 반복하며 모델을 개선합니다.

다음 코드를 살펴봅시다.

# 완전한 머신러닝 워크플로우 예제
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report

# 1. 데이터 수집 및 로드
data = pd.DataFrame({
    'age': [25, 30, 45, 35, 50, 23, 38, 42],
    'income': [3000, 5000, 8000, 6000, 9500, 2800, 7000, 8200],
    'loan_approved': [0, 1, 1, 1, 1, 0, 1, 1]
})

# 2. 데이터 탐색 및 전처리
X = data[['age', 'income']]
y = data['loan_approved']

# 3. 데이터 분리
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42
)

# 4. 특징 스케일링 (전처리)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# 5. 모델 선택 및 학습
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train_scaled, y_train)

# 6. 모델 평가
y_pred = model.predict(X_test_scaled)
print(classification_report(y_test, y_pred))

# 7. 새로운 데이터 예측 (배포 단계)
new_data = scaler.transform([[28, 4000]])
prediction = model.predict(new_data)
print(f"새 신청자 대출 승인: {'예' if prediction[0] == 1 else '아니오'}")

[도입 - 실무 상황 스토리] 김개발 씨가 드디어 독립적으로 프로젝트를 맡게 되었습니다. 고객 이탈 예측 모델을 혼자서 처음부터 끝까지 만들어야 했습니다.

의욕은 넘쳤지만 어디서부터 손을 대야 할지 막막했습니다. 박시니어 씨가 회의실로 불러 화이트보드에 큰 그림을 그려주었습니다.

"머신러닝은 요리와 비슷해요. 레시피를 따라가면 됩니다." [1단계: 문제 정의] 가장 먼저 할 일은 문제를 명확히 하는 것입니다.

"고객 이탈을 예측한다"는 막연한 목표가 아니라, 구체적으로 정의해야 합니다. "3개월 내 해지할 고객을 80% 정확도로 예측"처럼 측정 가능한 목표를 세웁니다.

이것이 분류 문제인지 회귀 문제인지도 결정합니다. 비즈니스 팀과 대화하면서 왜 이 문제를 풀어야 하는지, 예측 결과를 어떻게 활용할지도 파악합니다.

기술적으로 완벽해도 비즈니스 가치가 없으면 의미가 없습니다. [2단계: 데이터 수집] 다음은 데이터를 모으는 단계입니다.

데이터베이스에서 고객 정보를 추출합니다. 나이, 구매 이력, 접속 빈도, 고객센터 문의 횟수 등 예측에 도움이 될 만한 모든 정보를 긁어옵니다.

외부 데이터가 필요하면 API로 가져오거나 크롤링을 합니다. 중요한 것은 정답 레이블도 함께 수집하는 것입니다.

과거에 실제로 이탈한 고객과 유지한 고객의 데이터가 있어야 지도학습이 가능합니다. [3단계: 데이터 탐색 및 전처리] **EDA(탐색적 데이터 분석)**가 핵심입니다.

데이터를 눈으로 확인하고, 그래프를 그려봅니다. 이상치는 없는지, 결측값은 얼마나 되는지, 각 특징의 분포는 어떤지 파악합니다.

이 단계에서 많은 인사이트를 얻을 수 있습니다. 전처리도 이 단계에서 합니다.

결측값을 평균값으로 채우거나, 범주형 데이터를 숫자로 인코딩합니다. 스케일이 다른 특징들을 표준화하는 것도 중요합니다.

나이는 0100, 소득은 01억처럼 범위가 다르면 모델이 학습하기 어렵습니다. [4단계: 데이터 분리] 앞에서 배운 대로 학습/검증/테스트 데이터로 나눕니다.

일반적으로 60:20:20 비율을 사용합니다. 이때 stratify 옵션을 사용해 각 클래스 비율이 균등하게 분포되도록 합니다.

시계열 데이터라면 시간 순서를 고려해서 나눠야 합니다. [5단계: 모델 선택 및 학습] 드디어 모델을 학습시킵니다.

처음에는 간단한 모델로 시작합니다. 로지스틱 회귀나 결정 트리 같은 기본 모델로 베이스라인을 만듭니다.

그 다음 랜덤 포레스트, XGBoost 같은 복잡한 모델을 시도합니다. 여러 모델을 비교하면서 어떤 것이 이 문제에 적합한지 찾아냅니다.

하이퍼파라미터도 GridSearchCV로 자동으로 최적화합니다. [6단계: 모델 평가] 테스트 데이터로 최종 성능을 측정합니다.

정확도만 보지 말고 혼동 행렬, 정밀도, 재현율, F1 점수를 모두 확인합니다. 비즈니스 관점에서 어떤 지표가 중요한지 생각합니다.

고객 이탈 예측에서는 "이탈할 고객을 놓치는 것"이 치명적이므로 재현율이 중요할 수 있습니다. [7단계: 모델 배포] 마지막으로 실제 서비스에 적용합니다.

모델을 저장하고, API 서버를 만들어 다른 시스템에서 호출할 수 있게 합니다. 실시간 예측이 필요하면 서버에 모델을 로드해두고, 배치 예측이면 주기적으로 스크립트를 돌립니다.

배포 후에도 모니터링이 필수입니다. 시간이 지나면서 데이터 분포가 바뀌면 모델 성능이 떨어질 수 있습니다.

주기적으로 재학습하는 파이프라인을 구축합니다. [코드 분석 - 완전한 워크플로우] 위의 코드는 실제 워크플로우를 단계별로 보여줍니다.

9번째 줄부터 데이터를 준비하고, 15-16번째 줄에서 특징과 레이블을 분리합니다. 20번째 줄에서 train_test_split으로 데이터를 나누고, 25-27번째 줄에서 스케일러로 전처리합니다.

주의할 점은 fit_transform과 transform의 차이입니다. 학습 데이터에는 fit_transform을 쓰지만, 테스트 데이터에는 transform만 씁니다.

테스트 데이터의 통계로 스케일링하면 안 되기 때문입니다. 30-31번째 줄에서 모델 학습, 34-35번째 줄에서 평가, 38-40번째 줄에서 실제 예측을 합니다.

새 데이터도 같은 스케일러로 변환해야 한다는 점이 중요합니다. [반복적 개선] 실무에서는 이 과정을 여러 번 반복합니다.

첫 번째 모델의 성능이 목표에 못 미치면, 다시 2단계로 돌아가 더 많은 데이터를 모읍니다. 또는 3단계로 가서 새로운 특징을 만들어냅니다.

5단계에서 다른 알고리즘을 시도하기도 합니다. 이런 반복을 통해 점진적으로 모델을 개선합니다.

완벽한 모델을 한 번에 만들 수는 없습니다. 작은 개선을 계속 쌓아가는 것이 현실적인 접근입니다.

[실무 팁] 경험 많은 엔지니어들의 조언입니다. 전체 워크플로우를 빠르게 한 번 돌려보는 것이 좋습니다.

데이터 10%만 써서라도 끝까지 진행해보세요. 병목이 어디인지, 어떤 부분이 어려운지 미리 파악할 수 있습니다.

또한 버전 관리를 철저히 하세요. 어떤 데이터로, 어떤 전처리로, 어떤 모델로, 어떤 하이퍼파라미터로 학습했는지 기록합니다.

MLflow나 Weights & Biases 같은 도구가 유용합니다. [정리] 박시니어 씨의 설명을 들은 김개발 씨가 자신감을 얻었습니다.

"이제 어떤 순서로 진행해야 할지 알겠어요!" "맞아요. 처음에는 시간이 걸려도 이 순서를 따라가세요.

익숙해지면 자연스러워질 거예요." 김개발 씨는 이제 프로젝트를 체계적으로 시작할 준비가 되었습니다.

실전 팁

💡 - Jupyter Notebook으로 각 단계를 셀로 나눠서 작업하면 관리하기 편합니다

  • 데이터 전처리 코드는 함수로 만들어두면 재사용할 때 편리합니다
  • 모델을 joblib이나 pickle로 저장해서 나중에 다시 로드할 수 있게 하세요

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#Python#MachineLearning#Scikit-learn#Supervised#Unsupervised

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스

머신러닝 개념 소개 완벽 가이드 | CodeDeck | CodeDeck