Kaggle Competition : Bike Sharing Demand를 경험했다. 자전거 수요를 회귀 모델을 사용해 예측하고 제출하여 점수를 확인했다.
Gradient Boosting 모델을 사용했으며 GridSearchCV를 통해 최적의 하이퍼 파라미터를 탐색했다.
데이터 준비
competition page에서 train.csv, test.csv, sampleSubmission.csv를 다운로드했다. 각각 학습, 예측, 제출에 사용할 파일이다.
그 후 train.csv와 test.csv를 로드하여 각각 변수에 저장했다.
print(train.shape)
train.head()
train 데이터의 shape와 처음 5개 행 확인
print(test.shape)
test.head()
test 데이터의 shape와 처음 5개 행 확인
train 데이터가 test 데이터보다 열 수가 많은데, 이는 train에 예측해야 할 값이 포함되어 있기 때문이다.
train["datetime"] = pd.to_datetime(train["datetime"])
train["year"] = train["datetime"].dt.year
train["hour"] = train["datetime"].dt.hour
train["dayofweek"] = train["datetime"].dt.dayofweek
test["datetime"] = pd.to_datetime(test["datetime"])
test["year"] = test["datetime"].dt.year
test["hour"] = test["datetime"].dt.hour
test["dayofweek"] = test["datetime"].dt.dayofweek
train과 test 데이터에 예측과 학습에 사용할 연도, 시간, 요일 변수를 추가했다.
EDA
예측해야 할 값은 count 값이다. train['count']를 히스토그램과 kdeplot을 그려 확인하면 아래와 같다.
한쪽으로 매우 편향된 분포를 확인할 수 있다. 이런 경우 log를 사용하는 것이 좋다.
# count에 log를 취해준다
train['count_log1p'] = np.log1p(train['count'])
train[['count', 'count_log1p']].hist(bins=50, figsize=(12,4))
count와 numpy의 함수를 통해 로그를 취한 count_log1p를 비교해 보자.
육안으로도 개선된 것이 확인된다.
로그를 적용하면 상대적으로 큰 값에 대한 스케일을 줄여서 스케일 차이가 많이 나는 경우 평가 성능이 좋아질 수 있다.
로그를 적용하여 모델을 학습시키고 예측값을 얻게 되면, 반드시 다시 로그 적용을 복원해야 한다.
이때 numpy의 exp 함수를 사용한다.
train['count_expm1'] = np.exp(train['count_log1p']) - 1
train[['count', 'count_log1p', 'count_expml']].hist(bins=50, figsize=(10, 4))
원래 값, 로그 적용한 값, 적용한 로그를 복원한 값에 대해 히스토그램으로 확인한다.
원래 값과 로그 적용 후 복원한 값이 같아 보인다.
기술통계 값을 확인한 결과 정확히 복원되었다.
이제 학습, 예측 데이터를 준비하고 log와 exp를 활용해 본다.
학습에 사용할 데이터셋(X_train, y_train), 예측에 사용할 데이터셋 (X_test) 만들기
# 예측 target
label_name = 'count'
# 사용할 컬럼
feature_names = ['season', 'holiday', 'workingday', 'weather', 'temp',
'atemp', 'humidity', 'windspeed', 'year', 'hour', 'dayofweek']
먼저 학습과 예측에 사용할 컬럼을 정하고 target인 컬럼명 "count"는 label_name에 지정했다.
X_train = train[feature_names]
print(X_train.shape)
X_train.head(2)
학습에 사용할 데이터셋의 shape과 처음 2개 행 확인
y_train = np.log1p(train[label_name]) # 로그 적용
y_train
학습에 사용할 X_train의 정답 값에 해당하는 데이터셋 확인
y_train은 X_train과 동일한 개수인 Series다.
X_test = test[feature_names]
print(X_test.shape)
X_test.head(2)
예측에 사용할 데이터셋의 shape과 처음 2개 행 확인
X_test는 X_train에 비해 행 수가 적으며 컬럼 수는 같다.
머신러닝 모델을 활용한 학습과 예측
회귀 문제에 성능이 좋은 부스팅 모델을 사용한다.
from sklearn.ensemble import GradientBoostingRegressor
model = GradientBoostingRegressor(random_state=42)
GradientBoostingRegressor 모델을 생성했다.
GridSearchCV를 통해 최적의 하이퍼 파라미터를 찾는다.
parameters = {'n_estimators': (200, 300, 400),
'learning_rate': (0.05, 0.1, 0.2)}
from sklearn.model_selection import GridSearchCV
reg = GridSearchCV(model, parameters, cv=3, n_jobs=-1, verbose=2)
reg.fit(X_train, y_train) # 3*3개의 조합, cross validation 조각 3개
reg.best_estimator_
Fitting 3 folds for each of 9 candidates, totalling 27 fits를 통해 아래와 같은 best estimator를 얻었다.
이렇게 구한 모델에 X_train, y_train을 학습시키고 X_test에 대한 예측값을 얻는다.
y_pred = reg.best_estimator_.fit(X_train, y_train).predict(X_test)
y_pred = np.expm1(y_pred)
y_pred # 로그를 적용하여 학습했기 때문에 예측값은 로그 적용을 복원
학습시 로그를 적용한 y_train 값을 사용했기 때문에 역으로 예측값에 exp를 적용했다.
Kaggle에 제출 및 점수 확인
df_submit = pd.read_csv('sampleSubmission.csv')
df_submit['count'] = y_pred
df_submit
답안지 양식을 로드한 후 예측한 값 y_pred를 입력한다.
날짜,시간대별 예측값이 count 컬럼에 잘 입력되었다.
이제 캐글에 제출하기 위해 csv파일로 저장한 후
실제로 제출해서
채점된 score를 확인한 결과 0.37359라는 결과를 받았다.
당시의 Competition 결과를 Leaderboard에서 보니, 91위에 해당하는 점수인 것을 확인할 수 있다.
이렇게 부스팅 모델과 그리드서치를 이용하여 캐글 자전거 수요 예측대회에서 전체 3242팀 중 91위(상위 2.8%)에 해당하는 성적을 받아 보는 경험을 했다. 재미있었다.
'AI SCHOOL > TIL' 카테고리의 다른 글
[DAY 57] Tableau 계산된 필드, 매개변수 만들기, 대시보드 계획하기, 데이터 스토리텔링 (0) | 2023.03.17 |
---|---|
[DAY 56] Week 13 Insight Day (0) | 2023.03.16 |
[DAY 54] ExtraTreesClassifier, scikit-learn의 OneHotEncoder, cross validation (0) | 2023.03.14 |
[DAY 53] RandomForest, One Hot Encoding, get_dummies, train_test_split (0) | 2023.03.13 |
[DAY 52] Tableau 맵 차트, 영역 차트, 계층, 총계, 퀵 테이블 계산, 인터랙티브 대시보드 만들기 (0) | 2023.03.12 |
댓글