-
Notifications
You must be signed in to change notification settings - Fork 0
week4
Minji Hong edited this page Jan 18, 2021
·
1 revision
- Dates-minute
train["Dates-minute(abs)"] = np.abs(train["Dates-minute"] - 30)
test["Dates-minute(abs)"] = np.abs(test["Dates-minute"] - 30)
분은 자세히 기록되어 있지 않기 때문에, 분에 30을 뺀 후 절대값(absolute)을 씌운다. 이렇게 하면 0분을 기존으로 상대적인 플러스/마이너스치를 알 수 있다.
- Address
def clean_address(address):
if "/" not in address:
return address
address1, address2 = address.split("/")
address1, address2 = address1.strip(), address2.strip() # strip(): 공백 제거
if address1 < address2:
address = "{} / {}".format(address1, address2)
else:
address = "{} / {}".format(address2, address1)
return address
train["Address(clean)"] = train["Address"].apply(clean_address)
test["Address(clean)"] = test["Address"].apply(clean_address)
crossroad 이름 통일 교차로 이름이 a/b, b/a로 되어있는 경우가 있기 때문에 주소값을 비교하여 알파벳이 빠를수록 작은 값이라고 가정하고, 작은 값을 앞으로, 큰 값을 뒤로 배치한다.
address_counts = train["Address(clean)"].value_counts()
top_address_counts = address_counts[address_counts >= 100]
top_address_counts = top_address_counts.index
train.loc[~train["Address(clean)"].isin(top_address_counts), "Address(clean)"] = "Others"
test.loc[~test["Address(clean)"].isin(top_address_counts), "Address(clean)"] = "Others"
발생횟수가 작은 주소에 대해 Others 처리 주소값을 많은 순으로 정렬하고, 주소 발생 횟수가 100회 이상인 데이터만 가져온다. 100회 미만 주소들은 Others로 값을 통일한다.
- 전처리
train_address = pd.get_dummies(train["Address(clean)"])
test_address = pd.get_dummies(test["Address(clean)"])
from scipy.sparse import csr_matrix
train_address = csr_matrix(train_address)
test_address = csr_matrix(test_address)
메모리의 효율적인 사용을 위해 one-hot encoding 후 CSR Matrix로 변환한다.
- 모델 생성
from scipy.sparse import hstack
X_train = hstack([X_train.astype('float'), train_address])
X_train = csr_matrix(X_train)
X_test = hstack([X_test.astype('float'), test_address])
X_test = csr_matrix(X_test)
hstack: CSR Matrix를 하나로 합친다. -> 이를 이용해서 원래 train 데이터와 CSR Matrix를 합친다. -> 이를 다시 CSR Matrix로 변환한다.
- Coarse Search Random Search를 하되, 이론상으로 존재 가능한 모든 하이퍼패러미터 범위를 집어넣는다. 가장 좋은 하이퍼패러미터를 찾는 것은 어렵지만, 좋지 않은 하이퍼패러미터를 정렬해서 후순위로 놓을 수 있다.
- Fine Search Coarse Search를 통해 좋지 않은 하이퍼패러미터를 버린 뒤 다시 한 번 Random Search 진행.
■ Coarse Search 1. 필요한 변수 세팅
import numpy as np
from lightgbm import LGBMClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import log_loss # 해당 대회의 측정공식
X_train_kf, X_test_kf, y_train_kf, y_test_kf = \
train_test_split(X_train, y_train, test_size = 0.3, random_state = 37)
n_estimators = 100 # 트리의 개수
num_loop = 100 # 랜덤서치 반복횟수
early_stopping_rounds = 20
- 여러 파라미터로 모델 생성 및 학습
coarse_hyperparameters_list = []
for loop in range(num_loop):
# 이론 상으로 존재하는 모든 하이퍼패러미터 범위 탐색
learning_rate = 10 ** np.random.uniform(low = -10, high = 1)
num_leaves = np.random.randint(2, 500)
max_bin = np.random.randint(2, 500)
min_child_samples = np.random.randint(2, 500)
subsample = np.random.uniform(low = 0.1, high = 1.0)
colsample_bytree = np.random.uniform(low = 0.1, high = 1.0)
# LGBMClassifier
model = LGBMClassifier(n_estimators = n_estimators,
learning_rate = learning_rate,
num_leaves = num_leaves,
max_bin = max_bin,
min_child_samples = min_child_samples,
subsample = subsample,
subsample_freq = 1,
colsample_bytree = colsample_bytree,
class_type = 'balanced',
random_state = 37)
# 모델 학습
model.fit(X_train_kf, y_train_kf,
eval_set = [(X_test_kf, y_test_kf)],
verbose = 0,
early_stopping_rounds = early_stopping_rounds)
# 가장 좋은 점수와 이에 해당하는 n_estimators를 저장
best_iteration = model.best_iteration_
score = model.best_score_['valid_0']['multi_logloss']
# hyperparameter 탐색 결과를 리스트에 저장
coarse_hyperparameters_list.append({
'loop': loop,
'n_estimators': best_iteration,
'learning_rate': learning_rate,
'num_leaves': num_leaves,
'max_bin': max_bin,
'min_child_samples': min_child_samples,
'subsample': subsample,
'subsample_freq': 1,
'colsample_bytree': colsample_bytree,
'class_type': 'balanced',
'random_state': 37,
'score': score,
})
# hyperparameter 탐색 결과 출력
print(f"{loop:2} best iteration = {best_iteration} Score = {score:.5f}")
- 최적 파라미터 확인
coarse_hyperparameters_list = pd.DataFrame(coarse_hyperparameters_list)
coarse_hyperparameters_list = coarse_hyperparameters_list.sort_values(by = "score")
coarse_hyperparameters_list.head()
■ Fine Search 1. 필요한 변수 세팅: Coarse Search와 동일 2. 여러 파라미터로 모델 생성 및 학습
finer_hyperparameters_list = []
for loop in range(num_loop):
# Coarse Search를 통해 범위를 좁힌 하이퍼패러미터
learning_rate = np.random.uniform(low = 0.030977, high = 0.047312)
num_leaves = np.random.randint(16, 483)
max_bin = np.random.randint(135, 454)
min_child_samples = np.random.randint(111, 482)
subsample = np.random.uniform(low = 0.411598, high = 0.944035)
colsample_bytree = np.random.uniform(low = 0.603785, high = 0.929522)
model = LGBMClassifier(n_estimators = n_estimators,
learning_rate = learning_rate,
num_leaves = num_leaves,
max_bin = max_bin,
min_child_samples = min_child_samples,
subsample = subsample,
subsample_freq = 1,
colsample_bytree = colsample_bytree,
class_type = 'balanced',
random_state = 37)
model.fit(X_train_kf, y_train_kf,
eval_set = [(X_test_kf, y_test_kf)],
verbose = 0,
early_stopping_rounds = early_stopping_rounds)
best_iteration = model.best_iteration_
score = model.best_score_['valid_0']['multi_logloss']
finer_hyperparameters_list.append({
'loop': loop,
'n_estimators': best_iteration,
'learning_rate': learning_rate,
'num_leaves': num_leaves,
'max_bin': max_bin,
'min_child_samples': min_child_samples,
'subsample': subsample,
'subsample_freq': 1,
'colsample_bytree': colsample_bytree,
'class_type': 'balanced',
'random_state': 37,
'score': score,
})
print(f"{loop:2} best iteration = {best_iteration} Score = {score:.5f}")
- 최적 파라미터 확인
finer_hyperparameters_list = pd.DataFrame(finer_hyperparameters_list)
finer_hyperparameters_list = finer_hyperparameters_list.sort_values(by = "score")
finer_hyperparameters_list.head()
fine search로 찾은 가장 좋은 파라미터를 이용하여 최종모델을 생성
best_hyperparameters = finer_hyperparameters_list.iloc[0]
model = LGBMClassifier(n_estimators = best_hyperparameters['n_estimators'],
learning_rate = best_hyperparameters['learning_rate'],
num_leaves = best_hyperparameters['num_leaves'],
max_bin = best_hyperparameters['max_bin'],
min_child_samples = best_hyperparameters['min_child_samples'],
subsample = best_hyperparameters['subsample'],
subsample_freq = best_hyperparameters['subsample_freq'],
colsample_bytree = best_hyperparameters['colsample_bytree'],
class_type = best_hyperparameters['class_type'],
random_state = best_hyperparameters['random_state'])