"""
# INDIAN PREMIER LEAGUE (IPL)

### The Indian Premier League (IPL) is a professional Twenty20 cricket league in India usually contested between March and May of every year by eight teams representing eight different cities or states in India. The league was founded by the Board of Control for Cricket in India (BCCI) in 2007.

### Teams 
* Mumbai Indians
* Chennai Super Kings
* Sunrisers Hyderabad
* Kings XI Punjab 
* Delhi Captians
* Rajasthan Royals 
* Kolkatta Knight Riders
* Royal Challengers Banglore
"""
"""
### Problem Statement: We have the historical data of all IPL matches since the year 2008 this time we are trying to predict the player performance of each player who participated in the IPL 

### Libraries Used:
* Pandas : Pandas is used for data manipulating and to slice and index the tabular dataframe. 
* Numpy : Numpy is being used to convert the dataframe into a array of numbers because the model accepts only numeric data 
* missigno : This library is used to check for null values in the given data. Since the presence of null values leads to poor performance of model
* Matplotlib and Seaborn : These libraries are used for data visualization ie to present the numeric data in a graphical manner making it easy to interpret 
* Sklearn : This library form the brain of our machine learning model. Using the we import the Linear Regression model and the metrics to evaluate our model ie mean_squared_error. Further we also use train_test_split to split our data into training and validation set. We will talk more about this as you scroll down 

#### This whole model is build using python because of the following reasons:
* Python is open source language 
* Because of its high compatablility with various modules and libraries it is the most suitable language for data analytics and machine learning applications
* Python Code are easier to understand and interpret compared to any other programming language 
"""
"""
# Loading Datasets 
"""
# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)

# Input data files are available in the read-only "../input/" directory
# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory

import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))

# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using "Save & Run All" 
# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session
"""
### Importing Libraries 
"""
import missingno as msno
from math import sqrt

import matplotlib.pyplot as plt 
import seaborn as sns 
from termcolor import colored 

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.preprocessing import StandardScaler

import tensorflow 
import keras
from keras.models import Sequential
from keras import layers
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras import layers, callbacks

teams = pd.read_csv('../input/ipl-2020-player-performance/IPL 2020 Squads.csv',encoding='latin1')
match2020 = pd.read_csv('../input/ipl-2020-player-performance/Matches IPL 2020.csv')
match = pd.read_csv('../input/ipl-2020-player-performance/Matches IPL 2008-2019.csv')
train = pd.read_csv('../input/ipl-2020-player-performance/Training.csv')
"""
Below is information stored in the four tables ie teams ,match2020,match and train along with the number of rows and columns, number of null values in each column and its corresponding datatypes. There are mainly 2 data types being discussed here Object and integer 
"""
print('*'*50)
print(colored('TEAMS','red'))
print(teams.info())
print('*'*50)
print(colored('MATCHS IN 2020','red'))
print(match2020.info())
print('*'*50)
print(colored('MATCHS 2008-2019','red'))
print(match.info())
print('*'*50)
print(colored('TRAINING DATA','red'))
print(train.info())
train.head(20)

"""
# Exploratory Data Analysis

### This section will provide us insights about the following information:
* Defining the target variable 
* Defining the dependent variables 
* Finding the relation between dependent and independent variables 
"""
"""
### Bivariate Analysis 
#### Finding the relation between all the dependent variables against the independent or target variable
"""
plt.figure(figsize=(15,10))
plt.subplot(2,3,1)
sns.scatterplot(x='Runs',y='Batting_Points',data=train)
plt.subplot(2,3,2)
sns.scatterplot(x='Boundaries',y='Batting_Points',data=train)
plt.subplot(2,3,3)
sns.scatterplot(x='Six',y='Batting_Points',data=train)
plt.subplot(2,3,4)
sns.barplot(x='Fifty',y='Batting_Points',data=train)
plt.subplot(2,3,5)
sns.barplot(x='Hundred',y='Batting_Points',data=train)
plt.subplot(2,3,6)
sns.barplot(x='Duck',y='Batting_Points',data=train)
plt.figure(figsize=(15,10))
plt.subplot(2,3,1)
sns.scatterplot(x='Runs',y='Bowling_Points',data=train)
plt.subplot(2,3,2)
sns.scatterplot(x='Boundaries',y='Bowling_Points',data=train)
plt.subplot(2,3,3)
sns.scatterplot(x='Six',y='Bowling_Points',data=train)
plt.subplot(2,3,4)
sns.barplot(x='Fifty',y='Bowling_Points',data=train)
plt.subplot(2,3,5)
sns.barplot(x='Hundred',y='Bowling_Points',data=train)
plt.subplot(2,3,6)
sns.barplot(x='Duck',y='Bowling_Points',data=train)
plt.figure(figsize=(15,10))
plt.subplot(2,2,1)
sns.scatterplot(x='Wickets',y='Batting_Points',data=train)
plt.subplot(2,2,2)
sns.barplot(x='4W_Haul',y='Batting_Points',data=train)
plt.subplot(2,2,3)
sns.barplot(x='5W_Haul',y='Batting_Points',data=train)
plt.subplot(2,2,4)
sns.barplot(x='Maidens',y='Batting_Points',data=train)
plt.figure(figsize=(15,10))
plt.subplot(2,2,1)
sns.scatterplot(x='Wickets',y='Bowling_Points',data=train)
plt.subplot(2,2,2)
sns.barplot(x='4W_Haul',y='Bowling_Points',data=train)
plt.subplot(2,2,3)
sns.barplot(x='5W_Haul',y='Bowling_Points',data=train)
plt.subplot(2,2,4)
sns.barplot(x='Maidens',y='Bowling_Points',data=train)
plt.figure(figsize=(15,5))
plt.subplot(1,2,1)
sns.scatterplot(x='Batting_Points',y='Total Points',data=train)
plt.subplot(1,2,2)
sns.scatterplot(x='Bowling_Points',y='Total Points',data=train)

"""
### Insights:

* The batting score is linearly depended on Runs scored , Boundaries , Sixs , Hundreds , Fiftys and Duck outs.
* The bowlings score is also linearly related to Runs scored , Boundaries , Sixs , Hundreds , Fiftys and Duck outs. 
* Batting score shows negative correlation with Wickets takes, 4W haul, 5W haul and maiden overs. 
* Bowling Score shows positive correlation with wickets takes , 4W Haul, 5W Haul and Maiden overs 

"""
"""
## Univariate Analysis
* Here we look for outliers in continuous data and cap some of them to 95 or 90 percent of the maximum value. The presence of outlier cause the model to learn extreme values and overfit the training data. To generalise the data well it is good to remove outliers before feeding data to the mode

* We use boxplot from seaborn library to show the presence of outliers in data
"""
plt.figure(figsize=(30,10))
plt.subplot(2,4,1)
sns.boxplot(x='Total Points',data=train)
plt.subplot(2,4,2)
sns.boxplot(x='Bowling_Points',data=train)
plt.subplot(2,4,3)
sns.boxplot(x='Batting_Points',data=train)
plt.subplot(2,4,4)
sns.boxplot(x='Runs',data=train)
plt.subplot(2,4,5)
sns.boxplot(x='Boundaries',data=train)
plt.subplot(2,4,6)
sns.boxplot(x='Six',data=train)
plt.subplot(2,4,7)
sns.boxplot(x='Wickets',data=train)

"""
## Outlier Treatment
"""
def Outlier(col_name,quantile):
    uiqr = np.percentile(train[str(col_name)],quantile)
    print('Capping outlier to value {}'.format(uiqr))
    filt = train[str(col_name)] > uiqr
    train.loc[filt,:] = uiqr
    
    return sns.boxplot(x=str(col_name),data=train)
plt.figure(figsize=(30,10))
plt.subplot(2,3,1)
Outlier('Total Points',95)
plt.subplot(2,3,2)
Outlier('Bowling_Points',90)
plt.subplot(2,3,3)
Outlier('Batting_Points',95)
plt.subplot(2,3,4)
Outlier('Runs',95)
plt.subplot(2,3,5)
Outlier('Boundaries',87)
train.columns
train['Id']
"""
#### Since the model accepts only numeric data and the columns Id from train dataset is object data type we cannot feed it to the model. Hence i first split the id column info id and surename and dropped the column.
"""
train['Id'] = np.array(train['Id'].str.split(' ',expand=True))
train.head(10)
train.drop(train[train['Id'].isnull() == True].index, inplace = True) 

train.head()
"""
#### Used numpy library to convert the dataframe in to numerical arrays. Further assigned the dependent variables to the variable x and independent variable to y 
"""
x=np.array(train.iloc[:,1:-1])
y=np.array(train.iloc[:,-1])
"""
#### Here we divide the hundred percent of training data into 80% train and 20% validation data using train_test_split method from sklearn library. We train the model on 80% of the training data and test the model on rest of the 20% of validation data which is new to the model. Then compare the prediction wi
"""
train_x,val_x,train_y,val_y = train_test_split(x,y,test_size=0.2,random_state=0)
print(train_x.shape)
print(val_x.shape)
print('*'*30)
print(train_y.shape)
print(val_y.shape)
"""
# Linear Regression 
#### Since there exists a linear relation between the dependent and independent variable we choose the linear regression model to perform the prediction task. This model accepts numeric values and tunes its weights in order to form a generalised polynomial equation that can evaluate the value of y. 

"""
model = LinearRegression()
model.fit(train_x,train_y)
pred_y = model.predict(val_x)
pred_y[2]
val_y[2]
sqrt(mean_squared_error(pred_y,val_y))