kyejin0412 님의 블로그

Week 15-2 머신러닝 복습 본문

내일배움캠프-데이터분석

Week 15-2 머신러닝 복습

kyejin0412 2026. 1. 27. 21:32

오늘은 머신러닝 복습, 게임데이터 분석가 세션 자료 읽어보기를 진행했다.

머신러닝 기초 내용을 정리해보고자 한다.

 


 

머신러닝 순서

1) 데이터 수집/불러오기

2) 데이터 확인(타입/결측치/이상치)

3) 전처리(결측치 처리, 인코딩 등)

4) X/y 분리

5) 학습용/테스트용 분리

6) 모델 선택

7) 학습(fit)

8) 예측(predict)

9) 평가(성능 확인)

 

 

전처리의 3대 목표

  1. 학습 가능하게 만들기
    • NaN(빈 값), 문자열 같은 것 때문에 학습 자체가 안 되는 문제 해결
  2. 학습 품질 높이기(성능 향상)
    • 노이즈 제거, 의미 없는 컬럼 제거, 이상한 값 처리
  3. 학습 과정에서의 실수/오해 방지
    • 정답(y)이 섞이는 데이터 누수, 잘못된 타입, 잘못된 스케일 등 방지

 

데이터 기본 확인: head / info / describe

df.head()
df.info()
df.describe()

왜 확인해야 하나?

(1) 데이터 “모양” 확인 (행/열, 컬럼 이름)

  • 컬럼이 제대로 들어왔는지 확인
  • 분석/학습에 필요한 컬럼이 빠졌는지 체크

(2) 데이터 “타입” 확인 (int, float, object)

  • 숫자인 줄 알았는데 문자열일 수 있음 (예: "1,200")

(3) 결측치 여부 확인

  • NaN이 있으면 모델 학습이 실패하거나 예측이 왜곡됨

(4) 기초 통계로 이상한 값 탐지

  • 나이 평균이 200이면? 데이터 오류 가능성이 큼

 

결측치를 처리하지 않으면 생기는 문제

(1) 학습이 아예 안 되는 경우가 많다.

대부분의 scikit-learn 모델은 NaN을 포함하면 에러가 나거나 학습이 불가능하다.

 

(2) 계산 자체가 깨진다.

평균, 분산 같은 계산에서 NaN이 섞이면 결과가 이상해질 수 있다.

 

(3) 데이터가 “편향”될 수 있다.

NaN이 특정 그룹에서만 많이 발생한다면, 그 그룹의 특성이 학습에서 사라지고 예측이 왜곡될 수 있다.

 

 

결측치 처리 방법 & 각각의 이유

방법 A) 삭제(dropna)

df_drop = df.dropna()

왜 삭제하나?

  • NaN이 아주 적고, 삭제해도 데이터가 충분할 때
  • NaN이 있는 행이 “쓸모 없는 행”일 때

⚠️ 주의:

  • 데이터를 너무 많이 잃으면 학습 성능이 떨어짐
  • NaN이 특정 그룹에 몰려 있으면 편향 발생

 

방법 B) 평균/중앙값으로 채우기 (숫자형)

df["age"] = df["age"].fillna(df["age"].mean())
df["age"] = df["age"].fillna(df["age"].median())

왜 평균으로 채우나?

  • 숫자형 데이터에서 NaN을 “대표값”으로 메워
    전체 분포를 크게 흔들지 않기 위해서
  • 모델 학습이 가능해짐

평균 vs 중앙값

  • 평균(mean): 데이터가 정규분포처럼 큰 이상치가 없을 때
  • 중앙값(median): 이상치가 많을 때 더 안전

 

방법 C) 최빈값(mode)으로 채우기 (범주형)

df["gender"] = df["gender"].fillna(df["gender"].mode()[0])

왜 최빈값으로 채우나?

  • 범주형은 평균 같은 개념이 없으므로
    가장 자주 나오는 값으로 채워 “대표 범주”로 처리

⚠️ 단점:

  • 실제 결측이 의미가 있는 경우(예: 미응답)라면 정보 손실 가능
  • 이런 경우 Unknown 같은 별도 카테고리를 만들기도 함

 

 

범주형 데이터 인코딩 + 왜 해야 하는가?

왜 문자열을 못 쓰나?

머신러닝 모델(대부분)은 계산을 기반으로 학습.

그런데 "Seoul", "Busan" 같은 문자열은 덧셈/곱셈이 불가능함.

그래서 범주형 데이터는 반드시 숫자로 바꿔야 한다.

 

Label Encoding (간단 버전)

from sklearn.preprocessing import LabelEncoder

le = LabelEncoder()
df["gender_encoded"] = le.fit_transform(df["gender"])

왜 label encoding을 쓰나?

  • 간단하고 빠르게 숫자로 바꿀 수 있음
  • 이진 분류/순서가 있는 값에 비교적 적합

⚠️ 주의(중요!)

  • label encoding은 숫자에 “크기 의미”가 생길 수 있음
  • 예: Seoul=0, Busan=1이면 모델이 Busan이 더 크다고 오해할 수 있음
  • 그래서 일반 범주형(지역, 혈액형 등)에는 보통 One-Hot Encoding을 더 많이 씀

One-Hot Encoding (권장 방식)

df = pd.get_dummies(df, columns=["city"], drop_first=True)

왜 one-hot을 쓰나?

  • 범주 사이의 크기 관계를 만들지 않아서 안전
  • 지역, 직업, 혈액형 등 “서로 크기 비교가 의미 없는 값”에 적합

 

불필요한 컬럼 제거 + 왜 해야 하는가?

예: id, 이름 같은 컬럼

df = df.drop(columns=["id","name"])

왜 지우나?

  • id는 보통 “순번”이라서 패턴이 아니라 “식별자”임
  • 이름은 모델이 학습할 의미가 거의 없고, 오히려 노이즈가 됨

컬럼 제거의 효과

  • 모델이 중요한 변수에 집중할 가능성이 커짐
  • 학습 속도/성능 개선 가능
  • 과적합 위험 감소

 

전처리 순서가 왜 중요한가?

전처리는 “대충 아무 순서”로 하면 실수가 생긴다.

 

추천 흐름:

  1. 데이터 로드
  2. 데이터 확인(info/describe)
  3. 결측치 처리
  4. 범주형 인코딩
  5. 불필요 컬럼 제거
  6. X/y 분리

이유:

  • 결측치가 남아있으면 인코딩 단계에서 오류가 날 수 있음
  • y 분리보다 먼저 컬럼 삭제를 해버리면 y를 잃을 수도 있음
  • 전처리는 “모델 학습 가능 상태”를 만드는 과정이기 때문