import numpy as np 
import pandas as pd 
import warnings
warnings.filterwarnings('ignore')

import plotly.graph_objects as go
df = pd.read_json('../input/fraud-detection-dataset/transactions.txt', lines=True)
df.head()
df.shape
df.columns
df.dtypes
df.nunique()
#empty columns
df.drop(['merchantCity','merchantState','merchantZip','echoBuffer','posOnPremises','recurringAuthInd'],axis=1,inplace=True)
df.head()
"""
#### **Target col**
"""
fig = go.Figure(data=[go.Pie(labels=df.isFraud, hole=.3)])
fig.add_annotation(text='isFraud',
                   x=0.5,y=0.5,showarrow=False,font_size=14,opacity=0.7,font_family='monospace')
fig.update_traces(hoverinfo='label+percent+value',
                  marker=dict(colors=['darkorange','blue'], line=dict(color='#000000', width=2)))
fig.show()
"""
#### **Data preprocessing**
"""
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
var = ['merchantName','acqCountry','merchantCountryCode','posEntryMode','posConditionCode','merchantCategoryCode','transactionType','cardPresent','expirationDateKeyInMatch','isFraud']
for i in var:
    df[i] = le.fit_transform(df[i])
# converting in datetime format
df['transactionDateTime'] = pd.to_datetime(df['transactionDateTime'])
df['currentExpDate'] = pd.to_datetime(df['currentExpDate'])
df['accountOpenDate'] = pd.to_datetime(df['accountOpenDate'])
df['dateOfLastAddressChange'] = pd.to_datetime(df['dateOfLastAddressChange'])
# extractind year, month, day, hour, minute and seconds from datetime columns
df['transactionDateTime_year'] = df['transactionDateTime'].dt.year
df['transactionDateTime_month'] = df['transactionDateTime'].dt.month
df['transactionDateTime_day'] = df['transactionDateTime'].dt.day
df['transactionDateTime_hour'] = df['transactionDateTime'].dt.hour
df['transactionDateTime_minute'] = df['transactionDateTime'].dt.minute
df['transactionDateTime_second'] = df['transactionDateTime'].dt.second

df['currentExpDate_year'] = df['currentExpDate'].dt.year
df['currentExpDate_month'] = df['currentExpDate'].dt.month
df['currentExpDate_day'] = df['currentExpDate'].dt.day

df['accountOpenDate_year'] = df['accountOpenDate'].dt.year
df['accountOpenDate_month'] = df['accountOpenDate'].dt.month
df['accountOpenDate_day'] = df['accountOpenDate'].dt.day

df['dateOfLastAddressChange_year'] = df['dateOfLastAddressChange'].dt.year
df['dateOfLastAddressChange_month'] = df['dateOfLastAddressChange'].dt.month
df['dateOfLastAddressChange_day'] = df['dateOfLastAddressChange'].dt.day
# drop datetime column
df.drop('transactionDateTime',axis = 1,inplace = True)
df.drop('currentExpDate',axis = 1,inplace = True)
df.drop('accountOpenDate',axis = 1,inplace = True)
df.drop('dateOfLastAddressChange',axis = 1,inplace = True)
df.head()
df.dtypes
"""
#### **VIF (Variable Inflation Factors)**
for multicollinearity detection
"""
from statsmodels.stats.outliers_influence import variance_inflation_factor

def calc_vif(X):

    # Calculating VIF
    vif = pd.DataFrame()
    vif["variables"] = X.columns
    vif["VIF"] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]

    return(vif)
X = df.drop('isFraud',axis=1)
calc_vif(X)
"""
We can see here that the 'enteredCVV','customerId','availableMoney', 'currentBalance','cardCVV','accountNumber' and 'creditLimit'  have a high VIF value, meaning they can be predicted by other independent variables in the dataset.

#### **Fixing Multicollinearity**
Dropping one of the correlated features will help in bringing down the multicollinearity between correlated features:


"""
df.drop(['enteredCVV','customerId','availableMoney'],axis=1,inplace=True)
X = df.drop('isFraud',axis=1)
calc_vif(X)
"""
#### **Model building**
"""
"""
I'm using pycaret. pycaret package is used to automate the major steps for evaluating and comparing machine learning algorithms for classification and regression. The main benefit of the library is that a lot can be achieved with very few lines of code and little manual configuration.
"""
! pip install pycaret
from pycaret.classification import setup, compare_models, blend_models, finalize_model, predict_model
def pycaret_model(train, target, n_select, fold, opt):
    print('Setup Your Data....')
    setup(data=train,
              target=target,
              numeric_imputation = 'mean',
              silent= True)
  
    print('Comparing Models....')
    best = compare_models(sort=opt, n_select=n_select, fold = fold,include = ['gbc','rf','et','xgboost','lightgbm','catboost'])
    # gbc = gradient boosting classifier
    # rf = random forest classifier
    # et = extra tree classifier
    
    print('Blending Models....')
    blended = blend_models(estimator_list= best, fold=fold, optimize=opt)
    pred = predict_model(blended)
    
    return pred
pycaret_model(df, 'isFraud', 5, 3, 'Accuracy')