TabNet Regressor 간단실습

<개념>/Deep learning|2023. 1. 5. 12:59
반응형

데이터는 kaggle 주택데이터 사용했고 데이터 다운은 아래 더보기 클릭 

 

X      = train_data[features]
y      = np.log1p(train_data["SalePrice"]) # log1p !!!!!!!!!!!
X_test = test_data[features]
y_true = solution["SalePrice"]
import pandas as pd
import numpy  as np
from pytorch_tabnet.tab_model import TabNetRegressor
from sklearn.model_selection import KFold

pd.set_option('display.max_columns', None) # dataframe 잘림없이 출력
pd.set_option('display.max_rows', None)
pd.set_option('display.max_seq_items', None) # 리스트 잘림없이 출력
pd.options.display.float_format = '{:.5f}'.format  # e, 지수없이 출력
pd.set_option('display.max_colwidth', -1) #pd로 볼때 ...없이 출력
import warnings # warning 무시
warnings.filterwarnings('ignore')
pd.set_option('mode.chained_assignment',  None) # SettingWithCopyWarning 경고끄기
train_data = pd.read_csv('./train.csv')
test_data  = pd.read_csv('./test.csv')
sample     = pd.read_csv('./sample_submission.csv')
solution   = pd.read_csv('./solution.csv')

print(len(train_data))
print(len(test_data))
print(len(sample))
print(len(solution))
features = ['LotArea', 'OverallQual', 'OverallCond', 'YearBuilt', 
            'YearRemodAdd', 'BsmtFinSF1', 'BsmtFinSF2', 'TotalBsmtSF', 
            '1stFlrSF', 'LowQualFinSF', 'GrLivArea', 'BsmtFullBath', 
            'BsmtHalfBath', 'HalfBath', 'BedroomAbvGr',  'Fireplaces', 
            'GarageCars', 'GarageArea', 'WoodDeckSF', 'OpenPorchSF', 
            'EnclosedPorch',  'PoolArea', 'YrSold']
X      =      X.apply(lambda x: x.fillna(x.mean()),axis=0)
X_test = X_test.apply(lambda x: x.fillna(x.mean()),axis=0)

X      = X.to_numpy()
y      = y.to_numpy().reshape(-1, 1)
X_test = X_test.to_numpy()

# 결측지 해결
X = np.nan_to_num(X) 
X_test = np.nan_to_num(X_test) 
y = np.nan_to_num(y) 
y_true = np.nan_to_num(y_true)
kf = KFold(n_splits=5, random_state=42, shuffle=True) # 5개로 나누기
predictions_array = []
predictions_array2 = []
CV_score_array    = []
for train_index, test_index in kf.split(X): # train_index는 kfold1회에서 train조합, test_index는 테스트조합
    X_train, X_valid = X[train_index], X[test_index]  # train,valid 조합을 나나눠줌
    y_train, y_valid = y[train_index], y[test_index]  # y도 마찬가지
    regressor = TabNetRegressor(verbose=0,seed=42) # 모델정의
    regressor.fit(X_train=X_train, y_train=y_train, # fit + eval_set 추가
              eval_set=[(X_valid, y_valid)],
              patience=300, max_epochs=2000, #patience=성능이좋지않은 epoch 300번이상 반복되면 그마해라
              eval_metric=['rmse'])
    CV_score_array.append(regressor.best_cost) # 5회반복중에 가장좋은점수 저장저장
    predictions_array.append(np.expm1(regressor.predict(X_test)))
predictions = np.mean(predictions_array,axis=0)
print("The CV score is %.5f" % np.mean(CV_score_array,axis=0) ) # cv score 평균값
# from sklearn.metrics import mean_squared_log_error
# RMSLE = np.sqrt( mean_squared_log_error(y_true, predictions) )
# print("The LB score is %.5f" % RMSLE )

def mape(y_test, pred):
    y_test, pred = np.array(y_test), np.array(pred)
    mape = np.mean(np.abs((y_test - pred) / y_test))
    return mape

print(mape(y_true, predictions)*100)

 

 

여기서 y값에 log1p해주고 마지막에 expm1 해주는이유가 궁금했는데

 

 

Q. log말고 log1p해주는 이유?

로그그래프는 아래 그림처럼 0에 가까운 매우 작은수의 경우 무한 음수로 바뀜. 그래서 데이터보면 -Inf상태로 바뀌는걸 볼수가 있음. 그래서 이걸 방지하기 위해 1을 더해주어 방지하는것임.

Q. 굳이 log 씌워서 진행하는 이유?

데이터가 어떤 구간에 엄청 몰려있는 경우가 있음. 이럴때 log를 씌워주면 정규분포 비슷한 형태로 만들어줄수가 있음. 데이터 불균형을 풀어주기위한 방법

 

 

 

 

참조 

 

반응형

댓글()