Develop/ML·DL

머신러닝 데이터 처리 및 모델 훈련 과정 정리.

YOOZI. 2025. 1. 28. 21:52
728x90
너무 개념이 많은데 헷갈려서 간략하게 정리해보기

 

 

 

오늘은 머신러닝 데이터 처리 및 모델 훈련 과정 정리를 해보자.

오늘의 배움
  • 머신러닝의 핵심 개념, 실습 응용, 코딩 예제

 

 

1. 머신러닝 소개

  • 머신러닝이란?
    • 정의: 머신러닝은 컴퓨터가 데이터를 기반으로 학습하고 명시적인 프로그래밍 없이도 결정을 내릴 수 있게 합니다.
    • 실생활 예시:
      • 넷플릭스에서 영화 추천 (사용자가 좋아할 영화를 예측).
      • 스팸 이메일 필터 (원치 않는 메시지를 구분).
  • 머신러닝의 종류
    • 지도 학습 (예: 집 크기를 기반으로 집값 예측).
    • 비지도 학습 (예: 비슷한 구매 패턴을 가진 고객 그룹화).
    • 강화 학습 (예: 로봇이 걷는 법을 배우는 훈련).

2. 데이터 전처리

  • 데이터 전처리가 중요한 이유?
    • 데이터 품질을 보장하고 ML 모델의 활용성을 높이기 위해 필수적입니다.
  • 데이터 전처리 단계
    • 결측치 처리.
    • 범주형 데이터 인코딩.
    • 특성 스케일링 (데이터를 일관성 있게 정규화).
import pandas as pd
from sklearn.preprocessing import StandardScaler

# 데이터셋 로드
data = {'Age': [25, 27, None, 29], 'Salary': [50000, 54000, 58000, 61000]}
df = pd.DataFrame(data)

# 결측치 처리
df['Age'].fillna(df['Age'].mean(), inplace=True)  # 결측치를 평균값으로 대체

# 특성 스케일링
scaler = StandardScaler()
df[['Age', 'Salary']] = scaler.fit_transform(df[['Age', 'Salary']])
print(df)

 

3. 지도 학습

회귀 모델

  • 선형 회귀: 연속적인 값을 예측 (예: 집 크기를 기반으로 집값 예측).
from sklearn.linear_model import LinearRegression
import numpy as np

# 학습 데이터
X = np.array([[50], [60], [70]])  # 집 크기
y = np.array([300000, 400000, 500000])  # 가격

# 모델 학습
model = LinearRegression()
model.fit(X, y)

# 예측 수행
size = np.array([[65]])
print("예측 가격:", model.predict(size))

 

 

  • 다항 회귀 (Polynomial Regression): 비선형 관계를 모델링할 때 사용.
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression

# 학습 데이터
X = [[1], [2], [3], [4]]
y = [2.5, 3.6, 6.7, 8.8]

# 다항 특징 추가
poly = PolynomialFeatures(degree=2)
X_poly = poly.fit_transform(X)

# 모델 학습
poly_model = LinearRegression()
poly_model.fit(X_poly, y)

# 예측
predicted = poly_model.predict(poly.transform([[2.5]]))
print("다항 회귀 예측 결과:", predicted)

 

  • 결정 회귀 트리 (Decision Tree Regression): 의사결정 규칙을 통해 값을 예측.
from sklearn.tree import DecisionTreeRegressor

# 학습 데이터
X = [[1], [2], [3], [4]]
y = [2.5, 3.6, 6.7, 8.8]

# 모델 학습
tree_reg = DecisionTreeRegressor()
tree_reg.fit(X, y)

# 예측
predicted = tree_reg.predict([[2.5]])
print("결정 회귀 트리 예측 결과:", predicted)

 

  • 랜덤 포레스트 회귀 (Random Forest Regression): 여러 회귀 트리의 평균값으로 결과 예측.
from sklearn.ensemble import RandomForestRegressor

# 학습 데이터
X = [[1], [2], [3], [4]]
y = [2.5, 3.6, 6.7, 8.8]

# 모델 학습
rf_reg = RandomForestRegressor(n_estimators=100)
rf_reg.fit(X, y)

# 예측
predicted = rf_reg.predict([[2.5]])
print("랜덤 포레스트 회귀 예측 결과:", predicted)

 

  • 서포트 벡터 회귀 (SVR): 데이터 간 마진을 활용한 회귀.
from sklearn.svm import SVR

# 학습 데이터
X = [[1], [2], [3], [4], [5]]
y = [1, 4, 9, 16, 25]

# 모델 학습
svr = SVR(kernel='linear')
svr.fit(X, y)

# 예측
print("입력 6의 예측:", svr.predict([[6]]))

 

  • K-최근접 이웃 회귀 (KNN Regression): 주변 이웃 정보를 기반으로 연속값 예측.
from sklearn.neighbors import KNeighborsRegressor
import numpy as np

# 학습 데이터
X = np.array([[1], [2], [3], [4], [5]])
y = np.array([1.2, 1.8, 3.6, 3.8, 5.1])

# 모델 학습
knn_regressor = KNeighborsRegressor(n_neighbors=2)
knn_regressor.fit(X, y)

# 예측
print("특성 값 2.5의 예측 결과:", knn_regressor.predict([[2.5]]))

 

  • 신경망 (예: 피드포워드 신경망): 복잡한 패턴 학습에 유용.
from sklearn.neural_network import MLPRegressor
import numpy as np

# 데이터 준비
X = np.array([[0], [1], [2], [3], [4]])
y = np.array([0, 2, 4, 6, 8])

# 신경망 모델 생성
nn_model = MLPRegressor(hidden_layer_sizes=(10, 10), max_iter=1000, random_state=42)
nn_model.fit(X, y)

# 예측
prediction = nn_model.predict([[1.5]])
print("1.5에 대한 예측값:", prediction)

 

  • XGBoost
from xgboost import XGBRegressor
import numpy as np

# 데이터 준비
X = np.array([[1], [2], [3], [4], [5]])
y = np.array([1.5, 3.5, 5.5, 7.5, 9.5])

# XGBoost 모델 학습
xgb_model = XGBRegressor()
xgb_model.fit(X, y)

# 예측
prediction = xgb_model.predict([[6]])
print("6에 대한 예측값:", prediction)

 

  • LightGBM: 앙상블 회귀 모델로 높은 성능 제공.
from lightgbm import LGBMRegressor
import numpy as np

# 데이터 준비
X = np.array([[1], [2], [3], [4], [5]])
y = np.array([1.5, 3.5, 5.5, 7.5, 9.5])

# LightGBM 모델 학습
lgb_model = LGBMRegressor()
lgb_model.fit(X, y)

# 예측
prediction = lgb_model.predict([[6]])
print("6에 대한 예측값:", prediction)

 


분류 모델

  • 로지스틱 회귀: 이진 분류에 사용 (예: 스팸 이메일 분류).
from sklearn.linear_model import LogisticRegression

# 학습 데이터
X = [[1], [2], [3], [4]]  # 특징 (이메일 단어 수 등)
y = [0, 0, 1, 1]  # 레이블 (0 = 스팸 아님, 1 = 스팸)

# 모델 학습
classifier = LogisticRegression()
classifier.fit(X, y)

# 예측 수행
print("2.5 단어가 포함된 이메일의 예측:", classifier.predict([[2.5]]))

 

 

  • 결정 트리 (Decision Tree): 데이터에 대한 의사결정 규칙을 트리 구조로 학습합니다.
from sklearn.tree import DecisionTreeClassifier

# 학습 데이터
X = [[1], [2], [3], [4]]
y = [0, 0, 1, 1]

# 모델 생성 및 학습
tree_model = DecisionTreeClassifier()
tree_model.fit(X, y)

# 예측
predicted = tree_model.predict([[3]])
print("결정 트리 예측 결과:", predicted)

 

  • 랜덤 포레스트 (Random Forest): 여러 결정 트리를 앙상블하여 높은 성능을 제공합니다.
from sklearn.ensemble import RandomForestClassifier

# 학습 데이터
X = [[1], [2], [3], [4]]
y = [0, 0, 1, 1]

# 모델 생성 및 학습
rf_model = RandomForestClassifier(n_estimators=100)
rf_model.fit(X, y)

# 예측
predicted = rf_model.predict([[3]])
print("랜덤 포레스트 예측 결과:", predicted)

 

  • 서포트 벡터 머신 (SVM): 데이터를 분리하는 최적의 초평면을 찾는 분류 기법.
from sklearn.svm import SVC

# 학습 데이터
X = [[1], [2], [3], [4]]
y = [0, 0, 1, 1]

# 모델 생성 및 학습
svm_model = SVC(kernel='linear')
svm_model.fit(X, y)

# 예측
predicted = svm_model.predict([[3]])
print("SVM 예측 결과:", predicted)

 

  • K-최근접 이웃 (KNN): 데이터 포인트의 주변 이웃 정보를 기반으로 분류.
from sklearn.neighbors import KNeighborsClassifier

# 학습 데이터
X = [[1], [2], [3], [4]]
y = [0, 0, 1, 1]

# 모델 생성 및 학습
knn_model = KNeighborsClassifier(n_neighbors=3)
knn_model.fit(X, y)

# 예측
predicted = knn_model.predict([[2.5]])
print("KNN 예측 결과:", predicted)

 

  • XGBoost: 고성능 부스팅 알고리즘.
from xgboost import XGBClassifier

# 학습 데이터
X = [[1], [2], [3], [4]]
y = [0, 0, 1, 1]

# 모델 생성 및 학습
xgb_model = XGBClassifier(use_label_encoder=False)
xgb_model.fit(X, y)

# 예측
predicted = xgb_model.predict([[3]])
print("XGBoost 예측 결과:", predicted)

 

  • LightGBM: 고성능 부스팅 알고리즘.
from lightgbm import LGBMClassifier

# 학습 데이터
X = [[1], [2], [3], [4]]
y = [0, 0, 1, 1]

# 모델 생성 및 학습
lgbm_model = LGBMClassifier()
lgbm_model.fit(X, y)

# 예측
predicted = lgbm_model.predict([[3]])
print("LightGBM 예측 결과:", predicted)

4. 앙상블 학습

  • 배깅 (Bagging): 여러 모델의 평균을 통해 예측 안정성 증가. 랜덤포레스트가 대표적
from sklearn.ensemble import BaggingRegressor
from sklearn.tree import DecisionTreeRegressor

# 학습 데이터
X = np.array([[1], [2], [3], [4], [5]])
y = np.array([1.2, 1.8, 3.6, 3.8, 5.1])

# 배깅 회귀 모델
bagging_model = BaggingRegressor(base_estimator=DecisionTreeRegressor(), n_estimators=10, random_state=0)
bagging_model.fit(X, y)

# 예측
print("특성 값 2.5의 예측 결과:", bagging_model.predict([[2.5]]))

 

  • 스태킹 (Stacking): 다양한 모델의 예측 결과를 결합하여 최적 성능 도출.
from sklearn.ensemble import StackingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

# 데이터 로드
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 스태킹 모델 생성
estimators = [
    ('dt', DecisionTreeClassifier()),
    ('knn', KNeighborsClassifier())
]
stacking = StackingClassifier(estimators=estimators, final_estimator=LogisticRegression())
stacking.fit(X_train, y_train)

# 예측
print("스태킹 정확도:", stacking.score(X_test, y_test))
  • 부스팅 (Boosting): 약한 학습기를 결합하여 강력한 예측 모델 생성. 대표적인 알고리즘으로는 AdaBoost, XGBoost, LightGBM 등

 

5. 차원 축소 및 비지도 학습

  • PCA (주성분 분석): 데이터의 주요 패턴을 보존하면서 차원을 축소합니다.
from sklearn.decomposition import PCA
from sklearn.datasets import load_iris

# 데이터 로드
X, y = load_iris(return_X_y=True)

# PCA 변환
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)

print("변환된 데이터 형태:", X_pca.shape)

 

  • 커널 PCA: PCA의 확장판으로 비선형 구조를 가진 데이터의 차원을 축소
from sklearn.decomposition import KernelPCA
from sklearn.datasets import load_iris

# 데이터 로드
X, y = load_iris(return_X_y=True)

# 커널 PCA 변환
kpca = KernelPCA(n_components=2, kernel='rbf')
X_kpca = kpca.fit_transform(X)

print("변환된 데이터 형태:", X_kpca.shape)

 

  • LLE: 고차원 데이터의 지역적 구조를 보존하면서 차원을 축소
from sklearn.manifold import LocallyLinearEmbedding
from sklearn.datasets import load_iris

# 데이터 로드
X, y = load_iris(return_X_y=True)

# LLE 변환
lle = LocallyLinearEmbedding(n_components=2)
X_lle = lle.fit_transform(X)

print("변환된 데이터 형태:", X_lle.shape)

 

  • LDA: 차원축소 뿐만 아니라 분류 성능을 높이기 위해 클래스 간 분산을 최대화
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
from sklearn.datasets import load_iris

# 데이터 로드
X, y = load_iris(return_X_y=True)

# LDA 변환
lda = LDA(n_components=2)
X_lda = lda.fit_transform(X, y)

print("변환된 데이터 형태:", X_lda.shape)

 

  • 클러스터링(군집화)
    • 가우시안 혼합: 가우시안 분포 기반의 군집화
from sklearn.mixture import GaussianMixture
from sklearn.datasets import make_blobs

# 데이터 생성
X, _ = make_blobs(n_samples=300, centers=3, random_state=42)

# 가우시안 혼합 모델
gmm = GaussianMixture(n_components=3, random_state=42)
gmm.fit(X)
labels = gmm.predict(X)

print("군집 레이블:", labels)

 

 

  • DBSCAN: 밀도 기반 군집화 알고리즘
from sklearn.cluster import DBSCAN
from sklearn.datasets import make_blobs

# 데이터 생성
X, _ = make_blobs(n_samples=300, centers=3, random_state=42)

# DBSCAN 모델
dbscan = DBSCAN(eps=0.5, min_samples=5)
labels = dbscan.fit_predict(X)

print("군집 레이블:", labels)
  • 실루엣 분석: 데이터 포인트의 군집 내 응집도와 군집 간 분리도를 측정. 
    • -1에서 1 사이의 값을 가지며, 값이 1에 가까울수록 잘 군집화되었음을 의미
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score, silhouette_samples
from sklearn.datasets import make_blobs
import numpy as np

# 데이터 생성
X, _ = make_blobs(n_samples=300, centers=3, random_state=42)

# K-Means 클러스터링
kmeans = KMeans(n_clusters=3, random_state=42)
labels = kmeans.fit_predict(X)

# 실루엣 분석
silhouette_avg = silhouette_score(X, labels)
silhouette_vals = silhouette_samples(X, labels)

print("평균 실루엣 계수:", silhouette_avg)

# 군집별 실루엣 계수 시각화
import matplotlib.pyplot as plt
y_ticks = []
y_lower, y_upper = 0, 0
for i in range(3):  # 클러스터 수
    cluster_vals = silhouette_vals[labels == i]
    cluster_vals.sort()
    y_upper += len(cluster_vals)
    plt.barh(range(y_lower, y_upper), cluster_vals, edgecolor='none')
    y_ticks.append((y_lower + y_upper) / 2)
    y_lower += len(cluster_vals)

plt.axvline(silhouette_avg, color='red', linestyle='--')
plt.title("실루엣 분석")
plt.xlabel("실루엣 계수")
plt.ylabel("데이터 포인트")
plt.show()

 

  • K-평균 군집화: 비슷한 데이터를 그룹화 (예: 고객 세분화).
from sklearn.cluster import KMeans
import numpy as np

# 데이터셋
data = np.array([[1, 2], [1, 4], [1, 0], [10, 2], [10, 4], [10, 0]])

# K-평균 학습
kmeans = KMeans(n_clusters=2)
kmeans.fit(data)
print("클러스터 레이블:", kmeans.labels_)

 


6. 모델 학습, 테스트 및 평가

  • 단계
    1. 데이터를 학습용과 테스트용으로 분리.
    2. 학습용 데이터로 모델 훈련.
    3. 테스트 데이터로 모델 평가.
    4. 정확도, 정밀도, 재현율 등의 지표로 평가.
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 예제 데이터셋
X = [[1], [2], [3], [4], [5]]
y = [0, 0, 1, 1, 1]  # 레이블

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

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

# 모델 테스트
y_pred = classifier.predict(X_test)

# 평가
print("정확도:", accuracy_score(y_test, y_pred))

 

  • 이상치 및 결측치 처리
    • 이상치는 통계적 방법(IQR 등)으로 탐지.
    • 결측치는 대체하거나 제거.

 

7. 모델 평가 및 개선

평가 지표

  • 정확도(Accuracy): 전체 예측에서 정답인 데이터 비율.
    • 장점: 단순하고 직관적.
    • 단점: 데이터 불균형이 심한 경우 부적합. (예: 암 진단 데이터)
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier

# 데이터 로드
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

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

# 예측
y_pred = model.predict(X_test)

# 정확도 계산
accuracy = accuracy_score(y_test, y_pred)
print("정확도:", accuracy)

 

  • 정밀도(Precision): 관련 있는 긍정 예측에 집중. (예: 이메일 스팸 필터링)
from sklearn.metrics import precision_score
from sklearn.datasets import make_classification

# 데이터 생성
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.7, 0.3], random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

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

# 예측
y_pred = model.predict(X_test)

# 정밀도 계산
precision = precision_score(y_test, y_pred)
print("정밀도:", precision)

 

  • 재현율(Recall): 관련 사례를 모두 탐지하는 능력. (예: 암 진단 모델)
from sklearn.metrics import recall_score

# 재현율 계산
recall = recall_score(y_test, y_pred)
print("재현율:", recall)

 

  • F1-스코어: 정밀도와 재현율의 조화 평균
from sklearn.metrics import f1_score

# F1-스코어 계산
f1 = f1_score(y_test, y_pred)
print("F1-스코어:", f1)

 

 

 

개선 기법

  • 교차 검증(Cross-validation): 일관된 성능 보장.
  • 하이퍼파라미터 튜닝: 모델 성능 최적화를 위한 매개변수 조정.

 

비교표

 
개념 정의 코드 예제 적용 분야
데이터 전처리 데이터 품질 보정 및 준비 결측치 처리 및 스케일링 모든 머신러닝 문제
로지스틱 회귀 이진 분류 문제 해결 이메일 스팸 여부 예측 이메일 필터링, 의료 진단
결정 트리 트리 구조 기반 의사결정 고객 세그먼트 분석 마케팅, 의사결정
랜덤 포레스트 여러 트리 결합으로 높은 성능 제공 분류 및 회귀 금융 예측, 생물정보학
PCA 주요 패턴 보존하며 데이터 차원 축소 고차원 데이터 시각화 이미지 처리, 데이터 시각화

 

8. 최종 통합 코드

# 데이터 준비
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier

# 예제 데이터 (특징과 레이블)
X = np.array([[1, 2], [2, 3], [3, 4], [5, 6], [7, 8]])
y = np.array([0, 0, 1, 1, 1])

# 데이터 분리
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # Train/Test 분리

# 모델 학습
model = RandomForestClassifier()  # 랜덤 포레스트 모델 사용
model.fit(X_train, y_train)  # 학습

# 예측
predictions = model.predict(X_test)  # 테스트 데이터 예측
print("예측 결과:", predictions)

 

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification

# 데이터 생성
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.7, 0.3], random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

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

# 예측
y_pred = model.predict(X_test)

# 평가지표 계산
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)

print(f"정확도: {accuracy}")
print(f"정밀도: {precision}")
print(f"재현율: {recall}")
print(f"F1-스코어: {f1}")

 

 

728x90