import pandas as pd

raw_train = pd.read_csv("../input/kagglecamp2022/train.csv")
raw_train
category_cols = []
colunq_dict = dict()
for col in raw_train.columns:
    colunq_dict[col] = len(raw_train[col].unique())
    
    if 'Cover_Type' == col:
        continue
    
    if colunq_dict[col] < 40:
        category_cols.append(col)
colunq_dict
category_cols
category_cols
raw_train.isnull().sum(axis=1).describe()
raw_train.isnull().any(axis=1).sum(), round(raw_train.isnull().any(axis=1).sum() / raw_train.shape[0],2)
"""
- 행 단위 데이터의 null 값의 평균 0.23 , 표준편차 0.47

- 제 1,2,3 사분위수가 0인 것으로 보아 데이터는 대부분 널값이 없음
- null이 1개 이상 존재하는 데이터는 전체의 21%
"""
distance_cols = []
for col in raw_train.columns:
    if "Dis" in col:
        print(col)
        distance_cols.append(col)
import matplotlib.pyplot as plt
# for col in distance_cols:
#     print(col)
#     raw_train[col].hist()
#     plt.show()
"""
- Vertical_Distance_To_Hydrology에 음수가 존재
- Horizontal_Distance_To_Roadways, Horizontal_Distance_To_Fire_Points, Horizontal_Distance_To_Hydrology의 분포 형태 유사
"""
raw_train.Cover_Type.value_counts()
raw_train.Cover_Type.hist()
raw_corr = raw_train.corr()
fig = plt.figure(figsize=(20,6))
import numpy as np
mask = np.triu(raw_corr)
import seaborn as sns
sns.heatmap(raw_corr, 
               annot = True,      # 실제 값 화면에 나타내기
               cmap = 'RdYlBu_r',  # Red, Yellow, Blue 색상으로 표시
               vmin = -1, vmax = 1, #컬러차트 -1 ~ 1 범위로 표시
               mask=mask
              )
plt.show()
"""
# 원핫인코딩
"""
category_cols = []
colunq_dict = dict()
for col in raw_train.columns:
    colunq_dict[col] = len(raw_train[col].unique())
    
    if 'Cover_Type' == col:
        continue
    
    if colunq_dict[col] < 40:
        category_cols.append(col)
colunq_dict



from sklearn.preprocessing import OneHotEncoder
ohe_dict = dict()
ohe_df = raw_train.copy()
for col in category_cols:
    ohe = OneHotEncoder()
    df = ohe.fit_transform(raw_train[[col]]).toarray().astype(int)
    df = pd.DataFrame(df, columns=[str(col)+"_" + str(value) for value in ohe.categories_[0]])
    ohe_df = ohe_df.join(df)
    ohe_df= ohe_df.drop(columns = col)
    
    ohe_dict[col] = ohe
"""
# Test data 전처리 (원핫 인코딩)
"""
test_df = pd.read_csv("../input/kagglecamp2022/test.csv")
ohe_test = test_df.copy()

for col in category_cols:
    df = ohe_dict[col].transform(test_df[[col]]).toarray().astype(int)
    df = pd.DataFrame(df, columns=[str(col)+"_" + str(value) for value in ohe_dict[col].categories_[0]])
    ohe_test = ohe_test.join(df)
    ohe_test.drop(columns = col, inplace=True)
"""
# 데이터 셋 분리
"""
from sklearn.model_selection import train_test_split
X_train_ids = ohe_df['id']
ohe_data = ohe_df.drop(columns = 'id')

target = ohe_data["Cover_Type"]
InputData = ohe_data.drop(columns="Cover_Type")
test_ids = ohe_test['id']
ohe_X_test = ohe_test.drop(columns = 'id')
ohe_X_test.shape
X_train, X_val, y_train, y_val = train_test_split(InputData, target,
                                                  stratify = target,
                                                  test_size = 0.2)
X_train.shape
from sklearn.metrics import accuracy_score, confusion_matrix,f1_score, make_scorer

f1_scorer = make_scorer(f1_score,average='macro')
"""
# LGBM Classifer 사용
"""
# from lightgbm import LGBMClassifier
# lgbm = LGBMClassifier(n_estimators=100)
# lgbm.fit(X_train,y_train,eval_set=(X_val,y_val),verbose=False)
# pred = lgbm.predict(X_val)
# lgbm_f1 = f1_score(y_val,pred,average='macro')
# print(lgbm_f1)
# from sklearn.model_selection import RandomizedSearchCV, GridSearchCV
# from lightgbm import LGBMClassifier
# # params = {
# #     'n_estimators': [100], 
# #     'max_depth': [30,50,70]
# # }
# # clf = RandomizedSearchCV(LGBMClassifier(), params, random_state=42, cv=3, n_iter=25, scoring=f1_scorer)

# # clf.fit(X_train,y_train, eval_set=(X_val,y_val),verbose=False)

# # print('최적 하이퍼 파라미터: ', clf.best_params_)
# # print('최고 예측 정확도: {:.4f}'.format(clf.best_score_))


# # params = {'max_depth': [10, 15, 20],
# #           'min_child_samples': [20, 40, 60],
# #           'subsample': [0.8, 1]}

# # lgbm = LGBMClassifier(n_estimators=200)
# # grid = GridSearchCV(lgbm, param_grid=params)
# # grid.fit(X_train, y_train, early_stopping_rounds=100, eval_metric='auc',
# #          eval_set=[(X_val, y_val)])
# # lgbm_best_params = clf.best_params_
# # best_lgbm = LGBMClassifier(**lgbm_best_params)
# lgbm = LGBMClassifier(n_estimators=1000, num_leaves=50, subsample=0.8,
#                       min_child_samples=60, max_depth=20)
# lgbm.fit(X_train,y_train,eval_set=(X_val,y_val),verbose=False)
"""
LGBMClassifier(max_depth=20, min_child_samples=60, n_estimators=1000,
               num_leaves=50, subsample=0.8)
"""
"""
0.8734711984876256
"""
# pred = lgbm.predict(X_val)
# lgbm_f1 = f1_score(y_val,pred,average='macro')
# print(lgbm_f1)
# lgbm_pred = lgbm.predict(ohe_X_test)
# lgbm_submission = pd.read_csv("../input/kagglecamp2022/sample_submission.csv")
# lgbm_submission['Cover_Type'] = lgbm_pred
# lgbm_submission.to_csv("submission.csv",index=False)
xgb_target = target-1

X_train, X_val, y_train, y_val = train_test_split(InputData, xgb_target,
                                                  stratify = xgb_target,
                                                  test_size = 0.2)
# from xgboost import XGBClassifier

# xgb = XGBClassifier(**best_params_xgb)
# xgb.fit(X_train,y_train)
# pred = xgb.predict(X_test)
# xgb_acc = f1_score(y_test, pred)
# print(xgb_acc)
# from xgboost import XGBClassifier
# from sklearn.model_selection import GridSearchCV
# from sklearn.metrics import accuracy_score, confusion_matrix,f1_score, make_scorer

# f1_scorer = make_scorer(f1_score,average='macro')


# # 객체 생성, 일단은 트리 100개만 만듦
# xgb_model = XGBClassifier(random_state=42,tree_method='gpu_hist')

# # 후보 파라미터 선정
# params = {'max_depth':[3,8],# 'min_child_weight':[1,3,6], 'colsample_bytree':[0.3,0.5,0.7],
#           'objective' : ['multi:softmax'],'eval_metric' :['merror'],
#           'colsample_bylevel' : [0.5,0.8], 'min_child_weight' : [3],'n_estimators' : [100],
#           'gamma' : [0.2,0.6]}

# # gridsearchcv 객체 정보 입력(어떤 모델, 파라미터 후보, 교차검증 몇 번)
# # gridcv = GridSearchCV(xgb_model, param_grid=params, cv=3,scoring=f1_scorer)

# rancv = RandomizedSearchCV(xgb_model,param_distributions=params,
#                   n_iter = 5,cv = 3,scoring = f1_scorer)


# rancv.fit(X_train, y_train, early_stopping_rounds=30, eval_set=[(X_val, y_val)],verbose=False)
# best_xgb = rancv.best_estimator_ 
"""
{'objective': 'multi:softmax', 'n_estimators': 100, 'min_child_weight': 3, 'max_depth': 8, 'gamma': 0.2, 'eval_metric': 'merror', 'colsample_bylevel': 0.8}
"""
best_params_xgb = {'objective': 'multi:softmax', 'n_estimators': 100, 'min_child_weight': 3, 'max_depth': 8, 'gamma': 0.2, 'eval_metric': 'merror', 'colsample_bylevel': 0.8}
best_params_xgb['tree_method'] = 'gpu_hist'
best_params_xgb['random_state'] = 42
best_params_xgb['n_estimators'] = 500
print(best_params_xgb)
test_ids = ohe_test['id']
ohe_test.drop(columns='id',inplace=True)
from xgboost import XGBClassifier
xgb_model = XGBClassifier(**best_params_xgb)
xgb_model.fit(X_train,y_train,verbose=False)
submission = pd.read_csv("../input/kagglecamp2022/sample_submission.csv")
xgb_pred = xgb_model.predict(ohe_test) + 1
submission['Cover_Type'] = xgb_pred
submission.to_csv("submission.csv",index=False)