중고차 구매의 기술 🤑
2개월전 작성한 notebook...
처음 참여한 Competition에서 노트북 메달을 받았다..!!!
순위는... 1722/3066 😭
Art of Buying Used Cars 🤑
Explore and run machine learning code with Kaggle Notebooks | Using data from Regression of Used Car Prices
www.kaggle.com
1. 개요
이 노트북에서는 여러 가지 특성(feature)을 바탕으로 중고차의 가격을 예측하는 것을 목표로 합니다. 평가 지표는 Root Mean Squared Error (RMSE) 입니다. 예측 정확도를 높이기 위해 다양한 머신러닝 모델을 사용하고, 이를 앙상블하여 성능을 향상시킬 예정입니다
2. 라이브러리 임포트 및 데이터 로딩
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split, StratifiedKFold
from sklearn.preprocessing import StandardScaler, OrdinalEncoder
from sklearn.metrics import mean_squared_error
from xgboost import XGBRegressor
from lightgbm import LGBMRegressor
from catboost import CatBoostRegressor
# Loading the datasets
df_train = pd.read_csv('/kaggle/input/playground-series-s4e9/train.csv', index_col='id')
df_test = pd.read_csv('/kaggle/input/playground-series-s4e9/test.csv', index_col='id')
df_sub = pd.read_csv('/kaggle/input/playground-series-s4e9/sample_submission.csv')
3. 피쳐 개요
- brand: 자동차 브랜드
- model: 자동차 모델
- model_year: 자동차 제조 연도
- milage: 자동차 주행 거리
- fuel_type: 연료 유형 (예: 휘발유, 하이브리드 등)
- engine: 엔진 사양
- transmission: 변속기 유형 (수동/자동)
- accident: 자동차의 사고 이력
- clean_title: 자동차가 깨끗한 제목(clean title)을 가지고 있는지 여부
- price: 목표 변수, 자동차의 가격을 나타냄
4. 데이터 전처리
pd.options.display.max_columns = None
df_train.tail(10)
BMW | 328 i | 2011 | 239000 | Gasoline | 230.0HP 3.0L Straight 6 Cylinder Engine Gasoli... | 6-Speed A/T | Black | Black | None reported | Yes | 8000 |
Chevrolet | Camaro 1LT | 2019 | 59692 | Gasoline | 335.0HP 3.6L V6 Cylinder Engine Gasoline Fuel | 10-Speed A/T | Red | Black | At least 1 accident or damage reported | Yes | 33600 |
Audi | A4 2.0T Premium quattro | 2011 | 121886 | Gasoline | 211.0HP 2.0L 4 Cylinder Engine Gasoline Fuel | 8-Speed A/T | Gray | Black | None reported | Yes | 6000 |
GMC | Yukon XL Denali | 2016 | 89291 | Gasoline | 420.0HP 6.2L 8 Cylinder Engine Gasoline Fuel | 8-Speed A/T | Red | Black | At least 1 accident or damage reported | Yes | 24700 |
Chevrolet | Camaro Z28 | 1999 | 110000 | Gasoline | 310.0HP 5.7L 8 Cylinder Engine Gasoline Fuel | A/T | White | Gray | None reported | Yes | 14500 |
Cadillac | Escalade ESV Platinum | 2017 | 49000 | Gasoline | 420.0HP 6.2L 8 Cylinder Engine Gasoline Fuel | Transmission w/Dual Shift Mode | White | Beige | None reported | Yes | 27500 |
Mercedes-Benz | AMG C 43 AMG C 43 4MATIC | 2018 | 28600 | Gasoline | 385.0HP 3.0L V6 Cylinder Engine Gasoline Fuel | 8-Speed A/T | White | Black | At least 1 accident or damage reported | Yes | 30000 |
Mercedes-Benz | AMG GLC 63 Base 4MATIC | 2021 | 13650 | Gasoline | 469.0HP 4.0L 8 Cylinder Engine Gasoline Fuel | 7-Speed A/T | White | Black | None reported | Yes | 86900 |
Audi | S5 3.0T Prestige | 2022 | 13895 | Gasoline | 3.0L | 1-Speed Automatic | Daytona Gray Pearl Effect | Black | None reported | NaN | 84900 |
Porsche | Macan Base | 2016 | 59500 | Gasoline | 252.0HP 2.0L 4 Cylinder Engine Gasoline Fuel | Transmission w/Dual Shift Mode | White | Black | None reported | Yes | 28995 |
4.1 결측치 확인
print("Train Data Missing Values:")
print(df_train.isnull().sum())
print("\nTest Data Missing Values:")
print(df_test.isnull().sum())
Train Data Missing Values:
brand 0
model 0
model_year 0
milage 0
fuel_type 5083
engine 0
transmission 0
ext_col 0
int_col 0
accident 2452
clean_title 21419
price 0
dtype: int64
Test Data Missing Values:
brand 0
model 0
model_year 0
milage 0
fuel_type 3383
engine 0
transmission 0
ext_col 0
int_col 0
accident 1632
clean_title 14239
dtype: int64
4.2 결측치 처리
- fuel_type: 이 특성은 결측치가 상당히 많고, 가장 빈번한 값은 "gasoline"입니다. 결측치는 "gasoline"으로 채우겠습니다.
- accident와 clean_title: 이 특성들은 가격 예측에 중요한 변수이므로, 결측치는 'missing'으로 레이블을 지정합니다.
from sklearn.impute import SimpleImputer
def cleaning_data(df):
# Filling missing values for 'fuel_type'
fuel_type_imputer = SimpleImputer(strategy='most_frequent')
df['fuel_type'] = fuel_type_imputer.fit_transform(df[['fuel_type']]).ravel()
# Filling missing values for 'accident' and 'clean_title'
missing_label_imputer = SimpleImputer(strategy='constant', fill_value='missing')
df[['accident', 'clean_title']] = missing_label_imputer.fit_transform(df[['accident', 'clean_title']])
return df
# Applying cleaning function to both train and test data
df_train_cleaned = cleaning_data(df_train)
df_test_cleaned = cleaning_data(df_test)
4.3 숫자형 및 범주형 특성 분리
적절한 전처리를 위해 특성들을 숫자형과 범주형으로 나눕니다.
num_features = ['milage', 'model_year']
cat_features = ['brand', 'model', 'fuel_type', 'accident', 'clean_title', 'transmission', 'ext_col', 'int_col']
4.4 스케일링 및 인코딩
숫자형 특성은 StandardScaler를 사용하여 표준화하고, 범주형 특성은 OrdinalEncoder를 사용하여 인코딩합니다.
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
# Numerical pipeline
num_pipeline = Pipeline([
('scaler', StandardScaler())
])
# Categorical pipeline
cat_pipeline = Pipeline([
('ordinal', OrdinalEncoder(handle_unknown='use_encoded_value', unknown_value=-1))
])
# Combining pipelines
preprocessor = ColumnTransformer([
('num', num_pipeline, num_features),
('cat', cat_pipeline, cat_features)
])
# Applying transformations to training and test data
X_train = df_train_cleaned.drop(columns=['price'])
y_train = df_train_cleaned['price']
X_test = df_test_cleaned
X_train_transformed = preprocessor.fit_transform(X_train)
X_test_transformed = preprocessor.transform(X_test)
5. 모델링 및 평가
5.1 데이터 분할
데이터를 훈련 세트와 검증 세트로 나누고, StratifiedKFold를 사용하여 교차 검증을 합니다.
X_train, X_valid, y_train, y_valid = train_test_split(X_train_transformed, y_train, test_size=0.2, random_state=42)
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
5.2 모델 선택 및 훈련
세 가지 모델인 XGBoost, LightGBM, RandomForestRegressor를 훈련시킵니다.
# XGBoost model
xgb_model = XGBRegressor(n_estimators=300, learning_rate=0.05, random_state=42)
xgb_model.fit(X_train, y_train)
xgb_valid_pred = xgb_model.predict(X_valid)
# LightGBM model
lgbm_model = LGBMRegressor(n_estimators=300, learning_rate=0.05, random_state=42)
lgbm_model.fit(X_train, y_train)
lgbm_valid_pred = lgbm_model.predict(X_valid)
# CatBoost model
cat_model = CatBoostRegressor(iterations=300, learning_rate=0.05, random_state=42, verbose=0) # verbose=0 to suppress output
cat_model.fit(X_train, y_train)
cat_valid_pred = cat_model.predict(X_valid)
[LightGBM] [Info] Auto-choosing col-wise multi-threading, the overhead of testing was 0.019312 seconds.
You can set `force_col_wise=true` to remove the overhead.
[LightGBM] [Info] Total Bins 1004
[LightGBM] [Info] Number of data points in the train set: 150826, number of used features: 10
[LightGBM] [Info] Start training from score 43890.785316
5.3 모델 평가
각 모델을 평가하기 위해 RMSE를 계산합니다.
def calculate_rmse(y_true, y_pred):
return np.sqrt(mean_squared_error(y_true, y_pred))
# Evaluating each model
xgb_rmse = calculate_rmse(y_valid, xgb_valid_pred)
lgbm_rmse = calculate_rmse(y_valid, lgbm_valid_pred)
cat_rmse = calculate_rmse(y_valid, cat_valid_pred)
print(f"XGBoost RMSE: {xgb_rmse:.5f}")
print(f"LightGBM RMSE: {lgbm_rmse:.5f}")
print(f"CatBoost RMSE: {cat_rmse:.5f}")
XGBoost RMSE: 69245.96084
LightGBM RMSE: 68315.71391
CatBoost RMSE: 68548.69844
5.4 최종 예측 및 제출
세 모델의 예측을 앙상블하여 최종 예측을 생성하고, 제출 파일을 준비합니다.
test_pred = (lgbm_model.predict(X_test_transformed) * 0.6 +
cat_model.predict(X_test_transformed) * 0.3 +
xgb_model.predict(X_test_transformed) * 0.1)
# Preparing the submission file
df_sub['price'] = test_pred
df_sub.to_csv('submission.csv', index=False)
df_sub.head()
id | price | |
0 | 188533 | 20522.992960 |
1 | 188534 | 77216.713175 |
2 | 188535 | 50774.795522 |
3 | 188536 | 25234.286778 |
4 | 188537 | 32651.528025 |
요약
- XGBoost, LightGBM, CatBoost 세 가지 모델을 훈련시켰습니다.
- 각 모델을 RMSE로 평가한 결과, LightGBM이 가장 낮은 RMSE를 기록하여 가장 우수한 성능을 보였습니다.
- 최종 제출에서는 세 모델을 앙상블하여 예측을 생성했습니다.
'공부 > kaggle' 카테고리의 다른 글
[kaggle] 타이타닉 데이터 분석 튜토리얼 (0) | 2024.06.30 |
---|