🧩 머신러닝이란?
Machine Learning(ML)이란 학습 데이터의 패턴을 학습한 뒤 새로운 데이터에 대해 정확한 추론을 할 수 있는 알고리즘에 초점을 맞춘 AI의 하위 집합이다. (출처)

머신러닝(ML, 기계학습)이란 컴퓨터가 일일이 코드로 명령을 받지 않고, 방대한 데이터를 바탕으로 스스로 패턴을 찾아 학습하며 예측이나 결정을 내리게 하는 AI의 핵심 기술 분야다.

🧩 sklearn이란?
Scikit-learn은 NumPy, SciPy 및 matplotlib을 기반으로 구축된 예측 데이터 분석을 위한 간단하고 효율적인 도구이다. (scikit-learn 공식 웹사이트 발췌)
scikit-learn(a.k.a sklearn)은 파이썬에서 머신러닝을 쉽게 사용할 수 있게 해주는 대표적인 라이브러리로, 복잡한 머신러닝 알고리즘을 직접 구현할 필요 없이 비교적 간단한 API로 데이터 준비부터 모델 평가까지의 과정을 수행할 수 있게 해주는 도구다. 주로 데이터 분석과 예측 모델 개발이 많이 사용된다.
주요 기능
- 분류(Classification): 데이터를 범주로 나누기 (예: 이메일이 스팸인지 아닌지?)
- 회귀(Regression): 연속적인 숫자 예측 (예: 집값, 매출, 온도 예측)
- 군집화(Clustering): 비슷한 데이터끼리 그룹화 (예: 고객을 구매 성향에 따라 여러 그룹으로 분류)
- 차원 축소(Dimensionality Reduction): 많은 변수의 데이터를 더 적은 변수로 압축 (예: PCA)
- 데이터 전처리(Preprocessing): 결측치 처리, 정규화, 인코딩 등
- 모델 평가 및 검증: 정확도 측정, 교차 검증, 하이퍼파라미터 튜닝
사용 예시
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
# 예제 데이터 불러오기
iris = load_iris()
X = iris.data
y = 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)
# 예측
y_pred = model.predict(X_test)
# 성능 평가
print(accuracy_score(y_test, y_pred)) # 1.0
🧩 머신러닝 실습하기
sklearn을 사용해 머신러닝 전처리 → 학습 → 평가 → 예측 과정을 진행해 보자. 목표는 다음으로 설정한다.
게임 시작 전 픽/밴/소환사 주문 정보를 보고 팀1이 이길지 예측하기
1. 라이브러리 불러오기
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder
from sklearn.linear_model import LogisticRegression
from sklearn.dummy import DummyClassifier
from sklearn.metrics import (
accuracy_score,
classification_report,
confusion_matrix,
ConfusionMatrixDisplay,
roc_auc_score
)
2. 데이터 불러오기 및 타깃 만들기
df = pd.read_csv("dataset/games.csv")
print(df.shape) # (51490, 61)
# winner 이진 변환
# winner가 1이면 팀1 승리 -> 1
# winner가 2이면 팀2 승리 -> 0
df["target"] = (df["winner"] == 1).astype(int)
3. 데이터 누수 변수 제거
이번 목표는 게임 시작 전 승패 예측이므로 경기 결과가 나온 뒤에 알 수 있는 정보는 사용하면 안 된다.
# 제외할 누수 변수들
leakage_cols = [
"gameId",
"creationTime",
"gameDuration",
"winner",
"target",
"firstBlood",
"firstTower",
"firstInhibitor",
"firstBaron",
"firstDragon",
"firstRiftHerald",
"t1_towerKills",
"t1_inhibitorKills",
"t1_baronKills",
"t1_dragonKills",
"t1_riftHeraldKills",
"t2_towerKills",
"t2_inhibitorKills",
"t2_baronKills",
"t2_dragonKills",
"t2_riftHeraldKills"
]
게임 시작 전에 첫 킬이나 첫 포탑을 누가 가져갈지 아직 모르기 때문에 firstBlood, firstTower 같은 변수도 제외하였다.
4. 사용할 입력 변수 선택
게임 시작 전 알 수 있는 정보만 사용한다.
# 챔피언 선택 컬럼
champ_cols = [
"t1_champ1id", "t1_champ2id", "t1_champ3id", "t1_champ4id", "t1_champ5id",
"t2_champ1id", "t2_champ2id", "t2_champ3id", "t2_champ4id", "t2_champ5id"
]
# 소환사 주문 컬럼
summoner_spell_cols = [
"t1_champ1_sum1", "t1_champ1_sum2",
"t1_champ2_sum1", "t1_champ2_sum2",
"t1_champ3_sum1", "t1_champ3_sum2",
"t1_champ4_sum1", "t1_champ4_sum2",
"t1_champ5_sum1", "t1_champ5_sum2",
"t2_champ1_sum1", "t2_champ1_sum2",
"t2_champ2_sum1", "t2_champ2_sum2",
"t2_champ3_sum1", "t2_champ3_sum2",
"t2_champ4_sum1", "t2_champ4_sum2",
"t2_champ5_sum1", "t2_champ5_sum2"
]
# 밴 컬럼
ban_cols = [
"t1_ban1", "t1_ban2", "t1_ban3", "t1_ban4", "t1_ban5",
"t2_ban1", "t2_ban2", "t2_ban3", "t2_ban4", "t2_ban5"
]
# 최종 특성(feature) 목록
feature_cols = (
["seasonId"]
+ champ_cols
+ summoner_spell_cols
+ ban_cols
)
X = df[feature_cols]
y = df["target"]
print("X 크기:", X.shape) # X 크기: (51490, 41)
print("y 크기:", y.shape) # y 크기: (51490,)
X= 특성(Feature): 모델이 예측에 사용하는 입력정보, 예측 및 판단의 근거/단서y= 라벨(Label): 모델이 예측하려는 정답, 학습의 목푯값
5. Train / Test 데이터 분리
모델은 학습용 데이터(train data)로 학습하고, 한 번도 보지 못한 테스트 데이터(test data)로 성능을 평가해야 한다.
# Train / Test 데이터 분리
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2, # 전체 데이터의 20%를 테스트용으로 사용
random_state=42, # 실행할 때마다 같은 방식으로 데이터 분리
stratify=y # 팀1 승패 비율을 train과 test에 비슷하게 유지
)
print("훈련 데이터 X_train:", X_train.shape)
print("테스트 데이터 X_test:", X_test.shape)
print("\n훈련 타깃 비율:")
print(y_train.value_counts(normalize=True))
print("\n테스트 타깃 비율:")
print(y_test.value_counts(normalize=True))
'''
훈련 데이터 X_train: (41192, 41)
테스트 데이터 X_test: (10298, 41)
훈련 타깃 비율:
target
1 0.506458
0 0.493542
Name: proportion, dtype: float64
테스트 타깃 비율:
target
1 0.506409
0 0.493591
Name: proportion, dtype: float64
'''
6. Pipeline으로 전처리와 모델 연결하기
Pipeline은 결측치 처리 → 범주형 데이터 인코딩 → 모델 학습 과정을 하나로 묶는 도구다.
- 범주형 전처리기 만들기
- One-Hot Encoding: 챔피언 ID와 같은 범주형 데이터를 머신러닝 모델이 이해할 수 있는 형태로 변환해야 한다.
- 결측치는
-1로 채우고,OneHotEncoder로 One-Hot Encoding을 적용한다. handle_unknown="ignore": 테스트 데이터에 학습 데이터에서 한 번도 본 적 없는 챔피언 ID가 있어도 오류가 나지 않게 한다.
# 범주형 전처리기 만들기
categorical_features = feature_cols
categorical_transformer = Pipeline(
steps=[
("imputer", SimpleImputer(strategy="constant", fill_value=-1)),
("onehot", OneHotEncoder(handle_unknown="ignore"))
]
)
ColumnTransformer: 컬럼별로 서로 다른 전처리를 적용할 때 사용
# ColumnTransformer 만들기
preprocessor = ColumnTransformer(
transformers=[
("categorical", categorical_transformer, categorical_features)
]
)
7. 로지스틱 회귀 모델 만들기
1. 선형 회귀 (Linear Regression)

선형 회귀는 입력 변수 x를 사용해서 연속적인 숫자 값 y를 예측하는 모델이다.
[예시]
- 집 크기 → 집값 예측
- 공부 시간 → 시험 점수 예측
- 광고비 → 매출 예측
[수식]
- x: 입력 특성(feature)
- w: 회귀 계수(모수) 또는 각 특성의 가중치
- b: 절편
- y: 예측 대상
[특징]
- 예측 결과과 연속적인 숫자로 나옴
- 해석이 비교적 쉬움
- 변수와 결과 사이에 선형적인 관계가 있다고 가정
- 분류보다 회귀 문제에 적합함
2. 로지스틱 회귀 (Logistic Regression)

로지스틱 회귀는 선형 결합 결과를 시그모이드(sigmoid) 함수에 대입해 결과를 0~1 사이의 확률로 변환하는 모델이다.
[예시] 순서가 없는 범주를 확률로 직접 예측해 분류 문제에 적합하다.
- 스팸 메일 vs 정상 메일
- 질병 있음 vs 질병 없음
[수식] 모델 결과가 0.5 이상이면 1로, 0.5 미만이면 0으로 분류한다.
[특징]
- 이진 분류에 적합함
- 예측 결과를 확률로 표현 가능
- 학습 속도가 빠름
- 모델 구조가 비교적 단순함
- 복잡한 비선형 관계를 학습하기는 어려울 수 있음
3. 신경망 모델 (Neutral Network)

신경망 모델은 사람 뇌의 신경세포 연결 구조에서 아이디어를 얻은 머신러닝 모델이다.
[구조] 입력층 → 은닉층 → 출력층

[수식]
[특징]
- 복잡한 신경망 관계 학습 가능
- 복잡한 패턴 찾을 가능성 있음
- 이미지, 텍스트, 음성 등 복잡한 데이터에서 강력
- 데이터가 많을수록 성능이 좋아질 가능성이 있음
- 설정해야 할 값이 많으며 학습 시간이 더 오래 걸릴 수 있음
- 과적합(Overfitting) 위험이 있으며 결과 해석이 어려울 수 있음
이번 승패 예측 문제에서는 로지스틱 회귀 모델을 선택했다.
- 선형 회귀: 승패는
0또는1이어야 하지만, 선형 회귀로 예측하면 결과가-0.5나1.8처럼 나올 수 있어 분류로는 부적합함 - 로지스틱 회귀: 승패 예측은 이진 분류 문제이므로 로지스틱 회귀가 가장 적합함
- 신경망 모델: 복잡한 패턴을 학습할 수 있지만 난이도가 어려움
# 로지스틱 회귀 모델
model = LogisticRegression(
max_iter=1000,
random_state=42
)
8. 전처리 + 모델을 하나의 Pipeline으로 만들기
# 전처리 + 모델
clf = Pipeline(
steps=[
("preprocessor", preprocessor),
("model", model)
]
)
이제 clf 안에 결측치 처리 → One-Hot Encoding → Logistic Regression 학습 과정이 모두 들어있다.
9. 모델 학습하기
# 모델 학습하기
clf.fit(X_train, y_train)
10. 테스트 데이터 예측하기
# 테스트 데이터 예측하기
y_pred = clf.predict(X_test)
y_prob = clf.predict_proba(X_test)[:, 1]
print(y_prob[:10])
'''
[0.79158912 0.46268761 0.56285979 0.72050867 0.51578715 0.63640129
0.77212898 0.46479522 0.42304374 0.39547395]
'''
11. 모델 성능 평가
- Accuracy (정확도)
# 정확도 평가
accuracy = accuracy_score(y_test, y_pred)
print(f"정확도: {accuracy:.4f}") # 정확도: 0.5316
테스트 결과 53% 정도의 승패를 맞췄다. 게임 시작 전 픽/밴 정보만으로 승패를 맞히는 것은 쉬운 일이 아니므로 정확도가 높지 않더라도 너무 실망하지는 말자😅
- Classfication Report
# 분류 리포트
print(classification_report(
y_test,
y_pred,
target_names=["팀2 승리", "팀1 승리"]
))
'''
precision recall f1-score support
팀2 승리 0.53 0.51 0.52 5083
팀1 승리 0.54 0.55 0.55 5215
accuracy 0.53 10298
macro avg 0.53 0.53 0.53 10298
weighted avg 0.53 0.53 0.53 10298
'''
| 지표 | 의미 |
| Precision | 팀1 승리라고 예측한 경기 중 실제 팀1 승리 비율 (= TP / (TP + FP)) |
| Recall | 실제 팀1 승리 경기 중 모델이 팀1 승리라고 맞힌 비율 (= TP / (TP + FN)) |
| F1-score | Precision과 Recall의 균형 지표 (= 2 * (Precision * Recall) / (Precision + Recall)) |
| Support | 해당 클래스의 실제 데이터 수 |
- Confusion Matrix (혼동행렬)
# 혼동행렬
cm = confusion_matrix(y_test, y_pred)
disp = ConfusionMatrixDisplay(
confusion_matrix=cm,
display_labels=["팀2 승리", "팀1 승리"]
)
disp.plot(cmap="Blues")
plt.title("Confusion Matrix")
plt.show()

| 실제값 / 예측값 | 팀2 승리 예측 | 팀1 승리 예측 |
| 실제 팀2 승리 | TP 정확히 팀2 승리를 맞힌 수 |
FN 팀1 승리로 잘못 예측한 수 |
| 실제 팀1 승리 | FP 팀2 승리로 잘못 예측한 수 |
TN 정확히 팀1 승리를 맞힌 수 |
- ROC-AUC 점수: 단순히 맞고 틀린 결과뿐 만 아니라 예측 확률의 품질까지 평가하는 지표
# ROC-AUC 점수
auc = roc_auc_score(y_test, y_prob)
print(f"ROC-AUC: {auc:.4f}") # ROC-AUC: 0.5409
| ROC-AUC | 해석 |
| 0.5 | 무작위 추측 수준 |
| 0.6 ~ 0.7 | 어느 정도 구분 가능 |
| 0.7 ~ 0.8 | 좋은 편 |
| 0.8 | 매우 높은 성능 |
게임 시작 전의 픽/밴 데이터만 사용하는 경우 아주 높은 성능을 기대하기는 어렵다😢
12. DummyClassifier로 기준 성능 확인하기
모델이 실제로 의미 있는 학습을 한 것인지 확인하려면, 단순한 기준 모델과 비교하면 좋다. DummyClassifier는 데이터 패턴을 학습하지 않고 단순하게 예측하는 모델이다.
# DummyClassifier로 기준 성능 확인하기
dummy_clf = Pipeline(
steps=[
("preprocessor", preprocessor),
("model", DummyClassifier(strategy="most_frequent"))
]
)
dummy_clf.fit(X_train, y_train)
dummy_pred = dummy_clf.predict(X_test)
dummy_accuracy = accuracy_score(y_test, dummy_pred)
print(f"Dummy 모델 정확도: {dummy_accuracy:.4f}")
print(f"Logistic Regression 정확도: {accuracy:.4f}")
# Dummy 모델 정확도: 0.5064
# Logistic Regression 정확도: 0.5316
비교 결과 로지스틱 회귀 모델이 단순 무작위 예측보다 더 좋은 성능을 했다고 볼 수 있다.
🧩 머신러닝 과정 정리
- 데이터 불러오기
- target 만들기
- 데이터 누수 변수 제거
- feature 선택
- train/test 분리
- 결측치 처리
- 범주형 데이터 One-Hot Encoding
- 모델 학습
- 테스트 데이터 예측
- Accuracy, ROC-AUC, Confusion Matrix로 평가
'CS > Python' 카테고리의 다른 글
| 파이썬의 PyTorch 라이브러리에 대해 알아보기 (0) | 2026.08.10 |
|---|---|
| 파이썬으로 모델 검증/해석 찍먹하기 (0) | 2026.08.07 |
| 파이썬으로 데이터 전처리 찍먹하기 (0) | 2026.08.07 |
| 파이썬으로 데이터 시각화 찍먹하기 (0) | 2026.08.06 |
| 파이썬의 Pandas 라이브러리에 대해 알아보기 (0) | 2026.08.06 |