# -*- coding: utf-8 -*-
"""
Created on Mon Sep 20 16:15:37 2021

@author: em42363
"""
# In[1]: Import functions
'''
CatBoost is a high-performance open source library for gradient boosting
on decision trees
'''

from catboost import CatBoostRegressor
from sklearn.model_selection import train_test_split

import pandas as pd
import seaborn as sns
import numpy as np

import os
os.chdir(os.path.dirname(__file__))

import sys
sys.path.insert(0, r'C:\Users\eduar\OneDrive\PhD\UTuning')
sys.path.insert(0, r'C:\Users\em42363\OneDrive\PhD\UTuning')

from UTuning import scorer, plots

#df = pd.read_csv(r'C:\Users\eduar\OneDrive\PhD\UTuning\dataset\unconv_MV.csv')
df = pd.read_csv(r'C:\Users\em42363\OneDrive\PhD\UTuning\dataset\unconv_MV.csv')

import random
import matplotlib.pyplot as plt

# In[1]: Split train test
'''
Perform split train test
'''
y = df['Production'].values
X = df[['Por', 'LogPerm', 'Brittle', 'TOC']].values

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33)


# In[6]: Regressor
'''
Define the regressor, fit the model and predict the estimates
'''
model = CatBoostRegressor(iterations=1000, learning_rate=0.2, loss_function='RMSEWithUncertainty',
                          verbose=False, random_seed=0)
model.fit(X_train, y_train)

estimates = model.predict(X_test)

# In[9]: Plot error line
'''
Use UTuning to plot error lines
'''
plots.error_line(estimates[:, 0], y_test, np.sqrt(estimates[:, 1]), Frac=1)


# %% Define the virtual ensemble
def virt_ensemble(X_train,y_train, num_samples=100, iters=1000, lr=0.1): # 100, .1
    ens_preds = []
    
    model = CatBoostRegressor(iterations=iters, learning_rate=lr, loss_function='RMSEWithUncertainty',
                          verbose=False, random_seed=1)



    model.fit(X_train,y_train)

    
    ens_preds = model.virtual_ensembles_predict(X_test, prediction_type='VirtEnsembles', 
                                                virtual_ensembles_count=num_samples,
                                                thread_count=8)
    return np.asarray(ens_preds)

# %%
n_quantiles = 11
perc = np.linspace(0.0, 1.00, n_quantiles)

Samples = 10

ens_preds=virt_ensemble(X_train,y_train, num_samples=Samples)

Pred_array = ens_preds[:,:,0]

Knowledge_u=np.sqrt(np.var(Pred_array,axis=1)) #Knowledge uncertainty
Data_u=np.sqrt(np.mean(ens_preds[:,:,1],axis=1)) #Data uncertainty
Sigma=Knowledge_u+Data_u

# %%
'''
We use UTuning to return the Indicator Function and plot the
accuracy plot and diagnose our model.
'''
scorer = scorer.scorer(Pred_array, y_test, Sigma)

IF_array = scorer.IndicatorFunction()
avgIF = np.mean(IF_array,axis=0)

# % Second plot test
plots.error_accuracy_plot(perc,IF_array,Pred_array,y_test,Sigma)

# %
print('Accuracy = {0:2.2f}'.format(scorer.Accuracy()))
print('Precision = {0:2.2f}'.format(scorer.Precision()))
print('Goodness = {0:2.2f}'.format(scorer.Goodness()))

[((24, 0, 24, 58), 'sys.path.insert', 'sys.path.insert', ({(24, 16, 24, 17): '(0)', (24, 19, 24, 57): '"""C:\\\\Users\\\\eduar\\\\OneDrive\\\\PhD\\\\UTuning"""'}, {}), "(0, 'C:\\\\Users\\\\eduar\\\\OneDrive\\\\PhD\\\\UTuning')", False, 'import sys\n'), ((25, 0, 25, 60), 'sys.path.insert', 'sys.path.insert', ({(25, 16, 25, 17): '(0)', (25, 19, 25, 59): '"""C:\\\\Users\\\\em42363\\\\OneDrive\\\\PhD\\\\UTuning"""'}, {}), "(0, 'C:\\\\Users\\\\em42363\\\\OneDrive\\\\PhD\\\\UTuning')", False, 'import sys\n'), ((30, 5, 30, 80), 'pandas.read_csv', 'pd.read_csv', ({(30, 17, 30, 79): '"""C:\\\\Users\\\\em42363\\\\OneDrive\\\\PhD\\\\UTuning\\\\dataset\\\\unconv_MV.csv"""'}, {}), "(\n    'C:\\\\Users\\\\em42363\\\\OneDrive\\\\PhD\\\\UTuning\\\\dataset\\\\unconv_MV.csv')", True, 'import pandas as pd\n'), ((42, 35, 42, 73), 'sklearn.model_selection.train_test_split', 'train_test_split', (), '', False, 'from sklearn.model_selection import train_test_split\n'), ((49, 8, 50, 55), 'catboost.CatBoostRegressor', 'CatBoostRegressor', (), '', False, 'from catboost import CatBoostRegressor\n'), ((81, 7, 81, 42), 'numpy.linspace', 'np.linspace', ({(81, 19, 81, 22): '0.0', (81, 24, 81, 28): '1.0', (81, 30, 81, 41): 'n_quantiles'}, {}), '(0.0, 1.0, n_quantiles)', True, 'import numpy as np\n'), ((101, 8, 101, 32), 'numpy.mean', 'np.mean', (), '', True, 'import numpy as np\n'), ((104, 0, 104, 64), 'UTuning.plots.error_accuracy_plot', 'plots.error_accuracy_plot', ({(104, 26, 104, 30): 'perc', (104, 31, 104, 39): 'IF_array', (104, 40, 104, 50): 'Pred_array', (104, 51, 104, 57): 'y_test', (104, 58, 104, 63): 'Sigma'}, {}), '(perc, IF_array, Pred_array, y_test, Sigma)', False, 'from UTuning import scorer, plots\n'), ((21, 9, 21, 34), 'os.path.dirname', 'os.path.dirname', ({(21, 25, 21, 33): '__file__'}, {}), '(__file__)', False, 'import os\n'), ((59, 42, 59, 66), 'numpy.sqrt', 'np.sqrt', ({(59, 50, 59, 65): 'estimates[:, (1)]'}, {}), '(estimates[:, (1)])', True, 'import numpy as np\n'), ((66, 12, 67, 55), 'catboost.CatBoostRegressor', 'CatBoostRegressor', (), '', False, 'from catboost import CatBoostRegressor\n'), ((77, 11, 77, 32), 'numpy.asarray', 'np.asarray', ({(77, 22, 77, 31): 'ens_preds'}, {}), '(ens_preds)', True, 'import numpy as np\n'), ((89, 20, 89, 45), 'numpy.var', 'np.var', (), '', True, 'import numpy as np\n'), ((90, 15, 90, 47), 'numpy.mean', 'np.mean', (), '', True, 'import numpy as np\n')]