https://www.kaggle.com/competitions
Kaggle은 2010년 설립된 예측모델 및 분석 대회 플랫폼입니다.
위의 링크인 Kaggle Competition으로 들어가시면 기업 또는 단체에서 등록한 머신러닝 문제에 도전할 수 있습니다.
Competition에 등록된 문제는 대부분 raw data이기 때문에 회귀 또는 분류 모델로 학습을 하기 위한 전처리 과정이 필수적입니다.
따라서 이전 포스팅을 기반으로 kaggle competition 데이터 전처리를 진행해보겠습니다.
https://www.kaggle.com/competitions/hotel-booking-demand-3
해당 competition은 호텔 이용자 데이터를 분석하여 호텔 예약이 취소될지 아닐지를 분류하는 머신러닝 알고리즘을 개발하는 것입니다.
데이터는 정답값(y)인 'is_canceled' 칼럼을 제외하여 총 28개의 칼럼으로 이루어져 있습니다.
데이터는 문자, 숫자, 날짜 등이 존재합니다.
먼저 문자 데이터는 기본적으로 학습에 사용할 수 없습니다.
'arrival_data_month' 칼럼은 1월부터 12월을 나타내고, 이것을 숫자로 바꿔줘야 합니다.
이 작업을 인코딩(encoding)이라고 부릅니다.
예를 들어 1월은 0, 2월은 1, 3월은 2, ... 12월은 11
이런식으로 문자를 숫자로 바꿀 수 있습니다. 이러한 방법은 label encoding이라고 부릅니다.
하지만 이러한 label encoding같은 경우에 1월은 0이고, 12월은 11이 됩니다.
1월과 12월은 날짜를 나타낼 뿐 둘 중 어느 달이 더 중요한 값인지는 말하기 어렵습니다.
머신러닝 모델이 학습을 진행할 때, 12월의 값인 11이 1월인 0보다 훨씬 큰 값이 때문에 모델의 예측이 편향될 수 있습니다.
따라서 이러한 경우는 one-hot encoding을 통해 0과 1로 데이터를 표현하는 것이 좀 더 좋습니다.
'arrival_data_month' 칼럼을 one-hot encoding할 경우 첫 번째 데이터인 'February'은 1월부터 12월까지를 순서대로 고려하여 [0 1 0 0 0 0 0 0 0 0 0 0] 와 같이 표현될 수 있습니다.
'February'가 2월이기 때문에 이해를 돕기 위해 위와 같이 표현했지만,
그 순서는 직접 지정할 수 있으며 sklearn이나 pandas 라이브러리를 이용하면 default는 문자의 알파벳 순서입니다.
데이터 인코딩을 위해서는 먼저 데이터를 살펴볼 필요가 있습니다.
칼럼별 unique 값을 확인해보겠습니다.
for col in train_df.columns:
print('=============== ' + col + ' ===============')
print(train_df[col].unique())
hotel 칼럼은 문자이기 때문에 인코딩이 필수이며 unique 값이 'Resort hotel'과 'City hotel' 인것으로 볼 때, 순서의 의미가 없는 명목 데이터입니다. 또한 unique 값의 개수가 2개이기 때문에 이 경우에는 label encoding을 하겠습니다.
def label_encoding(in_df, column_list):
out_df = in_df.copy()
for col in column_list:
le = LabelEncoder()
value_data = out_df[col].values
new_data = le.fit_transform(value_data)
out_df[col] = new_data
return out_df
new_train_df = label_encoding(train_df, ['hotel'])
label_encoding 함수는 data frame의 칼럼명을 리스트로 전달받아 해당하는 칼럼에 전부 label encoding을 적용합니다.
나머지 문자로된 칼럼 'country', 'market_segment' 등은 one-hot encoding을 적용합니다.
또한 'arrival_date_year' 칼럼은 연도를 나타내는 숫자이지만 그 숫자들의 순서가 서로 의미가 없고 2015년에서 2017년까지 총 3년으로 제한하고 있기 때문에 (competition description에 기재되어 있음) one-hot encoding을 적용합니다.
def onehot_encoding(in_df, column_list):
out_df = in_df.copy()
for col in column_list:
new_data = pd.get_dummies((out_df[col]))
for i, name in zip(range(len(out_df)), out_df.columns):
if name == col:
for n in new_data.columns:
out_df.insert(i, str(col)+'_'+str(n), new_data[n])
break
out_df.drop(col, axis=1, inplace=True)
return out_df
new_train_df = onehot_encoding(new_train_df,
['arrival_date_year', 'arrival_date_month',
'arrival_date_day_of_month', 'meal', 'country', 'market_segment',
'distribution_channel', 'reserved_room_type', 'assigned_room_type',
'deposit_type', 'customer_type'])
'lead_time' 칼럼과 같은 데이터는 숫자이며, 'arrival_data_year' 칼럼과 같이 유한개로 정해져있기 않기 때문에 encoding을 할 수 없습니다.
Encoding을 할 수 있는 경우는 어떠한 테스트 데이터를 예측에 사용하더라도 해당 칼럼의 도메인의 범위를 벗어나지 않는다는 것이 보장 될 때 입니다. ('arrival_data_year'은 칼럼은 훈련 및 테스트 데이터 모두 2015~2017으로 제한되어 있습니다.)
하지만 'lead_time' 칼럼의 값은 최솟값은 0이고 최댓값은 500을 넘습니다.
이렇게 데이터 값의 범위가 크면 모델 학습에 악영향을 줄 수 있습니다. (편향성)
Scaling 방법은 여러가지가 있지만, 여기서는 standard scaler를 사용하겠습니다.
def standard_scaling(in_df, column_list):
out_df = in_df.copy()
for col in column_list:
std = StandardScaler()
std.fit(out_df[[col]])
new_data = std.transform(out_df[[col]])
out_df[col] = new_data
return out_df
new_train_df = standard_scaling(new_train_df,
['lead_time', 'arrival_date_week_number', 'stays_in_weekend_nights',
'stays_in_week_nights', 'adults', 'children', 'babies', 'previous_cancellations',
'previous_bookings_not_canceled', 'booking_changes', 'days_in_waiting_list',
'adr', 'required_car_parking_spaces', 'total_of_special_requests'])
'reservation_status_date' 칼럼을 제외하고 위와 같이 label encoding, one-hot encoding, standard scaling을 진행한 결과,
데이터셋의 27개의 칼럼이 271개가 되었습니다.
분류 모델에 전처리된 데이터를 사용하여 호텔 예약 취소 여부를 예측해보겠습니다.
사용된 모델은 xgboost classifier 입니다.
(훈련 및 검증 데이터 split 코드는 생략되었습니다.)
xg = XGBClassifier(gamma=0.5, learning_rate=0.03, max_depth=32, n_estimators=1000, silent=1)
xg.fit(X_train, y_train, early_stopping_rounds=20, eval_set=[(X_val, y_val)])
y_pred_xgb = xg.predict(X_val)
print('XGB Accuracy : %.4f' % accuracy_score(y_val, y_pred_xgb))
# XGB Accuracy : 0.8776
'AI > Machine Learning' 카테고리의 다른 글
[Machine Learning] 크로스-밸리데이션 (cross-validation) (0) | 2022.09.13 |
---|---|
[Machine Learning] 최소 제곱법 (0) | 2022.09.07 |
[Machine Learning] 통계학 - 평균과 분산 (0) | 2022.08.10 |
[Machine Learning] 통계학 - 확률 변수와 확률 분포 (0) | 2022.08.10 |
[Machine Learning] 선형대수 - 특이값 분해 (0) | 2022.08.09 |