728x90
이전 포스팅의 구현 순서에 맞게 코드를 작성한다
주요 아키텍쳐
Streamlit
┣ 📂data
┣ 📂models
┃ ┣ 📜gm_model.pkl # 모델 pkl
┃ ┗ 📜ngm_model.pkl # 모델 pkl
┣ 📂pages
┃ ┣ 📜main_page.py # 메인 페이지
┃ ┗ 📜sub_page.py # 서브 페이지
┣ 📜Home.py # 첫 페이지
┣ 📜models_gol.py # 골목상권 모델
┣ 📜models_ngol.py # 비골목상권 모델
┗ 📜requirements.txt
모델 pkl 형태로 저장
> models_gol.py, models_ngol.py 에서 각각 진행
- 머신러닝 코드 작성 (예시. models_gol.py 골목상권 모델)
import numpy as np
import pandas as pd
import lightgbm as lgb
from sklearn.model_selection import KFold, train_test_split, RandomizedSearchCV
from sklearn.metrics import mean_squared_error, mean_absolute_error
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib.font_manager as fm
import joblib
import os
#font 오류 수정
font_list = fm.findSystemFonts()
font_name = None
for font in font_list:
if 'AppleGothic' in font:
font_name = fm.FontProperties(fname=font).get_name()
plt.rc('font', family=font_name)
# 데이터 불러오기 및 전처리
data = pd.read_csv('data/골목_model용.csv')
# 데이터 분할
# k폴드, 라이트gbm 베이스라인 코드
# 라이브러리 임포트
import lightgbm as lgb
import numpy as np
import pandas as pd
from lightgbm import LGBMRegressor
from sklearn.model_selection import train_test_split, KFold, RandomizedSearchCV
from sklearn.metrics import mean_squared_error, mean_absolute_error
# 데이터 로드(실제 데이터셋 가져오기)
X = data.iloc[:, 5:]
y = data.iloc[:, 0]
# 데이터를 훈련세트와 테스트 세트로 나눔(test_size 설정 필요, 임의로 0.2)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# k-폴드 교차 검증
num_folds = 10
kf = KFold(n_splits= num_folds, shuffle=True, random_state=42)
# LightGBM 모델 초기화
params = {
'boosting_type': 'gbdt',
'objective': 'regression',
'metric': 'rmse',
'num_leaves': 31,
'learning_rate': 0.05,
'feature_fraction': 0.9
}
# 특성 중요도 리스트 초기화
feature_importance_list = []
# 결과 스코어
rmse_scores = [] # RMSE 스코어를 저장할 리스트
mae_scores = [] # MAE 스코어를 저장할 리스트
best_params_list = [] # 각 fold에서의 최적 파라미터를 저장할 리스트
# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 파라미터 범위 설정 (랜덤 서치용)
param_dist = {
'objective': ['regression'],
'metric': ['mse'],
'num_leaves': list(range(7, 64)), # 7부터 63까지
'learning_rate': [0.01, 0.02, 0.03, 0.04, 0.05], #0.01부터 0.05까지
'n_estimators': list(range(200, 301)), # 200부터 300까지
'early_stopping_rounds': list(range(40, 51)) # 40부터 50까지
}
# K-Fold 교차 검증 수행
for train_index, val_index in kf.split(X_train):
X_train_kf, X_val_kf = X.iloc[train_index], X.iloc[val_index]
y_train_kf, y_val_kf = y.iloc[train_index], y.iloc[val_index]
# 데이터셋
train_data = lgb.Dataset(X_train_kf, label=y_train_kf)
val_data = lgb.Dataset(X_val_kf, label=y_val_kf, reference=train_data)
# 랜덤 서치를 사용한 LightGBM 모델 튜닝
random_search = RandomizedSearchCV(
lgb.LGBMRegressor(),
param_distributions=param_dist,
n_iter=10,
scoring='neg_mean_squared_error',
cv=kf,
random_state=42,
n_jobs=-1,
verbose=1
)
evals = [(X_train_kf, y_train_kf),(X_val_kf, y_val_kf)]
random_search.fit(X_train_kf, y_train_kf, eval_set = evals, eval_metric='rmse')
best_params = random_search.best_params_
bst = lgb.LGBMRegressor(**best_params)
bst.fit(X_train_kf, y_train_kf,
eval_set=evals,
eval_metric='rmse',
verbose=False)
#Feature importance 계산
feature_importance = bst.feature_importances_
feature_importance_list.append(feature_importance)
# 모델 평가 (RMSE)
y_pred = bst.predict(X_val_kf)
mse = mean_squared_error(y_val_kf, y_pred)
rmse = np.sqrt(mean_squared_error(y_val_kf, y_pred))
mae = mean_absolute_error(y_val_kf, y_pred)
rmse_scores.append(rmse)
mae_scores.append(mae)
best_params_list.append(best_params)
# 교차 검증 결과 출력
mean_rmse = np.mean(rmse_scores)
mean_mae = np.mean(mae_scores)
print(f'평균 RMSE: {mean_rmse}')
print(f'평균 MAE: {mean_mae}')
# 특성 중요도 평균 계산
average_feature_importance = np.mean(feature_importance_list, axis=0)
# 특성 이름
feature_names = X.columns
# 중요도를 특성 이름과 함께 출력
feature_importance_df = pd.DataFrame({'Feature': feature_names, 'Importance': average_feature_importance})
feature_importance_df = feature_importance_df.sort_values(by='Importance', ascending=False)
print(feature_importance_df)
# 특성 중요도 시각화
plt.figure(figsize=(12, 8))
sns.barplot(x='Importance', y='Feature', data=feature_importance_df)
plt.title('특성 중요도')
plt.show()
# K-fold 교차 검증에서 얻은 최적 파라미터 출력
print("K-fold 교차 검증을 위한 최적 하이퍼파라미터:")
for i, params in enumerate(best_params_list):
print(f'Fold {i + 1}: {params}')
- 하단에 joblib 라이브러리로 모델을 pkl로 저장하는 코드 작성
# 모델 저장
if not os.path.exists("models"):
os.mkdir("models")
model_file = open("models/gm_model.pkl", "wb")
joblib.dump(bst, model_file) # Export
model_file.close()
os 라이브러리 이용해서, models 폴더 생성 한다. ( models 폴더가 없는 경우 models 폴더를 생성)
베스트 모델을 bst로 저장했으므로, joblib 라이브러리를 이용해서 bst 모델을 pkl로 저장한다.
- models 폴더에 gm_model.pkl,과 ngm_model.pkl 이 저장된 것을 확인
Streamlit
┣ 📂data
┣ 📂models
┃ ┣ 📜gm_model.pkl # 모델 pkl
┃ ┗ 📜ngm_model.pkl # 모델 pkl
┣ 📜models_gol.py # 골목상권 모델
┣ 📜models_ngol.py # 비골목상권 모델
┗ 📜requirements.txt
'Project > Convenience Store Location Analysis' 카테고리의 다른 글
[편의점 매출 예측] Streamlit 페이지 구현 3. 메인 페이지 모델 적용 코드 (1) | 2023.12.22 |
---|---|
[편의점 매출 예측] Streamlit 페이지 구현 1. 페이지 설명 및 구현 순서 (0) | 2023.12.22 |
[편의점 매출 예측] 데이터 수집- 크롤링 python 함수 구현(서울열린데이터 광장 API ) (0) | 2023.09.08 |