Ver2.0 파이썬 Scikit-learn으로 시작하는 예측 모델링 🚀

파이썬 Scikit-learn으로 시작하는 예측 모델링 🚀
데이터 사이언스의 세계로 떠나는 꿀잼 여행기 ✨
안녕하세요 여러분! 오늘은 파이썬 라이브러리 중에서도 머신러닝의 절대 강자 Scikit-learn에 대해 함께 알아볼게요. 이 글을 읽고 있다면 여러분도 이제 데이터 사이언스의 세계로 입문하려는 용자님들이시겠죠? 😎
머신러닝이라고 하면 뭔가 어렵고 복잡할 것 같은 느낌이 들죠? 근데 걱정 노노~! Scikit-learn은 진짜 초보자도 쉽게 시작할 수 있게 만들어진 라이브러리랍니다. 마치 재능넷에서 다양한 재능을 쉽게 찾을 수 있는 것처럼, Scikit-learn에서는 다양한 머신러닝 알고리즘을 쉽게 사용할 수 있어요! 👍
📚 목차
- Scikit-learn이 뭐길래? 🤔
- 설치부터 해볼까요? 🛠️
- 데이터 준비하기 (feat. 데이터 전처리) 📊
- 첫 번째 모델 만들기 (진짜 쉬워요, 믿어보세요!) 🎯
- 회귀 분석으로 예측해보기 📈
- 분류 모델로 카테고리 예측하기 🏷️
- 모델 평가하는 방법 (얼마나 잘했니?) 🧐
- 하이퍼파라미터 튜닝 (모델 업그레이드!) ⚙️
- 실전 프로젝트: 집값 예측하기 🏠
- 다음 단계는 어디로? 🚶♂️
1. Scikit-learn이 뭐길래? 🤔
Scikit-learn(사이킷런)은 파이썬에서 머신러닝을 할 때 가장 많이 사용하는 라이브러리예요. 그냥 많이 쓰는 게 아니라 머신러닝 입문자의 성지라고 불러도 될 정도랍니다! ㅋㅋㅋ
왜 이렇게 인기가 많을까요? 이유는 간단해요:
fit()하고 predict()하면 끝! 진짜임!
사실 머신러닝 세계에서는 Scikit-learn은 기본 중의 기본이에요. 마치 프로그래밍 세계에서 "Hello World" 출력하는 것처럼요! 그래서 데이터 사이언티스트가 되고 싶다면 반드시 알아야 하는 라이브러리랍니다. 😉
2. 설치부터 해볼까요? 🛠️
자, 이제 Scikit-learn을 설치해볼까요? 너무 쉬워서 놀랄 준비 되셨나요? ㅋㅋㅋ
설치 방법
파이썬이 이미 설치되어 있다면, 터미널(맥/리눅스) 또는 명령 프롬프트(윈도우)에서 다음 명령어를 입력하세요:
pip install scikit-learn
아나콘다를 사용하고 계신다면 이렇게 해보세요:
conda install scikit-learn
끝났습니다! 진짜로요! 이게 다예요. 😲
설치가 완료되었다면, 제대로 설치되었는지 확인해볼까요? 파이썬 인터프리터를 열고 다음 코드를 실행해보세요:
import sklearn
print(sklearn.__version__)
버전 번호가 출력된다면 성공입니다! 🎉 이제 본격적으로 머신러닝의 세계로 들어갈 준비가 되었어요!
꿀팁 🍯: Scikit-learn은 NumPy와 SciPy에 의존하고 있어요. 만약 설치 중에 오류가 발생한다면, 이 두 라이브러리가 먼저 설치되어 있는지 확인해보세요!
3. 데이터 준비하기 (feat. 데이터 전처리) 📊
머신러닝의 세계에서는 "쓰레기를 넣으면 쓰레기가 나온다"라는 유명한 말이 있어요. 즉, 데이터 품질이 결과의 품질을 결정한다는 거죠! 그래서 데이터 전처리는 정말 중요해요. 🧹
Scikit-learn에서는 데이터 전처리를 위한 다양한 도구를 제공하는데, 이걸 활용하면 데이터를 머신러닝 알고리즘에 딱 맞게 변환할 수 있어요!
3.1 데이터 불러오기
먼저 데이터를 불러와야겠죠? Scikit-learn에는 연습용 데이터셋이 내장되어 있어요. 진짜 개이득! 🙌
from sklearn import datasets
# 붓꽃(iris) 데이터셋 불러오기
iris = datasets.load_iris()
X = iris.data # 특성(feature) 데이터
y = iris.target # 타겟(레이블) 데이터
print(f"데이터 크기: {X.shape}") # (150, 4) 출력
print(f"클래스 종류: {set(y)}") # {0, 1, 2} 출력
이렇게 간단하게 데이터를 불러올 수 있어요! 물론 실제 프로젝트에서는 CSV 파일이나 데이터베이스에서 데이터를 가져오겠죠? 그럴 때는 pandas를 함께 사용하면 좋아요.
import pandas as pd
# CSV 파일에서 데이터 불러오기
df = pd.read_csv('my_data.csv')
X = df.drop('target_column', axis=1) # 타겟 컬럼을 제외한 모든 컬럼
y = df['target_column'] # 타겟 컬럼
3.2 데이터 분할하기
머신러닝에서는 데이터를 훈련 세트와 테스트 세트로 나누는 것이 일반적이에요. 훈련 세트로 모델을 학습시키고, 테스트 세트로 모델의 성능을 평가하죠!
from sklearn.model_selection import train_test_split
# 데이터를 훈련 세트(80%)와 테스트 세트(20%)로 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print(f"훈련 데이터 크기: {X_train.shape}")
print(f"테스트 데이터 크기: {X_test.shape}")
random_state는 난수 생성의 시드값이에요. 이 값을 고정하면 코드를 실행할 때마다 같은 방식으로 데이터가 분할돼요. 재현성을 위해 설정하는 것이 좋아요!
3.3 특성 스케일링
데이터의 각 특성(feature)이 서로 다른 범위를 가지고 있다면, 일부 머신러닝 알고리즘은 제대로 작동하지 않을 수 있어요. 그래서 특성 스케일링이 필요해요!
from sklearn.preprocessing import StandardScaler
# 표준화(평균=0, 표준편차=1)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test) # 테스트 데이터는 fit 하지 않고 transform만!
주의! ⚠️ 테스트 데이터는 훈련 데이터의 통계치로만 변환해야 해요. 그래서 fit_transform()이 아닌 transform()만 사용했어요. 이렇게 안 하면 데이터 누수(Data Leakage)가 발생할 수 있어요!
3.4 범주형 데이터 처리
머신러닝 알고리즘은 숫자만 이해할 수 있어요. 그래서 텍스트 같은 범주형 데이터는 숫자로 변환해야 해요!
from sklearn.preprocessing import OneHotEncoder
# 가정: X의 첫 번째 열이 범주형 데이터 (예: 'red', 'blue', 'green')
encoder = OneHotEncoder(sparse=False)
categorical_feature = X[:, 0].reshape(-1, 1) # 2D 배열로 변환
encoded_feature = encoder.fit_transform(categorical_feature)
print(f"원-핫 인코딩 결과 형태: {encoded_feature.shape}")
이렇게 하면 'red'는 [1, 0, 0], 'blue'는 [0, 1, 0], 'green'은 [0, 0, 1]과 같이 변환돼요. 이걸 원-핫 인코딩(One-Hot Encoding)이라고 해요! 😎
꿀팁 🍯: 범주형 변수가 많다면 pandas의 get_dummies() 함수를 사용하는 것도 좋은 방법이에요!
4. 첫 번째 모델 만들기 (진짜 쉬워요, 믿어보세요!) 🎯
자, 이제 드디어 첫 번째 머신러닝 모델을 만들어볼 시간이에요! 너무 설레지 않나요? ㅋㅋㅋ 진짜 간단하니까 긴장 풀고 따라와보세요~ 🤗
Scikit-learn의 모든 모델은 일관된 인터페이스를 가지고 있어요. 그래서 한 번 배우면 다른 모델도 쉽게 사용할 수 있어요!
- 모델 객체 생성하기: 사용할 알고리즘을 선택하고 객체를 만들어요.
- 모델 학습시키기:
fit()메서드로 훈련 데이터를 학습시켜요. - 예측하기:
predict()메서드로 새로운 데이터에 대한 예측을 수행해요.
정말 간단하죠? 이제 실제 코드로 확인해볼게요!
4.1 결정 트리 분류기 만들기
첫 번째 모델로 결정 트리(Decision Tree) 분류기를 만들어볼게요. 이 알고리즘은 이해하기 쉽고 시각화하기도 좋아요!
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
# 1. 모델 객체 생성
tree_model = DecisionTreeClassifier(random_state=42)
# 2. 모델 학습
tree_model.fit(X_train, y_train)
# 3. 예측
y_pred = tree_model.predict(X_test)
# 4. 성능 평가
accuracy = accuracy_score(y_test, y_pred)
print(f"모델 정확도: {accuracy:.4f}")
와우! 이게 전부예요! 단 몇 줄의 코드로 머신러닝 모델을 만들고 학습시키고 예측까지 했어요! 🎉
재미있는 사실 🎮: 결정 트리는 '스무고개' 게임과 비슷한 방식으로 작동해요! 일련의 질문을 통해 정답을 찾아가는 거죠. "꽃잎 길이가 5cm보다 큰가요?" → "꽃받침 너비가 3cm보다 작은가요?" 이런 식으로요!
4.2 결정 트리 시각화하기
결정 트리의 장점 중 하나는 시각화가 가능하다는 거예요! 모델이 어떻게 결정을 내리는지 직접 볼 수 있어요.
from sklearn.tree import export_graphviz
import graphviz
# 결정 트리 시각화 (Jupyter Notebook에서 실행 시)
dot_data = export_graphviz(
tree_model,
out_file=None,
feature_names=iris.feature_names,
class_names=iris.target_names,
filled=True,
rounded=True
)
graph = graphviz.Source(dot_data)
graph
이 코드를 실행하면 결정 트리의 구조를 시각적으로 볼 수 있어요. 각 노드는 질문을 나타내고, 각 잎은 최종 예측 클래스를 나타내죠!
이런 식으로 결정 트리는 특성(feature)을 기반으로 데이터를 분할하면서 예측을 수행해요. 각 노드에서는 "이 특성이 이 값보다 큰가?"라는 질문을 하고, 그 답에 따라 다음 노드로 이동하죠!
4.3 다른 분류 알고리즘 시도해보기
Scikit-learn에는 다양한 분류 알고리즘이 있어요. 결정 트리 외에도 다른 알고리즘을 시도해볼까요?
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
# K-최근접 이웃(KNN) 분류기
knn_model = KNeighborsClassifier(n_neighbors=5)
knn_model.fit(X_train, y_train)
knn_pred = knn_model.predict(X_test)
knn_accuracy = accuracy_score(y_test, knn_pred)
# 서포트 벡터 머신(SVM) 분류기
svm_model = SVC(kernel='linear', random_state=42)
svm_model.fit(X_train, y_train)
svm_pred = svm_model.predict(X_test)
svm_accuracy = accuracy_score(y_test, svm_pred)
print(f"KNN 정확도: {knn_accuracy:.4f}")
print(f"SVM 정확도: {svm_accuracy:.4f}")
print(f"결정 트리 정확도: {accuracy:.4f}")
이렇게 다양한 알고리즘을 시도해보고 성능을 비교할 수 있어요! 어떤 알고리즘이 가장 좋은 성능을 보이나요? 🤔
꿀팁 🍯: 모델 선택은 데이터의 특성과 문제의 성격에 따라 달라져요. 한 가지 모델이 모든 문제에 최적인 것은 아니에요! 여러 모델을 시도해보고 가장 좋은 성능을 보이는 모델을 선택하는 것이 좋아요.
5. 회귀 분석으로 예측해보기 📈
지금까지는 분류 문제를 다뤘어요. 이번에는 회귀 분석을 해볼게요! 회귀는 연속적인 값(예: 집 가격, 온도, 매출액 등)을 예측할 때 사용해요.
회귀 분석도 Scikit-learn에서는 분류와 거의 동일한 방식으로 수행할 수 있어요. 인터페이스가 일관되어 있다는 게 얼마나 편리한지 느껴보세요! 😉
5.1 선형 회귀 모델 만들기
가장 기본적인 회귀 모델인 선형 회귀(Linear Regression)부터 시작해볼게요!
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
import numpy as np
# 보스턴 주택 가격 데이터셋 불러오기
# 참고: 최신 버전의 scikit-learn에서는 이 데이터셋이 제거되었을 수 있어요
try:
boston = load_boston()
X = boston.data
y = boston.target
except:
# 대체 코드: 캘리포니아 주택 가격 데이터셋
from sklearn.datasets import fetch_california_housing
housing = fetch_california_housing()
X = housing.data
y = housing.target
# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 선형 회귀 모델 생성 및 학습
linear_model = LinearRegression()
linear_model.fit(X_train, y_train)
# 예측
y_pred = linear_model.predict(X_test)
# 성능 평가
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)
print(f"평균 제곱 오차(MSE): {mse:.4f}")
print(f"평균 제곱근 오차(RMSE): {rmse:.4f}")
print(f"결정 계수(R²): {r2:.4f}")
회귀 모델의 성능은 MSE(Mean Squared Error), RMSE(Root Mean Squared Error), R²(결정 계수) 등으로 평가해요. R²은 1에 가까울수록 좋은 모델이에요!
회귀 평가 지표 설명
- MSE(평균 제곱 오차): 예측값과 실제값 차이의 제곱 평균
- RMSE(평균 제곱근 오차): MSE의 제곱근, 원래 데이터와 같은 단위로 해석 가능
- R²(결정 계수): 모델이 데이터의 분산을 얼마나 설명하는지 나타내는 지표 (0~1)
5.2 다양한 회귀 모델 비교하기
선형 회귀 외에도 다양한 회귀 모델을 시도해볼 수 있어요!
from sklearn.ensemble import RandomForestRegressor
from sklearn.svm import SVR
# 랜덤 포레스트 회귀
rf_model = RandomForestRegressor(n_estimators=100, random_state=42)
rf_model.fit(X_train, y_train)
rf_pred = rf_model.predict(X_test)
rf_rmse = np.sqrt(mean_squared_error(y_test, rf_pred))
rf_r2 = r2_score(y_test, rf_pred)
# 서포트 벡터 회귀(SVR)
svr_model = SVR(kernel='linear')
svr_model.fit(X_train, y_train)
svr_pred = svr_model.predict(X_test)
svr_rmse = np.sqrt(mean_squared_error(y_test, svr_pred))
svr_r2 = r2_score(y_test, svr_pred)
print(f"선형 회귀 RMSE: {rmse:.4f}, R²: {r2:.4f}")
print(f"랜덤 포레스트 RMSE: {rf_rmse:.4f}, R²: {rf_r2:.4f}")
print(f"SVR RMSE: {svr_rmse:.4f}, R²: {svr_r2:.4f}")
이렇게 여러 모델을 비교해보면 어떤 모델이 가장 좋은 성능을 보이는지 알 수 있어요! 데이터마다 최적의 모델이 다를 수 있으니 여러 모델을 시도해보는 것이 중요해요.
꿀팁 🍯: 회귀 문제에서는 선형 회귀가 가장 간단하지만, 비선형 관계를 잘 포착하지 못할 수 있어요. 랜덤 포레스트나 그래디언트 부스팅 같은 앙상블 모델은 복잡한 패턴을 더 잘 학습할 수 있어요!
6. 분류 모델로 카테고리 예측하기 🏷️
이번에는 좀 더 복잡한 분류 문제를 다뤄볼게요! 여러 클래스를 가진 데이터셋에서 분류 모델을 만들고 평가하는 방법을 알아볼게요.
6.1 다중 클래스 분류
다중 클래스 분류는 2개 이상의 클래스를 예측하는 문제예요. 예를 들어, 손글씨 숫자를 인식하는 문제는 0부터 9까지 10개의 클래스를 분류해야 해요!
from sklearn.datasets import load_digits
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
# 손글씨 숫자 데이터셋 불러오기
digits = load_digits()
X = digits.data
y = digits.target
# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 랜덤 포레스트 분류기 학습
rf_classifier = RandomForestClassifier(n_estimators=100, random_state=42)
rf_classifier.fit(X_train, y_train)
# 예측
y_pred = rf_classifier.predict(X_test)
# 성능 평가
print("분류 보고서:")
print(classification_report(y_test, y_pred))
# 혼동 행렬(Confusion Matrix) 출력
print("혼동 행렬:")
print(confusion_matrix(y_test, y_pred))
classification_report는 정밀도(precision), 재현율(recall), F1-score 등 다양한 평가 지표를 제공해요. confusion_matrix는 어떤 클래스가 다른 클래스로 잘못 분류되었는지 보여주는 행렬이에요!
분류 평가 지표 설명
- 정밀도(Precision): 모델이 양성이라고 예측한 것 중 실제 양성인 비율
- 재현율(Recall): 실제 양성 중 모델이 양성이라고 예측한 비율
- F1-score: 정밀도와 재현율의 조화평균
- 혼동 행렬(Confusion Matrix): 예측 클래스와 실제 클래스의 교차표
6.2 확률 예측하기
분류 모델은 클래스 레이블뿐만 아니라 각 클래스에 속할 확률도 예측할 수 있어요! 이 확률은 모델의 신뢰도를 평가하는 데 유용해요.
# 클래스 확률 예측
y_proba = rf_classifier.predict_proba(X_test)
# 첫 번째 테스트 샘플의 확률 출력
print("첫 번째 샘플의 각 클래스 확률:")
for i, prob in enumerate(y_proba[0]):
print(f"클래스 {i}: {prob:.4f}")
print(f"실제 클래스: {y_test[0]}")
print(f"예측 클래스: {y_pred[0]}")
predict_proba() 메서드는 각 클래스에 속할 확률을 반환해요. 이 확률을 이용하면 모델이 얼마나 확신을 가지고 예측했는지 알 수 있어요!
6.3 ROC 곡선과 AUC
이진 분류 문제에서는 ROC(Receiver Operating Characteristic) 곡선과 AUC(Area Under the Curve)를 사용해 모델 성능을 평가할 수 있어요.
from sklearn.metrics import roc_curve, auc
import matplotlib.pyplot as plt
# 이진 분류 문제로 변환 (예: 숫자 '9'인지 아닌지)
y_test_binary = (y_test == 9).astype(int)
y_score = rf_classifier.predict_proba(X_test)[:, 9] # 클래스 '9'에 대한 확률
# ROC 곡선 계산
fpr, tpr, thresholds = roc_curve(y_test_binary, y_score)
roc_auc = auc(fpr, tpr)
print(f"AUC: {roc_auc:.4f}")
# ROC 곡선 그리기 (matplotlib 필요)
plt.figure()
plt.plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC curve (area = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic')
plt.legend(loc="lower right")
plt.show()
ROC 곡선은 다양한 임계값에서 모델의 성능을 보여주는 그래프예요. AUC는 ROC 곡선 아래 면적으로, 1에 가까울수록 좋은 모델이에요!
꿀팁 🍯: 불균형 데이터셋(한 클래스의 샘플이 다른 클래스보다 훨씬 많은 경우)에서는 정확도보다 ROC-AUC, F1-score, 정밀도-재현율 곡선 등을 사용하는 것이 더 좋아요!
7. 모델 평가하는 방법 (얼마나 잘했니?) 🧐
모델을 만들었다면 이제 제대로 평가해야겠죠? 모델 평가는 머신러닝 프로젝트에서 가장 중요한 부분 중 하나예요! 모델이 얼마나 잘 작동하는지, 어떤 부분에서 개선이 필요한지 알려주니까요.
7.1 교차 검증(Cross-Validation)
단순히 데이터를 훈련/테스트 세트로 한 번 나누는 것보다 더 신뢰할 수 있는 방법이 바로 교차 검증이에요! 데이터를 여러 폴드(fold)로 나누고, 각 폴드를 번갈아가며 테스트 세트로 사용하는 방식이에요.
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
# 붓꽃 데이터셋 불러오기
iris = datasets.load_iris()
X = iris.data
y = iris.target
# 랜덤 포레스트 분류기 생성
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)
# 5-폴드 교차 검증 수행
cv_scores = cross_val_score(rf_model, X, y, cv=5)
print(f"교차 검증 점수: {cv_scores}")
print(f"평균 점수: {cv_scores.mean():.4f}")
print(f"표준 편차: {cv_scores.std():.4f}")
교차 검증을 통해 모델의 평균 성능과 성능의 변동성을 확인할 수 있어요. 변동성이 크다면 모델이 데이터의 특정 부분에 과적합되었을 수 있어요!
7.2 학습 곡선(Learning Curves)
학습 곡선은 훈련 데이터의 크기에 따른 모델의 성능 변화를 보여주는 그래프예요. 이를 통해 모델이 과적합인지, 과소적합인지 판단할 수 있어요!
from sklearn.model_selection import learning_curve
import numpy as np
import matplotlib.pyplot as plt
# 학습 곡선 계산
train_sizes, train_scores, test_scores = learning_curve(
rf_model, X, y, cv=5, train_sizes=np.linspace(0.1, 1.0, 10)
)
# 평균과 표준편차 계산
train_mean = np.mean(train_scores, axis=1)
train_std = np.std(train_scores, axis=1)
test_mean = np.mean(test_scores, axis=1)
test_std = np.std(test_scores, axis=1)
# 학습 곡선 그리기
plt.figure(figsize=(10, 6))
plt.grid()
plt.fill_between(train_sizes, train_mean - train_std, train_mean + train_std, alpha=0.1, color="r")
plt.fill_between(train_sizes, test_mean - test_std, test_mean + test_std, alpha=0.1, color="g")
plt.plot(train_sizes, train_mean, 'o-', color="r", label="훈련 점수")
plt.plot(train_sizes, test_mean, 'o-', color="g", label="교차 검증 점수")
plt.xlabel("훈련 샘플 수")
plt.ylabel("점수")
plt.title("학습 곡선")
plt.legend(loc="best")
plt.show()
학습 곡선을 통해 다음과 같은 정보를 얻을 수 있어요:
- 과적합(Overfitting): 훈련 점수는 높지만 검증 점수가 낮은 경우
- 과소적합(Underfitting): 훈련 점수와 검증 점수 모두 낮은 경우
- 더 많은 데이터가 필요한지: 검증 점수가 계속 상승 중이라면 더 많은 데이터가 도움이 될 수 있어요
7.3 검증 곡선(Validation Curves)
검증 곡선은 하이퍼파라미터 값에 따른 모델의 성능 변화를 보여주는 그래프예요. 이를 통해 최적의 하이퍼파라미터 값을 찾을 수 있어요!
from sklearn.model_selection import validation_curve
# 검증 곡선 계산 (예: 결정 트리의 max_depth 파라미터)
param_range = np.arange(1, 11)
train_scores, test_scores = validation_curve(
DecisionTreeClassifier(), X, y, param_name="max_depth",
param_range=param_range, cv=5
)
# 평균과 표준편차 계산
train_mean = np.mean(train_scores, axis=1)
train_std = np.std(train_scores, axis=1)
test_mean = np.mean(test_scores, axis=1)
test_std = np.std(test_scores, axis=1)
# 검증 곡선 그리기
plt.figure(figsize=(10, 6))
plt.grid()
plt.fill_between(param_range, train_mean - train_std, train_mean + train_std, alpha=0.1, color="r")
plt.fill_between(param_range, test_mean - test_std, test_mean + test_std, alpha=0.1, color="g")
plt.plot(param_range, train_mean, 'o-', color="r", label="훈련 점수")
plt.plot(param_range, test_mean, 'o-', color="g", label="교차 검증 점수")
plt.xlabel("max_depth")
plt.ylabel("점수")
plt.title("검증 곡선")
plt.legend(loc="best")
plt.show()
검증 곡선을 통해 하이퍼파라미터의 최적값을 시각적으로 확인할 수 있어요. 교차 검증 점수가 가장 높은 지점이 최적의 하이퍼파라미터 값이에요!
꿀팁 🍯: 모델 평가는 단순히 하나의 지표만 보는 것이 아니라, 여러 지표와 그래프를 종합적으로 분석하는 것이 중요해요! 재능넷에서 다양한 분야의 전문가들이 그러하듯, 데이터 사이언티스트도 다양한 각도에서 모델을 평가해야 해요.
8. 하이퍼파라미터 튜닝 (모델 업그레이드!) ⚙️
모델의 성능을 최대한 끌어올리려면 하이퍼파라미터 튜닝이 필수예요! 하이퍼파라미터는 모델 학습 전에 설정하는 파라미터로, 이 값에 따라 모델의 성능이 크게 달라질 수 있어요.
Scikit-learn에서는 하이퍼파라미터 튜닝을 위한 다양한 도구를 제공해요. 가장 많이 사용하는 방법은 그리드 탐색(Grid Search)과 랜덤 탐색(Random Search)이에요!
8.1 그리드 탐색(Grid Search)
그리드 탐색은 가능한 모든 하이퍼파라미터 조합을 시도하고, 가장 좋은 성능을 내는 조합을 찾는 방법이에요.
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
# 탐색할 하이퍼파라미터 그리드 정의
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [None, 10, 20, 30],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
}
# 랜덤 포레스트 분류기 생성
rf = RandomForestClassifier(random_state=42)
# 그리드 탐색 객체 생성
grid_search = GridSearchCV(
estimator=rf,
param_grid=param_grid,
cv=5,
n_jobs=-1, # 모든 CPU 코어 사용
verbose=1,
scoring='accuracy'
)
# 그리드 탐색 수행
grid_search.fit(X_train, y_train)
# 최적의 하이퍼파라미터와 점수 출력
print(f"최적의 하이퍼파라미터: {grid_search.best_params_}")
print(f"최고 교차 검증 점수: {grid_search.best_score_:.4f}")
# 최적의 모델로 테스트 세트 예측
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"테스트 세트 정확도: {accuracy:.4f}")
그리드 탐색은 모든 조합을 시도하기 때문에 매우 철저하지만, 탐색 공간이 커지면 계산 비용이 급격히 증가해요. 위 예시에서는 3 × 4 × 3 × 3 = 108개의 조합을 모두 시도해요!
8.2 랜덤 탐색(Random Search)
랜덤 탐색은 그리드 탐색과 달리 무작위로 하이퍼파라미터 조합을 선택해 시도해요. 계산 비용을 줄이면서도 좋은 결과를 얻을 수 있어요!
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint, uniform
# 탐색할 하이퍼파라미터 분포 정의
param_dist = {
'n_estimators': randint(50, 500),
'max_depth': [None] + list(randint(5, 50).rvs(10)),
'min_samples_split': randint(2, 20),
'min_samples_leaf': randint(1, 10),
'max_features': ['auto', 'sqrt', 'log2', None]
}
# 랜덤 포레스트 분류기 생성
rf = RandomForestClassifier(random_state=42)
# 랜덤 탐색 객체 생성
random_search = RandomizedSearchCV(
estimator=rf,
param_distributions=param_dist,
n_iter=50, # 50번 시도
cv=5,
n_jobs=-1,
verbose=1,
random_state=42,
scoring='accuracy'
)
# 랜덤 탐색 수행
random_search.fit(X_train, y_train)
# 최적의 하이퍼파라미터와 점수 출력
print(f"최적의 하이퍼파라미터: {random_search.best_params_}")
print(f"최고 교차 검증 점수: {random_search.best_score_:.4f}")
# 최적의 모델로 테스트 세트 예측
best_model = random_search.best_estimator_
y_pred = best_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"테스트 세트 정확도: {accuracy:.4f}")
랜덤 탐색은 n_iter 매개변수로 시도할 횟수를 지정할 수 있어요. 그리드 탐색보다 효율적이면서도 좋은 결과를 얻을 수 있어요!
8.3 베이지안 최적화
더 고급 기법으로는 베이지안 최적화(Bayesian Optimization)가 있어요. 이 방법은 이전 시도의 결과를 바탕으로 다음에 시도할 하이퍼파라미터를 선택해요.
Scikit-learn에는 직접 구현되어 있지 않지만, scikit-optimize나 hyperopt 같은 라이브러리를 사용할 수 있어요!
꿀팁 🍯: 하이퍼파라미터 튜닝은 시간이 많이 걸릴 수 있어요. 처음에는 넓은 범위에서 랜덤 탐색을 하고, 좋은 영역을 찾으면 그 주변에서 그리드 탐색을 하는 전략이 효율적일 수 있어요!
9. 실전 프로젝트: 집값 예측하기 🏠
이제 지금까지 배운 내용을 종합해서 실전 프로젝트를 해볼게요! 보스턴 주택 가격 데이터셋을 사용해 집값을 예측하는 모델을 만들어볼게요.
이 프로젝트는 데이터 탐색부터 전처리, 모델 선택, 하이퍼파라미터 튜닝, 모델 평가까지 머신러닝 프로젝트의 전체 과정을 포함해요!
9.1 데이터 불러오기 및 탐색
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
# 캘리포니아 주택 가격 데이터셋 불러오기
housing = fetch_california_housing()
X = housing.data
y = housing.target
# 데이터프레임으로 변환
df = pd.DataFrame(X, columns=housing.feature_names)
df['PRICE'] = y
# 데이터 탐색
print(f"데이터 크기: {df.shape}")
print("\n처음 5개 행:")
print(df.head())
print("\n기술 통계량:")
print(df.describe())
# 상관관계 확인
correlation = df.corr()
print("\n가격과의 상관관계:")
print(correlation['PRICE'].sort_values(ascending=False))
데이터를 불러오고 기본적인 탐색을 수행했어요. 이 단계에서는 데이터의 특성, 분포, 상관관계 등을 파악하는 것이 중요해요!
9.2 데이터 전처리
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 전처리 파이프라인 생성
preprocessor = StandardScaler()
# 전처리 적용
X_train_scaled = preprocessor.fit_transform(X_train)
X_test_scaled = preprocessor.transform(X_test)
데이터를 훈련/테스트 세트로 분할하고, 표준화(StandardScaler)를 적용했어요. 실제 프로젝트에서는 결측치 처리, 이상치 제거, 특성 선택 등 더 많은 전처리 단계가 필요할 수 있어요!
9.3 모델 선택 및 학습
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.metrics import mean_squared_error, r2_score
import numpy as np
# 여러 모델 생성
models = {
"Linear Regression": LinearRegression(),
"Ridge Regression": Ridge(),
"Lasso Regression": Lasso(),
"Random Forest": RandomForestRegressor(random_state=42),
"Gradient Boosting": GradientBoostingRegressor(random_state=42)
}
# 각 모델 학습 및 평가
results = {}
for name, model in models.items():
# 모델 학습
model.fit(X_train_scaled, y_train)
# 예측
y_pred = model.predict(X_test_scaled)
# 평가
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)
# 결과 저장
results[name] = {'RMSE': rmse, 'R²': r2}
print(f"{name}:")
print(f" RMSE: {rmse:.4f}")
print(f" R²: {r2:.4f}")
여러 모델을 학습시키고 성능을 비교했어요. 이 단계에서는 어떤 모델이 가장 좋은 성능을 보이는지 확인하고, 더 자세히 튜닝할 모델을 선택해요!
9.4 최적 모델 선택 및 하이퍼파라미터 튜닝
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint, uniform
# 가장 성능이 좋은 모델이 랜덤 포레스트라고 가정
best_model_name = "Random Forest" # 실제로는 결과에 따라 선택
# 하이퍼파라미터 탐색 공간
param_dist = {
'n_estimators': randint(100, 500),
'max_depth': [None] + list(randint(5, 30).rvs(10)),
'min_samples_split': randint(2, 20),
'min_samples_leaf': randint(1, 10),
'max_features': ['auto', 'sqrt', 'log2', None]
}
# 랜덤 탐색 객체 생성
random_search = RandomizedSearchCV(
estimator=RandomForestRegressor(random_state=42),
param_distributions=param_dist,
n_iter=50,
cv=5,
n_jobs=-1,
verbose=1,
random_state=42,
scoring='neg_mean_squared_error'
)
# 랜덤 탐색 수행
random_search.fit(X_train_scaled, y_train)
# 최적의 하이퍼파라미터와 점수 출력
print(f"최적의 하이퍼파라미터: {random_search.best_params_}")
print(f"최고 교차 검증 RMSE: {np.sqrt(-random_search.best_score_):.4f}")
# 최적의 모델로 테스트 세트 예측
best_model = random_search.best_estimator_
y_pred = best_model.predict(X_test_scaled)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
r2 = r2_score(y_test, y_pred)
print(f"최종 모델 테스트 RMSE: {rmse:.4f}")
print(f"최종 모델 테스트 R²: {r2:.4f}")
가장 성능이 좋은 모델(이 예시에서는 랜덤 포레스트)을 선택하고, 하이퍼파라미터 튜닝을 수행했어요. 랜덤 탐색을 통해 최적의 하이퍼파라미터 조합을 찾았어요!
9.5 특성 중요도 분석
# 특성 중요도 확인
feature_importances = best_model.feature_importances_
feature_names = housing.feature_names
# 특성 중요도 시각화
indices = np.argsort(feature_importances)[::-1]
plt.figure(figsize=(10, 6))
plt.title("특성 중요도")
plt.bar(range(X.shape[1]), feature_importances[indices], align="center")
plt.xticks(range(X.shape[1]), [feature_names[i] for i in indices], rotation=90)
plt.tight_layout()
plt.show()
# 상위 5개 중요 특성 출력
print("상위 5개 중요 특성:")
for i in range(5):
print(f"{feature_names[indices[i]]}: {feature_importances[indices[i]]:.4f}")
모델의 특성 중요도를 분석했어요. 이를 통해 어떤 특성이 집값 예측에 가장 큰 영향을 미치는지 알 수 있어요! 이런 정보는 비즈니스 인사이트를 얻는 데 매우 유용해요.
9.6 최종 모델 저장 및 로드
import joblib
# 모델 저장
joblib.dump(best_model, 'housing_price_model.pkl')
joblib.dump(preprocessor, 'preprocessor.pkl')
# 모델 로드
loaded_model = joblib.load('housing_price_model.pkl')
loaded_preprocessor = joblib.load('preprocessor.pkl')
# 새로운 데이터로 예측 (예시)
new_data = X_test[:5] # 테스트 데이터의 처음 5개 샘플
new_data_scaled = loaded_preprocessor.transform(new_data)
predictions = loaded_model.predict(new_data_scaled)
print("새로운 데이터에 대한 예측:")
for i, pred in enumerate(predictions):
print(f"샘플 {i+1}: ${pred*100000:.2f}") # 가격 단위 조정
최종 모델과 전처리기를 저장하고 다시 로드하는 방법을 보여줬어요. 이렇게 하면 나중에 모델을 다시 학습시키지 않고도 새로운 데이터에 대한 예측을 수행할 수 있어요!
꿀팁 🍯: 실제 프로젝트에서는 모델 배포(deployment)도 중요한 단계예요! Flask나 FastAPI 같은 웹 프레임워크를 사용해 모델을 API로 제공하거나, 대시보드를 만들어 사용자가 쉽게 예측 결과를 볼 수 있게 할 수 있어요.
10. 다음 단계는 어디로? 🚶♂️
축하해요! 여러분은 이제 Scikit-learn을 사용한 예측 모델링의 기본을 마스터했어요! 🎉 하지만 머신러닝의 세계는 정말 넓고 깊어요. 더 나아가기 위한 몇 가지 방향을 소개할게요!
10.1 더 많은 알고리즘 탐색
Scikit-learn에는 우리가 다루지 않은 많은 알고리즘이 있어요:
- 클러스터링(Clustering): K-means, DBSCAN, 계층적 클러스터링 등
- 차원 축소(Dimensionality Reduction): PCA, t-SNE, UMAP 등
- 이상치 탐지(Outlier Detection): Isolation Forest, One-Class SVM 등
- 앙상블 방법(Ensemble Methods): Voting, Stacking, AdaBoost 등
10.2 딥러닝으로 확장
더 복잡한 문제를 해결하기 위해 딥러닝을 배워보는 것도 좋은 방법이에요! TensorFlow, PyTorch, Keras 같은 라이브러리를 사용해 신경망 모델을 만들 수 있어요.
# 간단한 신경망 예시 (TensorFlow/Keras 사용)
from tensorflow import keras
from tensorflow.keras import layers
# 모델 구성
model = keras.Sequential([
layers.Dense(64, activation='relu', input_shape=(X_train.shape[1],)),
layers.Dense(32, activation='relu'),
layers.Dense(1) # 회귀 문제이므로 활성화 함수 없음
])
# 모델 컴파일
model.compile(optimizer='adam', loss='mse', metrics=['mae'])
# 모델 학습
history = model.fit(
X_train_scaled, y_train,
epochs=100,
batch_size=32,
validation_split=0.2,
verbose=0
)
# 모델 평가
loss, mae = model.evaluate(X_test_scaled, y_test, verbose=0)
print(f"테스트 MAE: {mae:.4f}")
10.3 자연어 처리(NLP) 및 컴퓨터 비전
텍스트나 이미지 데이터를 다루는 것도 매우 흥미로운 분야예요! NLTK, spaCy, Transformers(BERT, GPT 등), OpenCV, TensorFlow의 이미지 처리 기능 등을 배워볼 수 있어요.
10.4 실전 프로젝트 도전
이론만 공부하는 것보다 실제 프로젝트를 진행하는 것이 가장 효과적인 학습 방법이에요! Kaggle 경진대회에 참가하거나, 오픈 데이터셋을 활용한 프로젝트를 진행해보세요.
재능넷에서도 데이터 분석이나 머신러닝 관련 프로젝트를 의뢰하거나 자신의 재능을 공유할 수 있어요! 실전 경험을 쌓는 좋은 기회가 될 수 있답니다. 😊
10.5 커뮤니티 참여
머신러닝 커뮤니티에 참여하는 것도 매우 중요해요! GitHub에서 오픈 소스 프로젝트에 기여하거나, Stack Overflow에서 질문하고 답변하거나, 블로그를 작성하거나, 컨퍼런스에 참여해보세요.
마치며
머신러닝은 끊임없이 발전하는 분야예요. 항상 새로운 것을 배우고 실험하는 자세가 중요해요! 이 글이 여러분의 머신러닝 여정에 도움이 되었기를 바랍니다. 😊
더 많은 프로그래밍과 데이터 사이언스 관련 지식을 얻고 싶다면, 재능넷에서 다양한 전문가들의 재능을 찾아보세요! 여러분의 학습 여정에 큰 도움이 될 거예요.
질문이나 피드백이 있으시면 언제든지 댓글로 남겨주세요. 함께 성장해요! 🚀
관련 키워드
댓글 작성
이 글에 대한 여러분의 생각을 들려주세요
로그인이 필요합니다
댓글을 작성하려면 먼저 로그인해주세요.
댓글 0
지식인의 숲 - 지적 재산권 보호 고지
지적 재산권 보호 고지
- 저작권 및 소유권: 본 컨텐츠는 재능넷의 독점 AI 기술로 생성되었으며, 대한민국 저작권법 및 국제 저작권 협약에 의해 보호됩니다.
- AI 생성 컨텐츠의 법적 지위: 본 AI 생성 컨텐츠는 재능넷의 지적 창작물로 인정되며, 관련 법규에 따라 저작권 보호를 받습니다.
- 사용 제한: 재능넷의 명시적 서면 동의 없이 본 컨텐츠를 복제, 수정, 배포, 또는 상업적으로 활용하는 행위는 엄격히 금지됩니다.
- 데이터 수집 금지: 본 컨텐츠에 대한 무단 스크래핑, 크롤링, 및 자동화된 데이터 수집은 법적 제재의 대상이 됩니다.
- AI 학습 제한: 재능넷의 AI 생성 컨텐츠를 타 AI 모델 학습에 무단 사용하는 행위는 금지되며, 이는 지적 재산권 침해로 간주됩니다.
아직 댓글이 없습니다.