🤖

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

⚠️

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

이미지 로딩 중...

로지스틱 회귀로 예측하기 완벽 가이드 - 슬라이드 1/8
A

AI Generated

2025. 12. 17. · 6 Views

로지스틱 회귀로 예측하기 완벽 가이드

머신러닝 분류 문제의 기본인 로지스틱 회귀를 처음부터 끝까지 배웁니다. 모델 학습부터 예측, 확률 계산, 그리고 모델 저장까지 실전 예제로 익히는 초급자 친화 가이드입니다.


목차

  1. 로지스틱_회귀란
  2. LogisticRegression_임포트
  3. fit으로_모델_학습
  4. predict로_예측하기
  5. predict_proba로_확률_얻기
  6. 간단한_예측_테스트
  7. 모델_저장과_로드

1. 로지스틱 회귀란

김개발 씨는 입사한 지 2주 된 주니어 데이터 분석가입니다. 팀장님이 고객 이탈 예측 프로젝트를 맡기며 말했습니다.

"로지스틱 회귀로 먼저 시작해보세요." 김개발 씨는 멍했습니다. 로지스틱 회귀가 뭐지?

로지스틱 회귀는 한마디로 Yes/No를 예측하는 머신러닝 알고리즘입니다. 마치 의사가 환자의 증상을 보고 "병에 걸렸나요?

아닌가요?"를 판단하는 것과 같습니다. 이것을 제대로 이해하면 분류 문제의 기초를 탄탄히 다질 수 있습니다.

다음 코드를 살펴봅시다.

# 로지스틱 회귀의 기본 개념 이해하기
# 입력 데이터: 공부 시간
# 출력: 합격 여부 (0 또는 1)

# 예시 데이터
study_hours = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
passed = [0, 0, 0, 0, 1, 1, 1, 1, 1, 1]

# 로지스틱 회귀는 이 데이터를 학습하여
# 새로운 공부 시간이 주어지면 합격 확률을 예측합니다
# 예: 5.5시간 공부하면 합격할까? -> 약 70% 확률

김개발 씨는 회의실에서 팀장님의 설명을 듣기 시작했습니다. "로지스틱 회귀는 우리 팀에서 가장 많이 쓰는 도구 중 하나예요." 팀장님은 화이트보드에 그림을 그리기 시작했습니다.

가로축에는 공부 시간, 세로축에는 합격 여부를 표시했습니다. 점들이 0과 1에 흩어져 있었습니다.

그렇다면 로지스틱 회귀란 정확히 무엇일까요? 쉽게 비유하자면, 로지스틱 회귀는 마치 경험 많은 의사와 같습니다.

의사는 수많은 환자를 진료하며 패턴을 익힙니다. "이 정도 증상이면 보통 감기구나." 이처럼 로지스틱 회귀도 데이터의 패턴을 학습하여 새로운 상황에서 결과를 예측합니다.

로지스틱 회귀가 없던 시절에는 어땠을까요? 개발자들은 복잡한 if-else 조건문을 수백 줄 작성해야 했습니다.

"만약 공부 시간이 5시간 이상이고, 출석률이 80% 이상이면 합격..." 이런 규칙을 일일이 손으로 만들었습니다. 더 큰 문제는 데이터가 늘어날수록 규칙이 더 복잡해진다는 것이었습니다.

바로 이런 문제를 해결하기 위해 로지스틱 회귀가 등장했습니다. 로지스틱 회귀를 사용하면 자동으로 패턴을 찾아냅니다.

개발자가 일일이 규칙을 만들 필요가 없습니다. 또한 확률로 결과를 알려주기 때문에 얼마나 확신하는지도 알 수 있습니다.

무엇보다 해석이 쉽다는 큰 이점이 있습니다. 팀장님이 설명을 이어갔습니다.

"로지스틱 회귀는 선형 회귀와 이름이 비슷하지만 완전히 다른 용도로 쓰입니다." 선형 회귀는 연속된 숫자를 예측합니다. "집값이 3억 2천만 원일 것이다." 하지만 로지스틱 회귀는 범주를 예측합니다.

"이 메일은 스팸이다/아니다." 여기서 핵심은 시그모이드 함수입니다. 이 함수는 모든 입력값을 0과 1 사이의 값으로 변환합니다.

마치 압력솥이 아무리 센 불을 받아도 일정 압력 이상 올라가지 않는 것처럼, 시그모이드 함수도 값을 0과 1 사이로 제한합니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 이커머스 서비스를 운영한다고 가정해봅시다. 고객의 구매 이력, 방문 횟수, 체류 시간 등을 입력값으로 넣으면 "이 고객이 이번 달에 구매할까?"를 예측할 수 있습니다.

많은 기업에서 이런 패턴을 적극적으로 활용하고 있습니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 모든 문제에 로지스틱 회귀를 적용하려는 것입니다. 로지스틱 회귀는 클래스가 2개인 문제에 가장 적합합니다.

3개 이상의 클래스가 있다면 다른 방법을 고려해야 할 수 있습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

팀장님의 설명을 들은 김개발 씨는 고개를 끄덕였습니다. "아, 그래서 고객 이탈 예측에 쓰는 거군요!" 로지스틱 회귀를 제대로 이해하면 분류 문제의 기초를 탄탄히 다질 수 있습니다.

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

실전 팁

💡 - 로지스틱 회귀는 이진 분류(Yes/No)에 가장 적합합니다

  • 결과를 확률로 해석할 수 있어 비즈니스 의사결정에 유용합니다
  • 간단하지만 강력한 베이스라인 모델로 활용하세요

2. LogisticRegression 임포트

김개발 씨는 첫 번째 단계를 시작하기로 했습니다. "일단 코드부터 작성해보자." 하지만 터미널 앞에서 막막해졌습니다.

어디서부터 시작해야 할까요?

LogisticRegression은 scikit-learn 라이브러리에서 제공하는 클래스입니다. 마치 주방에서 요리를 시작하기 전에 필요한 도구를 꺼내놓는 것처럼, 머신러닝도 필요한 모듈을 먼저 임포트해야 합니다.

올바른 임포트는 코드 작성의 첫걸음입니다.

다음 코드를 살펴봅시다.

# scikit-learn에서 로지스틱 회귀 모델 가져오기
from sklearn.linear_model import LogisticRegression

# 데이터 전처리를 위한 numpy도 함께 임포트
import numpy as np

# 모델 생성 (기본 설정)
model = LogisticRegression()

# 모델 생성 (옵션 지정)
# max_iter: 최대 반복 횟수
# random_state: 재현 가능한 결과를 위한 시드값
model = LogisticRegression(max_iter=1000, random_state=42)

김개발 씨는 선배 개발자 박시니어 씨에게 물어봤습니다. "scikit-learn이 뭔가요?" 박시니어 씨가 웃으며 대답했습니다.

"우리 회사에서 가장 많이 쓰는 머신러닝 라이브러리예요. 줄여서 sklearn이라고도 부르죠." scikit-learn은 파이썬에서 가장 인기 있는 머신러닝 라이브러리입니다.

수백 개의 알고리즘이 체계적으로 정리되어 있어서 개발자들이 쉽게 사용할 수 있습니다. 쉽게 비유하자면, scikit-learn은 마치 잘 정돈된 공구함과 같습니다.

드라이버가 필요하면 드라이버 칸을 열고, 망치가 필요하면 망치 칸을 엽니다. 이처럼 로지스틱 회귀가 필요하면 linear_model 모듈에서 LogisticRegression을 꺼내 쓰면 됩니다.

임포트 방법이 정해지지 않았던 시절에는 어땠을까요? 개발자들은 각자 다른 방식으로 코드를 작성했습니다.

어떤 사람은 전체 모듈을 임포트하고, 어떤 사람은 필요한 클래스만 임포트했습니다. 코드 리뷰가 지옥이었습니다.

더 큰 문제는 메모리 낭비였습니다. 쓰지도 않을 함수들까지 모두 불러오니 프로그램이 무거워졌습니다.

바로 이런 문제를 해결하기 위해 from ... import 문법이 널리 쓰이게 되었습니다.

이 방식을 사용하면 필요한 것만 정확히 가져올 수 있습니다. 코드도 깔끔해지고 메모리도 절약됩니다.

또한 어디서 왔는지 명확하게 알 수 있어서 협업할 때 유리합니다. 위의 코드를 한 줄씩 살펴보겠습니다.

첫 번째 줄에서 sklearn.linear_model 모듈에서 LogisticRegression 클래스를 가져옵니다. 이 부분이 핵심입니다.

다음으로 numpy를 임포트하는데, 이는 데이터를 배열 형태로 다루기 위해서입니다. 마지막으로 모델 객체를 생성합니다.

모델을 생성할 때 두 가지 옵션을 주목해야 합니다. max_iter는 모델이 학습할 때 최대 몇 번까지 반복할지 정합니다.

기본값은 100인데, 복잡한 데이터에서는 부족할 수 있어서 1000으로 늘려주는 것이 좋습니다. random_state는 랜덤 시드값입니다.

이 값을 고정하면 코드를 여러 번 실행해도 같은 결과가 나옵니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 A/B 테스트 결과를 분석한다고 가정해봅시다. 같은 코드를 여러 팀원이 돌려도 같은 결과가 나와야 합니다.

이때 random_state=42처럼 시드값을 고정해두면 재현 가능한 실험이 됩니다. 많은 데이터 팀에서 이런 방식을 표준으로 삼고 있습니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 max_iter를 너무 크게 설정하는 것입니다.

1000000처럼 과도하게 크게 설정하면 학습 시간만 길어질 뿐 성능 향상은 미미합니다. 따라서 적절한 값을 찾아 설정해야 합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.

"아, random_state를 설정하는 이유가 있었네요!" 올바른 임포트는 코드 작성의 첫걸음입니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - random_state=42는 관습적으로 많이 쓰는 시드값입니다

  • max_iter 경고가 뜨면 값을 늘려보세요
  • 필요한 것만 임포트하는 습관을 들이세요

3. fit으로 모델 학습

모델을 만들었으니 이제 학습시켜야 합니다. 김개발 씨는 데이터를 준비하고 코드 에디터를 열었습니다.

"어떻게 학습시키지?" 막막한 순간, 박시니어 씨가 다가왔습니다.

fit() 메서드는 모델에게 데이터를 학습시키는 함수입니다. 마치 학생이 교과서를 읽으며 공부하는 것처럼, 모델도 데이터를 보며 패턴을 익힙니다.

X는 입력 데이터, y는 정답 레이블을 의미합니다.

다음 코드를 살펴봅시다.

import numpy as np
from sklearn.linear_model import LogisticRegression

# 학습 데이터 준비
# X: 공부 시간 (2차원 배열이어야 함)
X = np.array([[1], [2], [3], [4], [5], [6], [7], [8]])
# y: 합격 여부 (0: 불합격, 1: 합격)
y = np.array([0, 0, 0, 0, 1, 1, 1, 1])

# 모델 생성
model = LogisticRegression()

# 모델 학습 (핵심!)
model.fit(X, y)

# 학습 완료 메시지가 자동으로 출력되지 않으므로
# 확인용 출력
print("모델 학습이 완료되었습니다!")

박시니어 씨가 김개발 씨의 화면을 보며 말했습니다. "모델을 만들었으면 이제 학습시켜야죠.

fit 메서드를 사용하면 됩니다." 김개발 씨는 고개를 갸우뚱했습니다. "fit이요?

뭔가 딱 맞춘다는 느낌인데..." 그렇습니다. fit이라는 단어는 영어로 "맞추다", "적합하게 하다"라는 뜻입니다.

모델이 데이터에 꼭 맞도록 조정한다는 의미입니다. 쉽게 비유하자면, fit은 마치 옷 수선사가 옷을 몸에 맞게 고치는 것과 같습니다.

처음에는 헐렁하거나 작은 옷이지만, 수선사가 치수를 재고 바느질하면서 점점 몸에 맞게 됩니다. 이처럼 모델도 처음에는 아무것도 모르지만, fit을 통해 데이터의 패턴을 익혀갑니다.

fit 메서드가 없던 시절에는 어땠을까요? 개발자들은 가중치편향을 직접 계산해야 했습니다.

경사하강법을 손으로 구현하고, 학습률을 조정하고, 반복문을 돌리는 모든 과정을 일일이 작성했습니다. 코드가 수백 줄로 늘어났고, 버그도 자주 발생했습니다.

바로 이런 문제를 해결하기 위해 fit() 메서드가 제공됩니다. fit()을 사용하면 한 줄로 학습이 완료됩니다.

복잡한 수학 계산은 라이브러리가 알아서 처리합니다. 또한 최적화된 알고리즘을 사용하기 때문에 속도도 빠릅니다.

무엇보다 코드가 깔끔해져서 유지보수하기 쉽습니다. 위의 코드를 한 줄씩 살펴보겠습니다.

먼저 X 배열을 보면 2차원 배열 형태입니다. [[1], [2], [3], ...]처럼 대괄호가 이중으로 씌워져 있습니다.

이것이 핵심입니다. scikit-learn은 항상 2차원 입력을 기대하기 때문입니다.

다음으로 y 배열은 1차원 배열로, 각 샘플의 정답을 담고 있습니다. 마지막으로 model.fit(X, y)를 호출하면 학습이 시작됩니다.

학습이 진행되는 동안 무슨 일이 벌어질까요? 모델은 내부적으로 경사하강법이라는 알고리즘을 사용합니다.

처음에는 무작위로 가중치를 설정하고, 예측 결과와 실제 정답을 비교합니다. 그 차이를 줄이는 방향으로 가중치를 조금씩 조정합니다.

이 과정을 수백 번 반복하면서 점점 정확해집니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 신용카드 사기 탐지 시스템을 만든다고 가정해봅시다. 과거의 거래 내역과 사기 여부 레이블을 X, y로 준비합니다.

model.fit(X, y)를 실행하면 모델이 사기 패턴을 학습합니다. 이후 새로운 거래가 들어오면 사기인지 아닌지 판단할 수 있게 됩니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 X를 1차원 배열로 넘기는 것입니다.

[1, 2, 3, 4]처럼 만들면 에러가 발생합니다. 반드시 [[1], [2], [3], [4]]처럼 2차원으로 만들어야 합니다.

reshape(-1, 1)을 사용하면 쉽게 변환할 수 있습니다. 또 다른 실수는 데이터 크기가 안 맞는 경우입니다.

X의 행 개수와 y의 원소 개수가 같아야 합니다. 만약 X가 8개 샘플인데 y가 7개면 에러가 납니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.

"아, fit 한 줄이면 되는구나!" fit()을 제대로 이해하면 머신러닝 학습의 핵심을 파악할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - X는 항상 2차원 배열로 준비하세요 (reshape 활용)

  • X와 y의 크기가 일치하는지 확인하세요
  • fit()은 모델 내부 상태를 변경하므로 재학습 시 주의하세요

4. predict로 예측하기

모델 학습이 끝났습니다. 김개발 씨는 신이 났습니다.

"이제 예측을 해볼까?" 하지만 어떤 메서드를 써야 할지 몰랐습니다. 다시 박시니어 씨에게 물었습니다.

predict() 메서드는 학습된 모델로 새로운 데이터를 예측하는 함수입니다. 마치 시험을 본 학생이 새로운 문제를 풀어보는 것과 같습니다.

입력값을 넣으면 0 또는 1의 클래스를 반환합니다.

다음 코드를 살펴봅시다.

import numpy as np
from sklearn.linear_model import LogisticRegression

# 학습 데이터
X_train = np.array([[1], [2], [3], [4], [5], [6], [7], [8]])
y_train = np.array([0, 0, 0, 0, 1, 1, 1, 1])

# 모델 학습
model = LogisticRegression()
model.fit(X_train, y_train)

# 새로운 데이터로 예측하기
X_test = np.array([[2.5], [5.5], [9]])
predictions = model.predict(X_test)

# 결과 출력
print(f"예측 결과: {predictions}")
# 예측 결과: [0 1 1]

박시니어 씨가 웃으며 대답했습니다. "학습이 끝났으면 이제 predict로 예측하면 됩니다.

간단해요." 김개발 씨는 코드를 작성해보았습니다. 신기하게도 모델이 바로 답을 내놓았습니다.

**predict()**는 머신러닝의 하이라이트입니다. 학습은 준비 단계일 뿐, 실제로 사용하는 것은 예측입니다.

쉽게 비유하자면, predict는 마치 훈련받은 탐지견과 같습니다. 탐지견은 훈련 기간 동안 특정 냄새를 익힙니다.

이후 현장에 투입되면 그 냄새를 맡고 짖어서 알려줍니다. 이처럼 모델도 학습 단계에서 패턴을 익히고, 예측 단계에서 그 패턴을 활용합니다.

predict가 없던 시절에는 어땠을까요? 개발자들은 학습된 가중치를 직접 꺼내서 계산해야 했습니다.

행렬 곱셈을 하고, 시그모이드 함수를 적용하고, 임계값과 비교하는 모든 과정을 손으로 구현했습니다. 실수하기 쉽고, 코드도 지저분했습니다.

바로 이런 문제를 해결하기 위해 predict() 메서드가 제공됩니다. predict()를 사용하면 한 줄로 예측이 완료됩니다.

내부 계산은 라이브러리가 처리합니다. 또한 배치 예측이 가능해서 한 번에 여러 샘플을 예측할 수 있습니다.

무엇보다 일관성이 보장됩니다. 같은 입력에는 항상 같은 출력이 나옵니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 X_test라는 새로운 데이터를 준비합니다.

이것은 모델이 한 번도 보지 못한 데이터입니다. [[2.5], [5.5], [9]]처럼 세 개의 샘플이 있습니다.

다음으로 model.predict(X_test)를 호출하면 예측이 시작됩니다. 결과는 numpy 배열로 반환됩니다.

결과를 해석해봅시다. 첫 번째 샘플 2.5시간은 0으로 예측되었습니다.

학습 데이터를 보면 4시간 이하는 대부분 불합격이었으니 합리적입니다. 두 번째 샘플 5.5시간은 1로 예측되었습니다.

5시간 이상부터 합격 경향이 있으니 맞습니다. 세 번째 샘플 9시간도 당연히 1입니다.

실제 현업에서는 어떻게 활용할까요? 예를 들어 이메일 스팸 필터를 만든다고 가정해봅시다.

수천 개의 이메일로 모델을 학습시킵니다. 이후 새로운 이메일이 도착하면 특성을 추출하고 predict()로 스팸 여부를 판단합니다.

스팸이면 자동으로 스팸함으로 이동시킵니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 학습 전에 예측을 시도하는 것입니다. fit()을 호출하지 않고 predict()를 호출하면 에러가 발생합니다.

"NotFittedError: This model is not fitted yet."라는 메시지가 나옵니다. 또 다른 실수는 입력 형태를 맞추지 않는 것입니다.

학습할 때 X가 1개의 특성을 가졌다면, 예측할 때도 1개의 특성을 넣어야 합니다. 특성 개수가 다르면 에러가 납니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.

"아, 이렇게 간단하게 예측할 수 있구나!" predict()를 제대로 이해하면 머신러닝 모델을 실전에 활용할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 반드시 fit() 후에 predict()를 호출하세요

  • 입력 데이터의 특성 개수를 학습 시와 동일하게 유지하세요
  • 배치 예측으로 성능을 최적화하세요

5. predict proba로 확률 얻기

김개발 씨는 예측 결과를 보고 있었습니다. 0과 1만 나오는 것이 아쉬웠습니다.

"얼마나 확신하는지도 알 수 있으면 좋을 텐데..." 박시니어 씨가 지나가다 말했습니다. "predict_proba를 써보세요."

predict_proba() 메서드는 각 클래스에 속할 확률을 반환하는 함수입니다. 마치 의사가 "70% 확률로 감기입니다"라고 말하는 것과 같습니다.

단순히 Yes/No가 아니라 확신의 정도를 알 수 있습니다.

다음 코드를 살펴봅시다.

import numpy as np
from sklearn.linear_model import LogisticRegression

# 학습 데이터
X_train = np.array([[1], [2], [3], [4], [5], [6], [7], [8]])
y_train = np.array([0, 0, 0, 0, 1, 1, 1, 1])

# 모델 학습
model = LogisticRegression()
model.fit(X_train, y_train)

# 확률 예측하기
X_test = np.array([[2.5], [5.5], [9]])
probabilities = model.predict_proba(X_test)

# 결과 출력
print("각 클래스 확률:")
print(probabilities)
# [[0.85, 0.15], [0.35, 0.65], [0.05, 0.95]]
# 각 행: [클래스 0 확률, 클래스 1 확률]

김개발 씨는 predict_proba를 실행해봤습니다. 놀라운 결과가 나왔습니다.

단순히 0과 1이 아니라 확률이 나왔습니다. 박시니어 씨가 설명했습니다.

"실무에서는 확률이 더 유용할 때가 많아요. 임계값을 조정할 수도 있고, 불확실한 케이스를 따로 처리할 수도 있죠." **predict_proba()**는 로지스틱 회귀의 숨은 보석입니다.

predict()보다 더 많은 정보를 제공합니다. 쉽게 비유하자면, predict_proba는 마치 날씨 예보와 같습니다.

"내일 비가 옵니다"라고만 말하는 것보다 "70% 확률로 비가 옵니다"라고 말하는 것이 더 유용합니다. 우산을 꼭 챙길지, 접이식으로 할지 판단할 수 있기 때문입니다.

확률 정보가 없던 시절에는 어땠을까요? 모델은 단순히 0 또는 1만 반환했습니다.

경계선 근처의 애매한 케이스와 확실한 케이스를 구분할 방법이 없었습니다. "이 환자는 60% 확률로 양성입니다"와 "95% 확률로 양성입니다"는 완전히 다른 의미인데, 둘 다 그냥 1로 표시되었습니다.

바로 이런 문제를 해결하기 위해 predict_proba() 메서드가 제공됩니다. predict_proba()를 사용하면 확신도를 알 수 있습니다.

임계값을 0.5가 아닌 다른 값으로 조정할 수도 있습니다. 또한 불확실한 샘플을 사람이 직접 검토하도록 분류할 수도 있습니다.

무엇보다 비즈니스 의사결정에 유용합니다. 위의 코드를 한 줄씩 살펴보겠습니다.

model.predict_proba(X_test)를 호출하면 2차원 배열이 반환됩니다. 각 행은 하나의 샘플에 대응되고, 각 열은 클래스에 대응됩니다.

첫 번째 열은 클래스 0의 확률, 두 번째 열은 클래스 1의 확률입니다. 두 확률을 더하면 항상 1이 됩니다.

결과를 자세히 해석해봅시다. 첫 번째 샘플 [0.85, 0.15]는 클래스 0일 확률이 85%, 클래스 1일 확률이 15%입니다.

불합격일 가능성이 높지만 완전히 확실하지는 않습니다. 두 번째 샘플 [0.35, 0.65]는 합격일 확률이 65%입니다.

경계선 근처라 애매합니다. 세 번째 샘플 [0.05, 0.95]는 합격일 확률이 95%로 거의 확실합니다.

실제 현업에서는 어떻게 활용할까요? 예를 들어 대출 심사 시스템을 만든다고 가정해봅시다.

승인 확률이 90% 이상이면 자동 승인, 10% 이하면 자동 거절, 그 사이는 심사역이 직접 검토합니다. 이렇게 하면 효율성과 정확성을 모두 잡을 수 있습니다.

의료 진단 시스템에서도 마찬가지입니다. 암일 확률이 80% 이상이면 정밀 검사를 권장하고, 50-80%는 재검사, 50% 이하는 정상으로 분류합니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 확률을 과신하는 것입니다.

모델이 95% 확률로 예측했다고 해서 정말 95% 정확하다는 뜻은 아닙니다. 모델의 보정 상태에 따라 달라집니다.

또 다른 실수는 인덱싱을 잘못하는 것입니다. probabilities[:, 1]로 클래스 1의 확률만 추출할 수 있는데, [:, 0]과 헷갈리기 쉽습니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.

"아, 확률 정보가 이렇게 유용하구나!" predict_proba()를 제대로 이해하면 더 섬세한 의사결정을 내릴 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 확률의 합은 항상 1입니다

  • [:, 1]로 양성 클래스 확률만 추출하세요
  • 임계값을 조정하여 precision과 recall을 최적화하세요

6. 간단한 예측 테스트

김개발 씨는 지금까지 배운 내용을 종합해보고 싶었습니다. "처음부터 끝까지 한번에 실행해보자." 전체 워크플로우를 코드로 작성하기 시작했습니다.

전체 워크플로우는 데이터 준비부터 예측까지의 모든 단계를 포함합니다. 마치 요리의 전체 레시피처럼, 각 단계를 순서대로 실행하면 완성된 결과물을 얻을 수 있습니다.

실전에서 가장 많이 사용하는 패턴입니다.

다음 코드를 살펴봅시다.

import numpy as np
from sklearn.linear_model import LogisticRegression

# 1단계: 데이터 준비
X_train = np.array([[1], [2], [3], [4], [5], [6], [7], [8]])
y_train = np.array([0, 0, 0, 0, 1, 1, 1, 1])

# 2단계: 모델 생성 및 학습
model = LogisticRegression(random_state=42)
model.fit(X_train, y_train)

# 3단계: 새로운 데이터로 예측
X_new = np.array([[2.5], [5.5]])
predictions = model.predict(X_new)
probabilities = model.predict_proba(X_new)

# 4단계: 결과 출력
for i, (pred, prob) in enumerate(zip(predictions, probabilities)):
    print(f"샘플 {i+1}: 예측={pred}, 확률={prob[1]:.2f}")

김개발 씨는 코드를 실행해봤습니다. 모든 단계가 순조롭게 진행되었고, 깔끔한 결과가 출력되었습니다.

박시니어 씨가 코드를 보고 칭찬했습니다. "좋아요!

전체 흐름을 제대로 이해했네요." 전체 워크플로우를 이해하는 것은 머신러닝의 핵심입니다. 개별 함수를 아는 것과 전체 과정을 이해하는 것은 다릅니다.

쉽게 비유하자면, 워크플로우는 마치 자동차 운전과 같습니다. 핸들 돌리는 법, 브레이크 밟는 법을 각각 아는 것도 중요하지만, 실제로 도로를 달리려면 전체 흐름을 체득해야 합니다.

시동 걸고, 기어 넣고, 출발하고, 운전하고, 주차하는 일련의 과정을 자연스럽게 수행해야 합니다. 체계적인 워크플로우가 없던 시절에는 어땠을까요?

개발자들은 매번 다른 순서로 코드를 작성했습니다. 어떤 사람은 모델을 먼저 만들고 데이터를 나중에 준비했습니다.

어떤 사람은 학습과 예측을 동시에 시도했습니다. 결과적으로 버그가 많았고, 협업도 어려웠습니다.

바로 이런 문제를 해결하기 위해 표준 워크플로우가 정립되었습니다. 표준 워크플로우를 따르면 실수를 줄일 수 있습니다.

단계가 명확하니 어디서 문제가 생겼는지 빠르게 찾을 수 있습니다. 또한 재사용성이 높아집니다.

한번 작성한 패턴을 다른 프로젝트에도 적용할 수 있습니다. 무엇보다 협업이 쉬워집니다.

위의 코드를 단계별로 살펴보겠습니다. 1단계에서는 numpy 배열로 데이터를 준비합니다.

실전에서는 pandas DataFrame에서 가져오는 경우가 많지만, 원리는 같습니다. 2단계에서는 모델을 생성하고 fit()으로 학습시킵니다.

random_state를 설정하여 재현 가능성을 확보합니다. 3단계가 핵심입니다.

새로운 데이터로 predict()와 predict_proba()를 동시에 호출합니다. 하나는 클래스를, 하나는 확률을 얻기 위해서입니다.

4단계에서는 zip을 사용하여 결과를 깔끔하게 출력합니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 고객 이탈 예측 시스템을 만든다고 가정해봅시다. 매일 밤 새로운 고객 데이터를 가져와서 이탈 확률을 계산합니다.

80% 이상이면 마케팅팀에 알림을 보내고, 50-80%는 모니터링 대상으로 분류합니다. 이런 시스템을 구축할 때 위의 워크플로우가 기본 골격이 됩니다.

또 다른 예시는 실시간 추천 시스템입니다. 사용자가 상품을 클릭할 때마다 특성을 추출하고, 모델에 입력하여 구매 확률을 계산합니다.

확률이 높은 상품을 상단에 노출합니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 학습 데이터로 성능을 평가하는 것입니다. X_train으로 학습한 모델을 X_train으로 평가하면 과대평가됩니다.

반드시 별도의 테스트 데이터를 준비해야 합니다. 또 다른 실수는 데이터 전처리를 빼먹는 것입니다.

실전 데이터는 결측치, 이상치, 스케일 문제 등이 있습니다. 이런 전처리 과정을 워크플로우에 포함시켜야 합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.

"아, 전체 흐름을 이해하니 자신감이 생기네요!" 전체 워크플로우를 제대로 이해하면 머신러닝 프로젝트를 독립적으로 수행할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 항상 train/test 데이터를 분리하세요

  • 전처리 단계를 워크플로우에 포함하세요
  • 재사용 가능한 함수로 만들어 관리하세요

7. 모델 저장과 로드

김개발 씨는 문득 궁금해졌습니다. "매번 모델을 새로 학습시켜야 하나?" 학습에는 시간이 걸리는데, 한번 학습한 모델을 저장해두면 좋을 것 같았습니다.

박시니어 씨에게 물었습니다.

모델 저장과 로드는 학습된 모델을 파일로 저장하고 나중에 불러오는 기능입니다. 마치 게임 세이브와 로드처럼, 진행 상황을 저장했다가 이어서 사용할 수 있습니다.

실전에서 필수적인 기능입니다.

다음 코드를 살펴봅시다.

import numpy as np
import joblib
from sklearn.linear_model import LogisticRegression

# 모델 학습
X_train = np.array([[1], [2], [3], [4], [5], [6], [7], [8]])
y_train = np.array([0, 0, 0, 0, 1, 1, 1, 1])
model = LogisticRegression(random_state=42)
model.fit(X_train, y_train)

# 모델 저장 (중요!)
joblib.dump(model, 'logistic_model.pkl')
print("모델이 저장되었습니다!")

# 모델 로드
loaded_model = joblib.load('logistic_model.pkl')
print("모델이 로드되었습니다!")

# 로드한 모델로 예측
X_test = np.array([[5.5]])
prediction = loaded_model.predict(X_test)
print(f"예측 결과: {prediction[0]}")

박시니어 씨가 웃으며 대답했습니다. "당연히 저장하고 불러와야죠!

매번 학습시키면 시간 낭비예요." 김개발 씨는 신기했습니다. 모델도 파일로 저장할 수 있다니!

모델 저장은 머신러닝 시스템의 핵심 인프라입니다. 학습과 배포를 분리할 수 있게 해줍니다.

쉽게 비유하자면, 모델 저장은 마치 요리를 냉동실에 보관하는 것과 같습니다. 한번 만든 요리를 냉동해두면 나중에 데우기만 하면 됩니다.

매번 처음부터 요리할 필요가 없습니다. 이처럼 모델도 한번 학습시켜 저장해두면 필요할 때마다 바로 불러와 사용할 수 있습니다.

모델 저장 기능이 없던 시절에는 어땠을까요? 개발자들은 매번 프로그램을 실행할 때마다 모델을 새로 학습시켜야 했습니다.

몇 초면 끝나는 간단한 모델은 괜찮지만, 몇 시간 걸리는 복잡한 모델은 악몽이었습니다. 서버를 재시작할 때마다 모델을 다시 학습시켜야 했고, 사용자는 그동안 기다려야 했습니다.

바로 이런 문제를 해결하기 위해 모델 직렬화 기능이 제공됩니다. 모델 직렬화를 사용하면 학습과 배포를 분리할 수 있습니다.

학습은 강력한 서버에서 하고, 배포는 가벼운 서버에서 할 수 있습니다. 또한 버전 관리가 가능해집니다.

모델을 날짜별로 저장해두고, 성능이 좋은 버전을 선택할 수 있습니다. 무엇보다 빠른 서비스가 가능합니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 joblib을 임포트합니다.

pickle도 사용할 수 있지만, joblib이 대용량 numpy 배열에 더 효율적입니다. **joblib.dump(model, 'filename.pkl')**로 모델을 저장합니다.

pkl은 pickle의 약자입니다. **joblib.load('filename.pkl')**로 모델을 불러옵니다.

중요한 점은 불러온 모델이 원본과 완전히 동일하다는 것입니다. 가중치, 편향, 모든 설정이 그대로 복원됩니다.

마치 게임을 세이브했다가 로드하면 정확히 그 시점부터 시작하는 것과 같습니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 머신러닝 API 서버를 운영한다고 가정해봅시다. 데이터 과학자가 모델을 학습시켜 pkl 파일로 저장합니다.

엔지니어는 그 파일을 서버에 배포하고, API 요청이 들어올 때마다 모델을 로드하여 예측합니다. 이렇게 하면 역할을 분담할 수 있습니다.

또 다른 예시는 A/B 테스트입니다. 모델 버전 A와 B를 각각 저장해두고, 사용자를 랜덤하게 나눠서 다른 모델로 서비스합니다.

나중에 성능을 비교하여 더 좋은 모델을 선택합니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 버전 불일치 문제입니다. scikit-learn 0.24에서 저장한 모델을 0.23에서 로드하려고 하면 에러가 날 수 있습니다.

버전을 일치시켜야 합니다. 또 다른 실수는 경로 문제입니다.

상대 경로로 저장하면 작업 디렉토리에 따라 파일을 찾지 못할 수 있습니다. 절대 경로나 환경 변수를 사용하는 것이 안전합니다.

보안도 중요합니다. pkl 파일은 임의의 Python 코드를 실행할 수 있어서 신뢰할 수 없는 출처의 파일을 로드하면 위험합니다.

반드시 출처를 확인해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다. "아, 이제 실전 시스템을 만들 수 있겠어요!" 모델 저장과 로드를 제대로 이해하면 머신러닝을 실제 서비스에 배포할 수 있습니다.

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

실전 팁

💡 - joblib이 pickle보다 효율적입니다

  • 모델과 함께 버전 정보도 저장하세요
  • 신뢰할 수 없는 pkl 파일은 로드하지 마세요

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

#Python#LogisticRegression#MachineLearning#Classification#Scikit-learn

댓글 (0)

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