Python과 XGBoost를 활용한 머신러닝 모델 구축 및 배포를 위한 종합 가이드
빠르게 진화하는 데이터 과학 분야에서 머신러닝 모델을 구축, 평가 및 배포하는 능력은 중요한 기술입니다. 날씨 패턴을 예측하든, 고객 행동을 분석하든, 의사 결정 프로세스를 자동화하든, 이러한 단계를 숙달하면 프로젝트의 효과성과 확장성을 크게 향상시킬 수 있습니다. 이 가이드는 강력한 XGBoost 알고리즘에 중점을 두고 Python을 사용하여 머신러닝 모델을 구축하고 배포하는 포괄적이고 단계별 접근 방식을 제공합니다. 데이터 전처리, 특징 선택, 모델 훈련, 평가 및 배포를 다루며, Jupyter Notebooks의 실용적인 코드 예제가 지원됩니다.
목차
- 머신러닝 모델 배포 소개
- 데이터 준비 및 전처리
- 라이브러리 및 데이터 가져오기
- 결측치 처리
- 범주형 특징 인코딩
- 특징 선택
- 모델 훈련 및 평가
- K-최근접 이웃 (KNN)
- 로지스틱 회귀
- 가우시안 나이브 베이즈
- 서포트 벡터 머신 (SVM)
- 의사 결정 나무
- 랜덤 포레스트
- AdaBoost
- XGBoost
- Pickle을 사용한 모델 저장 및 로드
- 배포된 모델을 사용한 예측
- 웹 애플리케이션에 모델 배포
- 결론
1. 머신러닝 모델 배포 소개
머신러닝 모델을 배포하는 것은 모델을 구축하고 훈련하는 것 이상의 여러 중요한 단계를 포함합니다. 여기에는 데이터를 준비하고, 올바른 특징을 선택하며, 여러 모델을 훈련시키고, 그 성능을 평가한 후, 가장 성능이 좋은 모델을 프로덕션 환경에 배포하여 실시간 예측을 제공할 수 있도록 하는 것이 포함됩니다. 이 가이드는 Python과 속도와 정확도에 최적화된 고성능 라이브러리인 XGBoost를 사용하여 이러한 각 단계를 안내합니다.
2. 데이터 준비 및 전처리
라이브러리 및 데이터 가져오기
모든 머신러닝 프로젝트의 첫 번째 단계는 데이터 준비입니다. 이는 필요한 라이브러리를 가져오고 데이터셋을 로드하는 것을 포함합니다.
1 2 3 4 5 6 |
import pandas as pd import seaborn as sns # Load the dataset data = pd.read_csv('weatherAUS - tiny.csv') data.tail() |
1 2 3 4 5 6 |
Date Location MinTemp MaxTemp Rainfall Evaporation Sunshine WindGustDir WindGustSpeed WindDir9am ... RainToday RISK_MM RainTomorrow 9994 04/01/2012 CoffsHarbour 19.6 28.6 0.0 7.4 10.0 NE 56.0 NNW ... No 0.6 No 9995 05/01/2012 CoffsHarbour 21.3 26.5 0.6 7.6 6.4 NNE 31.0 S ... No 0.0 No 9996 06/01/2012 CoffsHarbour 18.4 27.6 0.0 5.0 10.6 SSW 56.0 N ... No 0.0 No 9997 07/01/2012 CoffsHarbour 18.3 26.1 0.0 7.6 9.0 SW 28.0 SW ... No 0.0 No 9998 08/01/2012 CoffsHarbour 21.4 29.2 0.0 5.8 12.8 NNE 61.0 N ... No 2.0 Yes |
결측치 처리
결측 데이터를 처리하는 것은 신뢰할 수 있는 모델을 구축하는 데 중요합니다. 여기서는 Scikit-learn의 SimpleImputer
를 사용하여 숫자형 및 범주형 열의 결측치를 처리합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import numpy as np from sklearn.impute import SimpleImputer # Handling missing numeric data imp_mean = SimpleImputer(missing_values=np.nan, strategy='mean') numerical_cols = list(np.where((X.dtypes == np.int64) | (X.dtypes == np.float64))[0]) imp_mean.fit(X.iloc[:, numerical_cols]) X.iloc[:, numerical_cols] = imp_mean.transform(X.iloc[:, numerical_cols]) # Handling missing categorical data string_cols = list(np.where((X.dtypes == np.object))[0]) imp_mode = SimpleImputer(missing_values=np.nan, strategy='most_frequent') imp_mode.fit(X.iloc[:, string_cols]) X.iloc[:, string_cols] = imp_mode.transform(X.iloc[:, string_cols]) |
범주형 특징 인코딩
머신러닝 알고리즘은 숫자형 입력을 필요로 합니다. 따라서 우리는 레이블 인코딩과 원-핫 인코딩 방법을 모두 사용하여 범주형 특징을 인코딩합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
from sklearn import preprocessing from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder # Label Encoding function def LabelEncoderMethod(series): le = preprocessing.LabelEncoder() le.fit(series) print('Encoding values', le.transform(pd.unique(series))) return le.transform(series) # One Hot Encoding function def OneHotEncoderMethod(indices, data): columnTransformer = ColumnTransformer([('encoder', OneHotEncoder(), indices)], remainder='passthrough') return columnTransformer.fit_transform(data) # Encoding selection function def EncodingSelection(X, threshold=10): string_cols = list(np.where((X.dtypes == np.object))[0]) one_hot_encoding_indices = [] for col in string_cols: length = len(pd.unique(X[X.columns[col]])) if length == 2 or length > threshold: X[X.columns[col]] = LabelEncoderMethod(X[X.columns[col]]) else: one_hot_encoding_indices.append(col) X = OneHotEncoderMethod(one_hot_encoding_indices, X) return X # Apply encoding X = EncodingSelection(X) print(X.shape) # Output: (9999, 25) |
3. 특징 선택
적절한 특징을 선택하면 모델 성능이 향상되고 계산 비용이 줄어듭니다. 우리는 카이 제곱(chi2) 통계 검정을 사용하는 SelectKBest
를 사용하여 상위 5개 특징을 선택합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
from sklearn.feature_selection import SelectKBest, chi2 from sklearn import preprocessing # Initialize SelectKBest and MinMaxScaler kbest = SelectKBest(score_func=chi2, k=10) MMS = preprocessing.MinMaxScaler() K_features = 5 # Fit and transform the features x_temp = MMS.fit_transform(X) x_temp = kbest.fit(x_temp, y) # Select top features best_features = np.argsort(x_temp.scores_)[-K_features:] features_to_delete = np.argsort(x_temp.scores_)[:-K_features] X = np.delete(X, features_to_delete, axis=1) print(X.shape) # Output: (9999, 5) |
4. 모델 훈련 및 평가
데이터가 준비되면 이를 훈련 세트와 테스트 세트로 분할하고 여러 분류 모델을 구축하여 가장 성능이 좋은 모델을 결정합니다.
훈련-테스트 분할
1 2 3 4 5 |
from sklearn.model_selection import train_test_split # Split the data X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=1) print(X_train.shape) # Output: (7999, 5) |
특징 스케일링
피처 스케일링은 입력 데이터의 스케일에 민감한 KNN 및 SVM과 같은 알고리즘에 필수적입니다.
1 2 3 4 5 6 7 8 9 10 11 |
from sklearn import preprocessing # Initialize and fit the scaler sc = preprocessing.StandardScaler(with_mean=False) sc.fit(X_train) # Transform the data X_train = sc.transform(X_train) X_test = sc.transform(X_test) print(X_train.shape) # Output: (7999, 5) print(X_test.shape) # Output: (2000, 5) |
분류 모델 구축
K-최근접 이웃 (KNN)
1 2 3 4 5 6 7 8 9 10 |
from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import accuracy_score # Initialize and train KNN knnClassifier = KNeighborsClassifier(n_neighbors=3) knnClassifier.fit(X_train, y_train) # Make predictions y_pred = knnClassifier.predict(X_test) print(accuracy_score(y_pred, y_test)) # Output: 0.8455 |
로지스틱 회귀
1 2 3 4 5 6 7 8 9 |
from sklearn.linear_model import LogisticRegression # Initialize and train Logistic Regression LRM = LogisticRegression(random_state=0, max_iter=200) LRM.fit(X_train, y_train) # Make predictions y_pred = LRM.predict(X_test) print(accuracy_score(y_pred, y_test)) # Output: 0.869 |
가우시안 나이브 베이즈
1 2 3 4 5 6 7 8 9 |
from sklearn.naive_bayes import GaussianNB # Initialize and train GaussianNB model_GNB = GaussianNB() model_GNB.fit(X_train, y_train) # Make predictions y_pred = model_GNB.predict(X_test) print(accuracy_score(y_pred, y_test)) # Output: 0.822 |
서포트 벡터 머신 (SVM)
1 2 3 4 5 6 7 8 9 |
from sklearn.svm import SVC # Initialize and train SVC model_SVC = SVC() model_SVC.fit(X_train, y_train) # Make predictions y_pred = model_SVC.predict(X_test) print(accuracy_score(y_pred, y_test)) # Output: 0.87 |
의사 결정 나무
1 2 3 4 5 6 7 8 9 |
from sklearn.tree import DecisionTreeClassifier # Initialize and train Decision Tree model_DTC = DecisionTreeClassifier() model_DTC.fit(X_train, y_train) # Make predictions y_pred = model_DTC.predict(X_test) print(accuracy_score(y_pred, y_test)) # Output: 0.8335 |
랜덤 포레스트
1 2 3 4 5 6 7 8 9 |
from sklearn.ensemble import RandomForestClassifier # Initialize and train Random Forest model_RFC = RandomForestClassifier(n_estimators=500, max_depth=5) model_RFC.fit(X_train, y_train) # Make predictions y_pred = model_RFC.predict(X_test) print(accuracy_score(y_pred, y_test)) # Output: 0.873 |
AdaBoost
1 2 3 4 5 6 7 8 9 |
from sklearn.ensemble import AdaBoostClassifier # Initialize and train AdaBoost model_ABC = AdaBoostClassifier() model_ABC.fit(X_train, y_train) # Make predictions y_pred = model_ABC.predict(X_test) print(accuracy_score(y_pred, y_test)) # Output: 0.8715 |
XGBoost
XGBoost는 효율성과 성능으로 유명하며, 특히 대규모 데이터셋을 처리하는 데 탁월합니다.
1 2 3 4 5 6 7 8 9 |
import xgboost as xgb # Initialize and train XGBoost model_xgb = xgb.XGBClassifier(use_label_encoder=False) model_xgb.fit(X_train, y_train) # Make predictions y_pred = model_xgb.predict(X_test) print(accuracy_score(y_pred, y_test)) # Output: 0.865 |
참고: 훈련 중에 XGBoost의 기본 평가 지표에 대한 경고가 표시될 수 있습니다. 이 경고를 억제하려면 eval_metric
매개변수를 명시적으로 설정할 수 있습니다.
1 |
model_xgb = xgb.XGBClassifier(use_label_encoder=False, eval_metric='logloss') |
5. Pickle을 사용한 모델 저장 및 로드
가장 성능이 좋은 모델을 식별한 후, 이를 미래에 사용하기 위해 저장하는 것이 필수적입니다. Python의 pickle
라이브러리는 모델의 직렬화 및 역직렬화를 쉽게 할 수 있게 해줍니다.
모델 저장
1 2 3 4 5 |
import pickle # Save the XGBoost model file_name = 'model_xgb.pkl' pickle.dump(model_xgb, open(file_name, 'wb')) |
모델 로드
1 2 3 4 5 6 |
# Load the saved model saved_model = pickle.load(open('model_xgb.pkl', 'rb')) # Verify the loaded model y_pred = saved_model.predict(X_test) print(accuracy_score(y_pred, y_test)) # Output: 0.865 |
6. 배포된 모델을 사용한 예측
모델이 저장되었으므로 이제 새로운 데이터에 대해 예측을 수행할 수 있습니다. 모델을 로드하고 새로운 인스턴스를 예측하는 방법은 다음과 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 |
import pickle import numpy as np # Load the model saved_model = pickle.load(open('model_xgb.pkl', 'rb')) # New data instance new_data = np.array([[0.02283472, 3.93934668, 1.95100361, 2.12694147, 0 ]]) # Make prediction prediction = saved_model.predict(new_data) print(prediction) # Output: [1] |
7. 웹 애플리케이션에 모델 배포
머신러닝 모델을 배포하면 다른 사람들이 웹 인터페이스를 통해 상호작용할 수 있습니다. 사용자가 특징 값을 입력할 수 있는 양식을 갖춘 웹 애플리케이션을 만든다고 가정해보겠습니다. 백엔드는 저장된 model_xgb.pkl
파일을 로드하고, 입력을 처리한 뒤 예측 결과를 반환할 수 있습니다.
예제 워크플로우:
- 프론트엔드: 사용자가 양식에 특징 값을 입력합니다.
- 백엔드:
- 입력 데이터를 수신합니다.
- 데이터를 전처리합니다(예: 스케일링, 인코딩).
pickle
을 사용하여model_xgb.pkl
을 로드합니다.- 예측을 수행합니다.
- 응답: 예측 결과를 사용자에게 표시합니다.
예제 Python Flask 코드:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
from flask import Flask, request, jsonify import pickle import numpy as np app = Flask(__name__) # Load the trained model model = pickle.load(open('model_xgb.pkl', 'rb')) @app.route('/predict', methods=['POST']) def predict(): data = request.get_json(force=True) # Extract features from the request features = [data['feature1'], data['feature2'], data['feature3'], data['feature4'], data['feature5']] # Convert to numpy array final_features = np.array([features]) # Make prediction prediction = model.predict(final_features) # Return the result return jsonify({'prediction': int(prediction[0])}) if __name__ == '__main__': app.run(debug=True) |
이 Flask 애플리케이션은 JSON 데이터를 포함한 POST 요청을 수락하는 API 엔드포인트 /predict
를 생성합니다. 입력을 처리하고, 로드된 XGBoost 모델을 사용하여 예측을 수행한 후, 결과를 JSON 형식으로 반환합니다.
8. 결론
머신러닝 모델을 구축하고 배포하는 것은 데이터 전처리 및 특징 선택부터 모델 훈련, 평가, 배포에 이르기까지 일련의 체계적인 단계를 포함합니다. XGBoost와 같은 강력한 라이브러리와 Jupyter Notebooks, Flask와 같은 도구를 활용하면 이 과정을 간소화하여 효율적이고 확장 가능하게 만들 수 있습니다. 이 포괄적인 가이드를 따르면 견고한 머신러닝 모델을 개발하고 이를 효과적으로 배포하여 특정 요구 사항을 충족시킬 수 있습니다.
추가 자료
- Jupyter 노트북:
- S31L02 – Prediction using value.ipynb *(노트북 링크)*
- S31L02 – temp file, include in project files.ipynb *(노트북 링크)*
- 데이터셋: Kaggle의 Weather AUS 데이터셋
이러한 실습을 통합하고 제공된 코드 스니펫을 활용함으로써 머신러닝 프로젝트의 정확도를 향상시키고 모델을 프로덕션 환경에 원활하게 배포할 수 있습니다.