머신러닝 모델 이론 & DecisionTree 심화 & 당뇨 예측 성능 향상 & LinearRegression 매개변수 정리 — 이상치 대체/스케일링으로 성능 향상

syeom·2026년 5월 11일

멀티캠퍼스 데이터분석 5월 11일 수업 내용 — 머신러닝 모델 이론, DecisionTree 실습, LinearRegression 실습


📌 목차

머신러닝 모델 이론
1. Logistic Regression
2. Ridge / Lasso / ElasticNet
3. Support Vector Machine (SVM)
4. Ensemble — Bagging & Boosting
5. Random Forest & XGBoost
6. K-Fold & GridSearchCV & Pipeline

실습

  1. DecisionTree — 매개변수 & 속성
  2. DecisionTree 실습 — iris 데이터
  3. DecisionTree 실습 — diabetes 데이터 & 성능 향상
  4. LinearRegression — 매개변수 & 속성 & 메서드
  5. LinearRegression 실습 — boston 데이터

머신러닝 모델 이론

1. Logistic Regression

  • 이름은 회귀지만 실제로는 분류에서 사용하는 모델
  • 예측값을 0과 1 사이의 확률값으로 변환
  • 0.5보다 크면 1(긍정), 작으면 0(부정)으로 판단


2. Ridge / Lasso / ElasticNet

Ridge

  • 선형 회귀에 L2 패널티를 추가한 규제 모델
  • 가중치를 0에 가까운 값으로 줄여 과적합 방지
  • 모든 특징을 유지하되 극단적인 가중치를 억제

Lasso

  • 선형 회귀에 L1 패널티를 추가한 규제 모델
  • 불필요한 특징의 가중치를 0으로 만들어 자동 제거
  • 모델을 단순하고 해석 가능하게 만드는 방식

ElasticNet

  • Ridge(L2)와 Lasso(L1)의 장점을 결합한 모델
  • l1_ratio 매개변수로 L1/L2 비율을 조절 가능
  • Lasso의 특징 선택 + Ridge의 전반적인 일반화를 동시에 활용
모델패널티특징 가중치 처리
RidgeL20에 가깝게 축소
LassoL10으로 만들어 제거
ElasticNetL1 + L2두 방식 결합

3. Support Vector Machine (SVM)

  • 데이터를 분리하는 최적의 결정 경계(Decision Boundary) 를 찾는 모델
  • 경계선에서 마진(여유 공간) 을 최대화하여 학습
  • 마진 밖 데이터에는 패널티를 적용
  • 회귀와 분류 모두 사용 가능

4. Ensemble — Bagging & Boosting

Ensemble 은 여러 머신러닝 모델을 결합해 더 강력한 모델을 만드는 방법입니다.

Bagging

  • 데이터를 부트스트랩 방식으로 여러 개 생성
  • 각 모델이 독립적으로(병렬) 학습
  • 각 모델의 예측을 결합해 최종 결과 출력
  • 장점: 분산 감소 / 단점: 편향 유지
  • 대표 모델: Random Forest

Boosting

  • 여러 약한 모델을 순차적으로 학습
  • 이전 모델의 오류를 점점 보완
  • 장점: 편향 감소 / 단점: 병렬화 어려움, 과적합 위험
  • 대표 모델: XGBoost
BaggingBoosting
학습 방식병렬순차
목표분산 감소편향 감소
속도빠름느림
과적합 위험낮음높음 (횟수 많을수록)

5. Random Forest & XGBoost

Random Forest

  • 대표적인 배깅 방식 모델
  • 여러 결정 트리를 배깅으로 학습 후 결과를 결합
  • 무작위 특성 선택으로 트리 간 상관성을 줄임
  • 각 트리는 독립적으로 학습 → 최종 예측값 결합

XGBoost

  • 대표적인 부스팅 방식 모델
  • 기존 Gradient Boosting 알고리즘을 고도화
  • 첫 번째 약한 모델 학습 후 오차를 계산하고 반복 보완

6. K-Fold & GridSearchCV & Pipeline

K-Fold

  • 데이터를 K개의 동일 크기 폴드로 나눔
  • K번 반복 → 매번 1개 폴드는 검증, 나머지는 학습
  • 모든 폴드가 한 번씩 검증용으로 사용
  • 데이터 수가 적을 때 모델 성능을 안정적으로 평가하는 방법

GridSearchCV

  • 매개변수 조합을 탐색하여 최적의 조합을 찾는 방법
  • 각 매개변수 조합별로 학습 + 교차 검증 진행
  • 최적 매개변수를 자동으로 확인

Pipeline


실습

7. DecisionTree — 매개변수 & 속성

주요 매개변수

매개변수기본값설명
criterion'gini'분할 기준 (분류: gini/entropy, 회귀: squared_error/absolute_error)
splitter'best'분할 시 특성 선택 방식 (best: 최적 / random: 무작위)
max_depthNone트리 최대 깊이 (None → 과적합 위험)
min_samples_split2노드 분할을 위한 최소 샘플 수
min_samples_leaf1Leaf 노드가 되기 위한 최소 샘플 수
max_featuresNone분할 시 고려할 특성 수 (None/sqrt/log2/숫자)
min_impurity_decrease0.0불순도 감소량이 이 값 이상일 때만 분할 수행
ccp_alpha0.0비용-복잡도 가지치기 (값 클수록 트리 단순화)
random_stateNone재현 가능한 결과를 위한 시드값

주요 속성 & 메서드

이름종류설명
feature_importances_속성각 특성의 중요도 (합계 = 1)
classes_속성클래스 목록
n_features_in_속성입력 특성(컬럼) 개수
fit(X, y)메서드모델 학습
predict(X)메서드예측
score(X, y)메서드분류: 정확도 / 회귀: R² Score
predict_proba(X)메서드각 클래스별 예측 확률 (분류만)

8. DecisionTree 실습 — iris 데이터

import matplotlib.pyplot as plt
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.metrics import accuracy_score, f1_score, confusion_matrix, precision_score, recall_score

iris = pd.read_csv('../csv/iris.csv')

X_train, X_test, y_train, y_test = train_test_split(
    iris.drop('species', axis=1),
    iris['species'],
    test_size    = 0.2,
    random_state = 42,
    stratify     = iris['species']
)

# max_depth 별 3개 모델 생성
clf_5 = DecisionTreeClassifier(max_depth=5, random_state=42)
clf_3 = DecisionTreeClassifier(max_depth=3, random_state=42)
clf_1 = DecisionTreeClassifier(max_depth=1, random_state=42)

clf_5.fit(X_train, y_train)
clf_3.fit(X_train, y_train)
clf_1.fit(X_train, y_train)

# 훈련 데이터 정확도 비교
print(clf_5.score(X_train, y_train))
print(clf_3.score(X_train, y_train))
print(clf_1.score(X_train, y_train))

# 테스트 데이터 예측 및 F1 Score 비교
pred_5 = clf_5.predict(X_test)
pred_3 = clf_3.predict(X_test)
pred_1 = clf_1.predict(X_test)

print(f1_score(y_test, pred_5, average='micro'))
print(f1_score(y_test, pred_3, average='micro'))
print(f1_score(y_test, pred_1, average='micro'))

plot_tree — 트리 시각화

feature_names = X_train.columns
class_names   = y_train.unique()

plt.figure(figsize=(16, 20))
plot_tree(clf_3, feature_names=feature_names, class_names=class_names)

# min_samples_split 적용 모델
clf = DecisionTreeClassifier(max_depth=3, random_state=42, min_samples_split=40)
clf.fit(X_train, y_train)

plt.figure(figsize=(16, 20))
plot_tree(clf, feature_names=feature_names, class_names=class_names)

💡 max_depth 가 클수록 훈련 데이터 정확도는 높지만 과적합 위험이 커집니다.
min_samples_split 을 높이면 과적합을 억제할 수 있습니다.


9. DecisionTree 실습 — diabetes 데이터 & 성능 향상

데이터 로드 & 확인

df = pd.read_csv('../data/diabetes.csv')

# 컬럼 설명
# Pregnancies : 임신 횟수
# Glucose : 혈당
# BloodPressure : 이완기 혈압
# SkinThickness : 삼두근 피부 주름 두께
# Insulin : 인슐린
# BMI : 체질량 지수
# DiabetesPedigreeFunction : 당뇨 내력
# Age : 나이
# Outcome : 클래스 결정값 (1: 당뇨 / 0: 정상)

df.describe()
df['Outcome'].value_counts()

기본 모델 학습 & 평가

X_train, X_test, y_train, y_test = train_test_split(
    df.drop('Outcome', axis=1), df['Outcome'],
    test_size=0.3, stratify=df['Outcome'], random_state=42
)

clf_7 = DecisionTreeClassifier(max_depth=7, random_state=42)
clf_5 = DecisionTreeClassifier(max_depth=5, random_state=42)
clf_3 = DecisionTreeClassifier(max_depth=3, random_state=42)

clf_7.fit(X_train, y_train)
clf_5.fit(X_train, y_train)
clf_3.fit(X_train, y_train)

print(clf_7.score(X_test, y_test),
      clf_5.score(X_test, y_test),
      clf_3.score(X_test, y_test))

# 혼동 행렬 & 평가 지표
pred = clf_7.predict(X_test)
cm   = confusion_matrix(y_test, pred)

print('정확도', accuracy_score(y_test, pred))
print('정밀도', precision_score(y_test, pred))
print('재현율', recall_score(y_test, pred))
print('F1 Score', f1_score(y_test, pred))

# 특성 중요도
clf_7.feature_importances_

성능 향상 — 이상치 대체 + 스케일링

import numpy as np

# 1. 혈당(Glucose) 0 → 0 제외 평균으로 대체
flag = df['Glucose'] == 0
df.loc[flag, 'Glucose'] = df.loc[~flag, 'Glucose'].mean()

# 2. 혈압(BloodPressure) 0 → 결측치로 대체 후 평균 채우기
flag2 = df['BloodPressure'] == 0
df.loc[flag2, 'BloodPressure'] = np.nan
df['BloodPressure'] = df['BloodPressure'].fillna(df['BloodPressure'].mean())

# 3. BMI 0 → 최빈값으로 대체
flag3 = df['BMI'] == 0
df.loc[flag3, 'BMI'] = df['BMI'].value_counts().index[0]
# 평가 지표 출력 함수
def score_print(y, pred):
    print('정확도', accuracy_score(y, pred))
    print('정밀도', precision_score(y, pred))
    print('재현율', recall_score(y, pred))
    print('F1 Score', f1_score(y, pred))

# 이상치 대체 후 재학습
X_train, X_test, y_train, y_test = train_test_split(
    df.drop('Outcome', axis=1), df['Outcome'],
    test_size=0.3, random_state=42, stratify=df['Outcome']
)

clf_7.fit(X_train, y_train)
pred = clf_7.predict(X_test)
score_print(y_test, pred)
from sklearn.preprocessing import StandardScaler

# 스케일링 적용
stdScaler    = StandardScaler()
X_train_sc   = stdScaler.fit_transform(X_train)   # train으로 fit → transform
X_test_sc    = stdScaler.transform(X_test)         # test는 transform만

clf_7.fit(X_train_sc, y_train)
pred2 = clf_7.predict(X_test_sc)

print('=== 원본 데이터 ===')
score_print(y_test, pred)
print('=== 스케일링 데이터 ===')
score_print(y_test, pred2)

⚠️ 스케일링 주의사항
fit_transform()Train 데이터에만 사용합니다.
Test 데이터는 Train의 범위 기준을 그대로 사용해야 하므로 transform() 만 적용합니다.


10. LinearRegression — 매개변수 & 속성 & 메서드

주요 매개변수

매개변수기본값설명
fit_interceptTrue절편(y절편) 사용 여부
copy_XTrue입력 X를 복사하여 사용
n_jobsNone병렬 계산에 사용할 CPU 수
positiveFalse회귀 계수를 양수로만 제한

주요 속성

속성설명
coef_추정된 회귀 계수 (가중치)
intercept_절편 값
rank_선형 독립 차원 수 (rank_ < 특성 수 → 다중공선성 존재)

주요 메서드

메서드설명
fit(X, y)모델 학습
predict(X)예측 (array 반환)
score(X, y)결정 계수 (R² Score)
get_params()설정된 매개변수 출력

회귀 평가 지표

지표함수설명
MAEmean_absolute_error()오차의 절댓값 평균
MSEmean_squared_error()오차의 제곱 평균
r2_score()1에 가까울수록 좋은 모델

11. LinearRegression 실습 — boston 데이터

import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score

boston = pd.read_csv('../csv/boston.csv')

# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(
    boston.drop('Price', axis=1),
    boston['Price'],
    test_size    = 0.3,
    random_state = 42
)

# 스케일링
stdScaler  = StandardScaler()
X_train_sc = stdScaler.fit_transform(X_train)
X_test_sc  = stdScaler.transform(X_test)

기본 모델 vs 절편 제외 모델

lr       = LinearRegression()               # 기본 (절편 포함)
lr_inter = LinearRegression(fit_intercept=False)  # 절편 제외

# 원본 데이터로 학습 & 평가
lr.fit(X_train, y_train)
pred = lr.predict(X_test)
print('MSE:', mean_squared_error(y_test, pred))
print('R2 :', r2_score(y_test, pred))

# 스케일링 데이터로 학습 & 평가
lr.fit(X_train_sc, y_train)
pred = lr.predict(X_test_sc)
print('MSE:', mean_squared_error(y_test, pred))
print('R2 :', r2_score(y_test, pred))

# 절편 제외 모델
lr_inter.fit(X_train, y_train)
pred_inter = lr_inter.predict(X_test)
print('MSE:', mean_squared_error(y_test, pred_inter))
print('R2 :', r2_score(y_test, pred_inter))

# 회귀 계수 비교
print('절편 포함 계수:', lr.coef_)
print('절편 제외 계수:', lr_inter.coef_)

# 결정 계수 비교
print(lr.score(X_train_sc, y_train))
print(lr_inter.score(X_train_sc, y_train))

💡 스케일링이 필요한 이유
특성(컬럼)마다 값의 범위가 다르면 모델이 범위가 큰 특성에 편향되어 학습됩니다.
StandardScaler 로 정규화하면 모든 특성을 동등하게 반영합니다.

💡 R² Score 해석

  • 1 → 완벽한 예측
  • 0 → 평균만 예측하는 수준
  • 음수 → 평균보다 못한 예측

📎 핵심 개념 요약

개념설명
과적합 (Overfitting)훈련 데이터에는 잘 맞지만 새 데이터에는 틀리는 문제
규제 (Regularization)과적합 방지를 위해 가중치에 패널티 부여
L1 패널티 (Lasso)가중치를 0으로 만들어 특성 제거
L2 패널티 (Ridge)가중치를 0에 가깝게 축소
배깅병렬 학습, 분산 감소 → Random Forest
부스팅순차 학습, 편향 감소 → XGBoost
fit_transform()Train 데이터에만 사용 (범위 학습 + 변환)
transform()Test 데이터에만 사용 (Train 범위 기준으로 변환)
feature_importances_각 특성의 중요도 (합계 = 1)
confusion_matrix()예측/실제 값의 분류 결과 행렬
precision_score()정밀도 — 양성 예측 중 실제 양성 비율
recall_score()재현율 — 실제 양성 중 양성으로 예측한 비율
f1_score()정밀도와 재현율의 조화 평균
r2_score()결정 계수 — 1에 가까울수록 좋음
mean_squared_error()MSE — 오차의 제곱 평균
profile
공부 기록

0개의 댓글