Fly ai 4기 3주차 day 12 : 딥러닝 dacon 해커톤

이성원·2024년 1월 4일
0

12일차

대구 교통사고 피해 예측

데이콘 링크 - https://dacon.io/competitions/official/236193/data

1. 데이터 전처리

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from datetime import datetime
from workalendar.asia import SouthKorea
from catboost import CatBoostRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.ensemble import RandomForestRegressor
from xgboost import XGBRegressor
from sklearn.ensemble import VotingRegressor

#압축풀기
!unzip /content/drive/MyDrive/open.zip

train_df = pd.read_csv('/content/drive/MyDrive/daegu/open/train.csv')
test_df = pd.read_csv('/content/drive/MyDrive/daegu/open/test.csv')
sub_df = pd.read_csv('/content/drive/MyDrive/daegu/open/sample_submission.csv')

train_df

ID	사고일시	요일	기상상태	시군구	도로형태	노면상태	사고유형	사고유형 - 세부분류	법규위반	...	가해운전자 상해정도	피해운전자 차종	피해운전자 성별	피해운전자 연령	피해운전자 상해정도	사망자수	중상자수	경상자수	부상자수	ECLO
0	ACCIDENT_00000	2019-01-01 00	화요일	맑음	대구광역시 중구 대신동	단일로 - 기타	건조	차대사람	길가장자리구역통행중	안전운전불이행	...	상해없음	보행자	여	70세	중상	0	1	0	0	5
1	ACCIDENT_00001	2019-01-01 00	화요일	흐림	대구광역시 달서구 감삼동	단일로 - 기타	건조	차대사람	보도통행중	기타	...	상해없음	보행자	남	61세	경상	0	0	1	0	3
2	ACCIDENT_00002	2019-01-01 01	화요일	맑음	대구광역시 수성구 두산동	단일로 - 기타	건조	차대사람	차도통행중	안전운전불이행	...	상해없음	보행자	남	38세	경상	0	0	1	0	3
3	ACCIDENT_00003	2019-01-01 02	화요일	맑음	대구광역시 북구 복현동	단일로 - 기타	건조	차대차	추돌	안전운전불이행	...	상해없음	승용	남	36세	중상	0	1	0	0	5
4	ACCIDENT_00004	2019-01-01 04	화요일	맑음	대구광역시 동구 신암동	단일로 - 기타	건조	차대차	추돌	안전운전불이행	...	상해없음	승용	남	52세	경상	0	0	1	0	3

test_df

ID	사고일시	요일	기상상태	시군구	도로형태	노면상태	사고유형
0	ACCIDENT_39609	2022-01-01 01	토요일	맑음	대구광역시 수성구 상동	교차로 - 교차로안	건조	차대사람
1	ACCIDENT_39610	2022-01-01 01	토요일	맑음	대구광역시 수성구 지산동	단일로 - 기타	건조	차대사람
2	ACCIDENT_39611	2022-01-01 04	토요일	맑음	대구광역시 수성구 수성동2가	교차로 - 교차로안	건조	차대차
3	ACCIDENT_39612	2022-01-01 04	토요일	맑음	대구광역시 수성구 신매동	단일로 - 기타	건조	차대차
4	ACCIDENT_39613	2022-01-01 06	토요일	맑음	대구광역시 달서구 감삼동	교차로 - 교차로안	건조	차대차

test_df 를 보니 train_df 에 없는 데이터들이 많았다.
test_df만으로 train_df에만 있는 열을 추론할 수 있을 것 같지 않아서 없는 열은 모두 drop했다.

train_df = train_df[['사고일시', '요일', '기상상태', '시군구', '도로형태', '노면상태', '사고유형', 'ECLO']]
test_df = test_df[['사고일시', '요일', '기상상태', '시군구', '도로형태', '노면상태', '사고유형']]

데이터중에 우리 조가 제일 중요하게 본 부분은 주말, 공휴일과 밤과 새벽이다.
그 시점에 사고가 많지않을까 라는 생각으로 전처리 했다.

주말, 공휴일 추출

# '사고일시' 열을 datetime 형식으로 변환
train_df['사고일시'] = pd.to_datetime(train_df['사고일시'], format='%Y-%m-%d %H')

# '공휴일' 및 '주말' 열 추가
cal = SouthKorea()
train_df['공휴일'] = train_df['사고일시'].apply(lambda x: 1 if cal.is_holiday(x) else 0)
train_df['주말'] = train_df['사고일시'].dt.dayofweek.isin([5, 6]).astype(int)



test_df['사고일시'] = pd.to_datetime(test_df['사고일시'], format='%Y-%m-%d %H')

test_df['공휴일'] = test_df['사고일시'].apply(lambda x: 1 if cal.is_holiday(x) else 0)
test_df['주말'] = test_df['사고일시'].dt.dayofweek.isin([5, 6]).astype(int)

시간대 추출

# 시간 범주를 나누어 새로운 열에 인덱스로 추가
bins = [0, 6, 12, 18, 24]
labels = [0, 1, 2, 3]
train_df['시간대'] = pd.cut(train_df['사고일시'].dt.hour, bins=bins, labels=labels, include_lowest=True, right=False)
test_df['시간대'] = pd.cut(test_df['사고일시'].dt.hour, bins=bins, labels=labels, include_lowest=True, right=False)

범주형 데이터 원 핫 인코딩

categorical_cols = ['기상상태', '도로형태', '노면상태', '사고유형']

train_df = pd.get_dummies(train_df, columns=categorical_cols)
test_df = pd.get_dummies(test_df, columns=categorical_cols)


train_df['시간대'] = train_df['시간대'].astype(int)
test_df['시간대'] = test_df['시간대'].astype(int)
train_df = train_df.drop('기상상태_안개', axis=1)

2. catboost 모델 학습

model = CatBoostRegressor(iterations=100, depth=10, learning_rate=0.1, loss_function='RMSE')


X = train_df.drop('ECLO', axis=1)
y = train_df['ECLO']

X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)

model.fit(X_train, y_train)

y_val_pred = model.predict(X_val)

rmse = mean_squared_error(y_val, y_val_pred, squared=False)
print(f"Validation RMSE: {rmse}")

Validation RMSE: 3.110688184835299

catboost의 경우 public 480/1928 등수를 기록했다.

3. RandomForestRegressor

# RandomForestRegressor 모델 생성
rf_model = RandomForestRegressor(n_estimators=100, max_depth=10, random_state=42)

# 훈련 데이터로 모델 학습
rf_model.fit(X_train, y_train)

# 검증 데이터에 대한 예측 수행
y_val_pred_rf = rf_model.predict(X_val)

# RMSE 계산
rmse_rf = mean_squared_error(y_val, y_val_pred_rf, squared=False)
print(f"Validation RMSE (Random Forest): {rmse_rf}")

Validation RMSE (Random Forest): 3.113345023838463

RandomForest의 경우 public 473/1928 등수를 기록했다.

4. RandomForestRegressor, GBRegressor 앙상블

rf_model2 = RandomForestRegressor(n_estimators=100, max_depth=10, random_state=42)

xgb_model2 = XGBRegressor(n_estimators=100, max_depth=5, learning_rate=0.1, random_state=42)

ensemble_model = VotingRegressor([('rf', rf_model2), ('xgb', xgb_model2)])

ensemble_model.fit(X_train, y_train)

y_val_pred_ensemble = ensemble_model.predict(X_val)

rmse_ensemble = mean_squared_error(y_val, y_val_pred_ensemble, squared=False)
print(f"Validation RMSE (Ensemble): {rmse_ensemble}")

Validation RMSE (Ensemble): 3.112085168550964

앙상블의 경우 public 470/1928 등수를 기록했다.

profile
개발자

0개의 댓글