"""
# IF you like this notebook then please give an upvote 👍
**and also give suggestions in comment 🙌**
"""
import datetime
import tensorflow as tf
import keras
import itertools
import matplotlib
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.utils import class_weight
import tensorflow_addons as tfa
from sklearn.model_selection import StratifiedKFold
from imblearn.combine import SMOTEENN
from imblearn.under_sampling import RandomUnderSampler
from imblearn.pipeline import Pipeline
from sklearn.metrics import mean_absolute_error as mae
import random
import math
from sklearn.metrics import accuracy_score
from hyperopt import STATUS_OK, Trials, fmin, hp, tpe
import plotly.express as px
from plotly.subplots import make_subplots
import seaborn as sns
from sklearn import preprocessing
import numpy as np
import pandas as pd
from sklearn.model_selection import KFold, StratifiedKFold, cross_val_score
from sklearn import linear_model, tree, ensemble
from xgboost import plot_importance
import optuna

def sigmoid(x):
    return 1 / (1 + math.exp(-x))
"""
# Importing of Dataset
"""
df=pd.read_csv('../input/home-data-for-ml-course/train.csv')
test=pd.read_csv('../input/home-data-for-ml-course/test.csv')
x=test.drop('Id', axis=1)
df=df.drop('Id', axis=1)
df=df.sample(frac=1)
X=df.drop('SalePrice', axis=1)
y=df.SalePrice
object_columns = X.select_dtypes(include=['object']).columns
numeric_columns = X.select_dtypes(exclude=['object']).columns
total_X=pd.concat([X,x], ignore_index=True)
total_X.reset_index()
df.info()
object_columns
numeric_columns
import missingno as msno

msno.bar(df[numeric_columns])
plt.show()
total_X[object_columns].isnull().sum()
total_X[numeric_columns].isnull().sum()
"""
**we can see garage yr built has some missing values and in object features there are missing of garage details which means garage is not built yet**
"""
"""
# Handling of Missing Values for Categorical Features
"""
for i in object_columns:
    if(total_X[i].isnull().sum()<=50 & total_X[i].isnull().sum()>0):
        total_X[i]=total_X[i].fillna(total_X[i].mode()[0], inplace = True)
total_X[object_columns]=total_X[object_columns].fillna('NA')
"""
# Handling of Missing values of numerical Features
"""
for i in numeric_columns:
    if(total_X[i].isnull().sum()<50 & total_X[i].isnull().sum()>0):
        total_X[i]=total_X[i].fillna(total_X[i].mean())
total_X['LotFrontage']=total_X['LotFrontage'].fillna(0)     
#missing values for garage yr built indicates that garage is not made yet
fig=px.scatter(df,
                 x="GarageYrBlt", y="SalePrice",
                 log_x=True, size_max=20,
                 template='plotly', title="How saleprice varies with year garage was built?",opacity=1)
fig.show()  
"""
**It is clear that SalePrice is dependent on GarageYrBlt so we take min yr as it is not built so...**
"""
total_X['GarageYrBlt']=total_X['GarageYrBlt'].fillna(total_X['GarageYrBlt'].min())
X=total_X.iloc[:len(y),:]
X['SalePrice']=y
"""
# Lets visualize relations in details
"""
fig, ax=plt.subplots(figsize=(15,5))
sns.histplot(df['SalePrice'],kde=True)
ax.set_title('How is SalePrice distributed')
plt.show()
sns.catplot(x = 'HouseStyle', y = 'SalePrice', data = df, kind = 'bar', hue='RoofStyle', height=10, aspect=2)
fig=px.scatter(df,
                 x="LotArea", y="SalePrice",
                 log_x=True, size_max=20,
                 template='plotly', title="How saleprice varies with LotArea?",opacity=0.7, color='YrSold')
fig.show()  
sns.catplot(x = 'YrSold', y = 'SalePrice', data = df, kind = 'bar', hue='SaleType', height=10, aspect=2)
sns.barplot(x='CentralAir', y='SalePrice', data=df);
sns.kdeplot(x=X['YrSold'], shade=True)
corrmatrix=df.corr()
fig, ax=plt.subplots(figsize=(30,30))
sns.heatmap(corrmatrix, vmax=8, square=True, annot=True, fmt='.2f')
plt.show()
plt.figure(figsize=(28,50))
c=1
for i in numeric_columns:
    plt.subplot(7, 6, c)
    #sns.scatterplot(data=X, x=i, y="SalePrice", hue="CentralAir", fit_reg=True)
    sns.regplot(x=i, y="SalePrice", data=df)
    plt.title(str(i)+" Vs SalePrice")
    c+=1
plt.subplots_adjust(wspace=0.3, hspace=-0.1)
plt.show()    
"""
# Feature Generation
"""
#how much is the age of house can be a good feature
total_X['---**---Age']=total_X['YrSold']-total_X['YearBuilt']
total_X['---**---Garage_Age']=total_X['YrSold']-total_X['GarageYrBlt']
total_X['---**---Age_se']=total_X['YrSold']-total_X['YearRemodAdd']
total_X['---**---full_bath_per_bedroom']=total_X['FullBath']/(total_X['BedroomAbvGr'])
total_X['---**---half_bath_per_bedroom']=total_X['HalfBath']/(total_X['BedroomAbvGr'])
total_X['---**---garage_per_bedroom']=total_X['GarageCars']/(total_X['BedroomAbvGr'])
total_X['---**---kitchen_per_bedroom']=total_X['KitchenAbvGr']/(total_X['BedroomAbvGr'])
total_X['---**---full_bath_per_bedroom']= total_X['---**---full_bath_per_bedroom'].apply(lambda x: sigmoid(x))
total_X['---**---half_bath_per_bedroom']=total_X['---**---half_bath_per_bedroom'].apply(lambda x: sigmoid(x))
total_X['---**---garage_per_bedroom']=total_X['---**---garage_per_bedroom'].apply(lambda x: sigmoid(x))
total_X['---**---kitchen_per_bedroom']=total_X['---**---kitchen_per_bedroom'].apply(lambda x: sigmoid(x))
"""
# encoding categorical features
"""
%%capture
dummies = pd.get_dummies(total_X[object_columns])
total_X=total_X.drop(object_columns, axis=1)
total_X = pd.concat([total_X, dummies], axis=1, join='inner')
for col in numeric_columns:
    percentiles = total_X[col].quantile([0.05, 0.95]).values
    total_X[col][total_X[col] <= percentiles[0]] = percentiles[0]
    total_X[col][total_X[col] >= percentiles[1]] = percentiles[1]
total_X=total_X.drop('MoSold', axis=1)
X=total_X.iloc[:len(y),:]
x=total_X.iloc[len(y):,:]
kf =KFold(n_splits=5, shuffle=True, random_state=42)
cnt = 1
for train_index, test_index in kf.split(X, y):
    print(f'Fold:{cnt}, Train set: {len(train_index)}, Test set:{len(test_index)}')
    cnt += 1
X_train, X_validation, y_train, y_validation = train_test_split(X, y, test_size=0.1)
import xgboost as xgb
from xgboost import XGBRegressor, XGBClassifier
xgb_m = XGBRegressor(n_estimators=1000, random_state=0, tree_method='gpu_hist', gpu_id=0)
xgb_m.fit(X_train,y_train)
preds=xgb_m.predict(X_validation)
r=mae(y_validation, preds)
print(r)
fig, ax=plt.subplots(figsize=(20,60))
plot_importance(xgb_m,ax=ax)
plt.show()
"""
# Tuning hyperparams
"""
def objective(trial,data=X,target=y):
    
    train_x, test_x, train_y, test_y = train_test_split(data, target, test_size=0.1,random_state=42)
    param = {
        'tree_method':'gpu_hist',  # this parameter means using the GPU when training our model to speedup the training process
        'lambda': trial.suggest_loguniform('lambda', 1e-3, 10.0),
        'alpha': trial.suggest_loguniform('alpha', 1e-3, 10.0),
        'colsample_bytree': trial.suggest_categorical('colsample_bytree', [0.3,0.4,0.5,0.6,0.7,0.8,0.9, 1.0]),
        'subsample': trial.suggest_categorical('subsample', [0.4,0.5,0.6,0.7,0.8,1.0]),
        'learning_rate': trial.suggest_categorical('learning_rate', [0.008,0.009,0.01,0.012,0.014,0.016,0.018, 0.02]),
        'max_depth': trial.suggest_categorical('max_depth', [5,7,9,11,13,15,17,20]),
        'random_state': trial.suggest_categorical('random_state', [24, 48,2020]),
        'min_child_weight': trial.suggest_int('min_child_weight', 1, 300),
        'n_estimators': trial.suggest_categorical('n_estimators',[3200,3400,3500,3600,3800,3900])
    }
    model = XGBRegressor(**param)  
    
    model.fit(train_x,train_y,eval_set=[(test_x,test_y)],early_stopping_rounds=100,verbose=False)
    
    preds = model.predict(test_x)
    
    rmse = mae(test_y, preds)
    
    return rmse
study = optuna.create_study(direction='minimize')
study.optimize(objective, n_trials=100)
print('Number of finished trials:', len(study.trials))
print('Best trial:', study.best_trial.params)
def checking(X,y,params_fi):
    xgb_m = XGBRegressor(**params_fi, tree_method='gpu_hist', gpu_id=0)
    r = -1*cross_val_score(xgb_m, X, y, cv= kf, scoring="neg_mean_absolute_error")
    r=r.mean()
    print("The model gives Mae loss of "+str(r))          
    return xgb_m  
params_fi=study.best_trial.params
xt=checking(X,y,params_fi)
xt.fit(X,y)
fig, ax=plt.subplots(figsize=(20,60))
plot_importance(xt,ax=ax)
plt.show()
t_df=pd.read_csv('../input/home-data-for-ml-course/sample_submission.csv')
preds=xt.predict(x)
t_df['SalePrice']=preds
import gzip
t_df.to_csv('sub.gz', index=False, compression='gzip')
t_df.head(10)
"""
# IF you like this notebook then please give an upvote 👍
**and also give suggestions in comment 🙌**
"""