<jupyter_start><jupyter_text><jupyter_code>import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
from IPython.display import display

import warnings
warnings.filterwarnings('ignore')

pd.options.display.max_columns = None
from sklearn.linear_model import LinearRegression,Ridge,SGDRegressor,ElasticNet
from sklearn import linear_model
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.utils import shuffle
from sklearn.utils.validation import check_array 
from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error, confusion_matrix, classification_report
from sklearn.svm import LinearSVR, SVC, SVR
from sklearn.tree import DecisionTreeRegressor, DecisionTreeClassifier
from sklearn.ensemble import RandomForestRegressor,RandomForestClassifier,ExtraTreesRegressor,GradientBoostingRegressor,AdaBoostRegressor,BaggingRegressor<jupyter_output><empty_output><jupyter_text>Steps to be Executed<jupyter_code>#1st Step

"""
No NAN values
All features should be numerical (can use label encoding or pd.dummies to convert categorical data into numerical data)
use MinMaxScaler or StandardScaler (to bring all features to the same scale)
"""
# sc = StandardScaler()
# X_train = sc.fit_transform(X_train)
# X_test = sc.transform(X_test)
#2nd Step

"""
Perform correlation analysis (to find similar features, then remove similar features)
"""
# prediction_df=matches[["team1","team2","team1_toss_win","team1_bat","team1_win","venue"]]
# #finding the higly correlated features
# correlated_features = set()
# correlation_matrix = prediction_df.drop('team1_win', axis=1).corr()
# for i in range(len(correlation_matrix.columns)):
#     for j in range(i):
#         if abs(correlation_matrix.iloc[i, j]) > 0.9:
#             column = correlation_matrix.columns[i]
#             correlated_features.add(column)
# prediction_df.drop(columns=correlated_features)

"""
make at least 2 new features which would be useful to predict your target
https://colab.research.google.com/drive/1dnT8wZo3-SNwUbvuwjGzBz4amuUteAqg?usp=sharing#scrollTo=qv98PJ5UMv9I
"""
#3rd Step

"""
Use at least three different ML models for each task
For classification tasks: RF, Logit, DTC, XGB, SVM (https://towardsdatascience.com/predicting-ipl-match-winner-fc9e89f583ce)
For Regression tasks: Linear Reg, RF, SVR
Compare the metrics for all the models in a pandas dataframe
"""
#4th Step

# def custom_accuracy2(y_test,y_pred,thresold):
#     right = 0
#     l = len(y_pred)
#     for i in range(0,l):
#         if(abs(y_pred[i]-y_test[i]) <= thresold):
#             right += 1
#     return ((right/l)*100)<jupyter_output><empty_output><jupyter_text>Classification Task  Data Cleaning<jupyter_code>matches_data = pd.read_csv('matches.csv')
null_city_list = list(matches_data['city'].isnull())

#imputing the values in column city based on venue
matches = matches_data.copy()
conditions = [matches["venue"] == "Rajiv Gandhi International Stadium, Uppal",matches["venue"] == "Maharashtra Cricket Association Stadium",
              matches["venue"] == "Saurashtra Cricket Association Stadium", matches["venue"] == "Holkar Cricket Stadium",
              matches["venue"] == "M Chinnaswamy Stadium",matches["venue"] == "Wankhede Stadium",
              matches["venue"] == "Eden Gardens",matches["venue"] == "Feroz Shah Kotla",
              matches["venue"] == "Punjab Cricket Association IS Bindra Stadium, Mohali",matches["venue"] == "Green Park",
              matches["venue"] == "Punjab Cricket Association Stadium, Mohali",matches["venue"] == "Dr DY Patil Sports Academy",
              matches["venue"] == "Sawai Mansingh Stadium", matches["venue"] == "MA Chidambaram Stadium, Chepauk", 
              matches["venue"] == "Newlands", matches["venue"] == "St George's Park" , 
              matches["venue"] == "Kingsmead", matches["venue"] == "SuperSport Park",
              matches["venue"] == "Buffalo Park", matches["venue"] == "New Wanderers Stadium",
              matches["venue"] == "De Beers Diamond Oval", matches["venue"] == "OUTsurance Oval", 
              matches["venue"] == "Brabourne Stadium",matches["venue"] == "Sardar Patel Stadium", 
              matches["venue"] == "Barabati Stadium", matches["venue"] == "Vidarbha Cricket Association Stadium, Jamtha",
              matches["venue"] == "Himachal Pradesh Cricket Association Stadium",matches["venue"] == "Nehru Stadium",
              matches["venue"] == "Dr. <NAME> Reddy ACA-VDCA Cricket Stadium",matches["venue"] == "Subrata Roy Sahara Stadium",
              matches["venue"] == "Shaheed Veer Narayan Singh International Stadium",matches["venue"] == "JSCA International Stadium Complex",
              matches["venue"] == "Sheikh Zayed Stadium",matches["venue"] == "Sharjah Cricket Stadium",
              matches["venue"] == "Dubai International Cricket Stadium",matches["venue"] == "M. A. Chidambaram Stadium",
              matches["venue"] == "Feroz Shah Kotla Ground",matches["venue"] == "M. Chinnaswamy Stadium",
              matches["venue"] == "Rajiv Gandhi Intl. Cricket Stadium" ,matches["venue"] == "IS Bindra Stadium",matches["venue"] == "ACA-VDCA Stadium"]
values = ['Hyderabad', 'Mumbai', 'Rajkot',"Indore","Bengaluru","Mumbai","Kolkata","Delhi","Mohali","Kanpur","Mohali","Pune","Jaipur","Chennai","Cape Town","Port Elizabeth","Durban",
          "Centurion",'Eastern Cape','Johannesburg','Northern Cape','Bloemfontein','Mumbai','Ahmedabad','Cuttack','Jamtha','Dharamshala','Chennai','Visakhapatnam','Pune','Raipur','Ranchi',
          'Abu Dhabi','Sharjah','Dubai','Chennai','Delhi','Bengaluru','Hyderabad','Mohali','Visakhapatnam']
matches['city'] = np.where(matches['city'].isnull(),
                              np.select(conditions, values),
                              matches['city'])
matches_data = matches.copy()

#Clearing Ambiguity regarding same team name in different fasion
matches_data['team1'] = matches_data['team1'].replace("Rising Pune Supergiant","Rising Pune Supergiants")
matches_data['team2'] = matches_data['team2'].replace("Rising Pune Supergiant","Rising Pune Supergiants")
matches_data['winner'] = matches_data['winner'].replace("Rising Pune Supergiant","Rising Pune Supergiants")
matches_data['toss_winner'] = matches_data['toss_winner'].replace("Rising Pune Supergiant","Rising Pune Supergiants")

#Removing Null values
matches_data = matches_data[matches_data['winner'].notna()]

#Encoding
from sklearn import preprocessing
encoder = preprocessing.LabelEncoder()
matches_data['team1'] = encoder.fit_transform(matches_data['team1'])
matches_data['team2'] = encoder.fit_transform(matches_data['team2'])
matches_data['winner'] = encoder.fit_transform(matches_data['winner'].astype(str))
matches_data['toss_winner'] = encoder.fit_transform(matches_data['toss_winner'])
matches_data['venue'] = encoder.fit_transform(matches_data['venue'])


#Feature Engineering
matches_data.loc[matches_data['winner']==matches_data['team1'], 'team1_win']=1    #"team1_win"
matches_data.loc[matches_data['winner']!=matches_data['team1'], 'team1_win']=0

matches_data.loc[matches_data["toss_winner"]==matches_data["team1"],"team1_toss_win"]=1   #"team1_toss_win" 
matches_data.loc[matches_data["toss_winner"]!=matches_data["team1"],"team1_toss_win"]=0

matches_data["team1_bat"]=0     #"team1_bat"
matches_data.loc[((matches_data["team1_toss_win"]==1) & (matches_data["toss_decision"]=="bat")) | ((matches_data["team1_toss_win"]==0) & (matches_data["toss_decision"]=="field")) ,"team1_bat"]=1

#Removing unnecessary columns
sign_matches = matches_data.drop(columns=['umpire1', 'umpire2', 'umpire3'])

#Copying Dataframe to matches variable
matches = sign_matches.copy()<jupyter_output><empty_output><jupyter_text>Feature selection<jupyter_code>matches.head()
matches = matches[['id', 'season', 'team1', 'team2', 'winner', 'team1_win', 'team1_toss_win', 'team1_bat', 'venue', 'win_by_runs', 'win_by_wickets']]
matches.head()
matches['team1_bat'].unique()
#Winning stats of teams bat/field first by venues
# venue_toss_decision_result=matches[["team1_toss_win","team1_bat","team1_win","venue"]]
# venue_toss_decision_result["decision"]=np.where((venue_toss_decision_result.team1_toss_win == venue_toss_decision_result.team1_win) & (venue_toss_decision_result.team1_bat == 0),"field_won","bat_won")
# venue_result=venue_toss_decision_result.groupby(["venue"]).decision.value_counts().reset_index(name="count")
# #Visualization
# sns.set(rc={'figure.figsize':(20,10)})
# plot = sns.barplot(x="venue", y="count", hue="decision", data=venue_result)
# plot.set_title('Teams bat/field first results on venues')
# plot.set_xticklabels(venue_result['venue'].unique(),rotation=90)
# plt.show()
#Correlation Analysis (to find similar features, then remove similar features)

prediction_df=matches[["team1","team2","team1_toss_win","team1_bat","team1_win","venue"]]
correlated_features = set()
correlation_matrix = prediction_df.drop('team1_win', axis=1).corr()
print(correlation_matrix)
for i in range(len(correlation_matrix.columns)):
    for j in range(i):
        if abs(correlation_matrix.iloc[i, j]) > 0.9:
            column = correlation_matrix.columns[i]
            correlated_features.add(column)
prediction_df.drop(columns=correlated_features)<jupyter_output>team1     team2  team1_toss_win  team1_bat     venue
team1           1.000000 -0.108116       -0.116832        NaN  0.108240
team2          -0.108116  1.000000       -0.008782        NaN  0.084187
team1_toss_win -0.116832 -0.008782        1.000000        NaN  0.050049
team1_bat            NaN       NaN             NaN        NaN       NaN
venue           0.108240  0.084187        0.050049        NaN  1.000000<jupyter_text>Train-Test split<jupyter_code>X = prediction_df.drop('team1_win', axis=1)
y = prediction_df['team1_win'].astype(int)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
#StandardScaler (to bring all features to the same scale)
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)<jupyter_output><empty_output><jupyter_text>ML Models  Logistic Regression<jupyter_code>logreg = LogisticRegression()
logreg.fit(X_train, y_train)
y_pred = logreg.predict(X_test)
print(confusion_matrix(y_test,y_pred))
print(classification_report(y_test,y_pred))
print('Accuracy of logistic regression classifier on test set: {:.4f}'.format(logreg.score(X_test, y_test)))<jupyter_output>[[76  0]
 [75  0]]
              precision    recall  f1-score   support

           0       0.50      1.00      0.67        76
           1       0.00      0.00      0.00        75

    accuracy                           0.50       151
   macro avg       0.25      0.50      0.33       151
weighted avg       0.25      0.50      0.34       151

Accuracy of logistic regression classifier on test set: 0.5033<jupyter_text>SVM<jupyter_code>svm = SVC()
svm.fit(X_train,y_train)
svm.score(X_test,y_test)
y_pred = svm.predict(X_test)
print(confusion_matrix(y_test,y_pred))
print(classification_report(y_test,y_pred))
print('Accuracy of SVM classifier on test set: {:.4f}'.format(svm.score(X_test, y_test)))<jupyter_output>[[67  9]
 [63 12]]
              precision    recall  f1-score   support

           0       0.52      0.88      0.65        76
           1       0.57      0.16      0.25        75

    accuracy                           0.52       151
   macro avg       0.54      0.52      0.45       151
weighted avg       0.54      0.52      0.45       151

Accuracy of SVM classifier on test set: 0.5232<jupyter_text>Decision Tree Classifier<jupyter_code>dtree=DecisionTreeClassifier()
dtree.fit(X_train,y_train)
dtree.score(X_test,y_test)
y_pred = dtree.predict(X_test)
print(confusion_matrix(y_test,y_pred))
print(classification_report(y_test,y_pred))
print('Accuracy of decision tree classifier on test set: {:.4f}'.format(dtree.score(X_test, y_test)))<jupyter_output>[[51 25]
 [44 31]]
              precision    recall  f1-score   support

           0       0.54      0.67      0.60        76
           1       0.55      0.41      0.47        75

    accuracy                           0.54       151
   macro avg       0.55      0.54      0.53       151
weighted avg       0.55      0.54      0.54       151

Accuracy of decision tree classifier on test set: 0.5430<jupyter_text>Random Forest Classifier<jupyter_code>randomForest= RandomForestClassifier(n_estimators=100)
randomForest.fit(X_train,y_train)
randomForest.score(X_test,y_test)
y_pred = randomForest.predict(X_test)
print("Confusion matrix\n",confusion_matrix(y_test,y_pred))
print(classification_report(y_test,y_pred))
print('Accuracy of random forest classifier on test set: {:.4f}'.format(randomForest.score(X_test, y_test)))<jupyter_output>Confusion matrix
 [[52 24]
 [45 30]]
              precision    recall  f1-score   support

           0       0.54      0.68      0.60        76
           1       0.56      0.40      0.47        75

    accuracy                           0.54       151
   macro avg       0.55      0.54      0.53       151
weighted avg       0.55      0.54      0.53       151

Accuracy of random forest classifier on test set: 0.5430<jupyter_text>Conclusion<jupyter_code>df = [['Logistic Regression', logreg.score(X_test, y_test)], 
      ['SVM', svm.score(X_test, y_test)], 
      ['Decision Tree Classifier', dtree.score(X_test, y_test)], 
      ['Random Forest Classifier', randomForest.score(X_test, y_test)]]
metric_comparison = pd.DataFrame(df, columns=['model', 'f1_score'])
metric_comparison<jupyter_output><empty_output><jupyter_text>So accuracy of  **Decisoin Tree** and **Random Forest** are nearly equal, so compairing as per confusion matrix, best suitable model for this task is ***Random Forest Classifier***<jupyter_code><jupyter_output><empty_output><jupyter_text>Regression Task  Data Collection<jupyter_code>balls = pd.read_csv('IPL Ball-by-Ball 2008-2020.csv')
print(balls.shape)
balls.head()
matches = pd.read_csv('IPL Matches 2008-2020.csv')
print(matches.shape)
matches.head()
ipl_data = pd.merge(left=matches, right=balls, on='id')
print(ipl_data.shape)
ipl_data.head()<jupyter_output>(193468, 34)<jupyter_text>Helper Functions<jupyter_code>def make_count_df(sign_matches, target_col, col1, col2):
    team_win_ser = sign_matches[target_col].value_counts()
    team_win_df = pd.DataFrame(columns=[col1, col2])
    for items in team_win_ser.iteritems():
        temp_df = pd.DataFrame({
            col1:[items[0]],
            col2:[items[1]]
        })
        team_win_df = team_win_df.append(temp_df, ignore_index=True) 

    return team_win_df<jupyter_output><empty_output><jupyter_text>Data Preprocessing<jupyter_code>ipl_data['year'] = pd.DatetimeIndex(pd.to_datetime(ipl_data['date'])).year
make_count_df(ipl_data, 'team1', 'team', 'No. of appearance in df')<jupyter_output><empty_output><jupyter_text>Modifying Data based on historical information1) On December 5th 2018, the team of **Delhi Daredevils** got its name changed to **Delhi Capitals** 2) **Pune Warriors India** and **Rising Pune Supergiant** were the two teams that represented the city in **different years** 3) The owners changed the team name **Rising Pune Supergiants** to **Rising Pune Supergiant** on 26 March 2017<jupyter_code>ipl_data = ipl_data.replace(['Rising Pune Supergiants','Rising Pune Supergiant', 'Delhi Daredevils'],['Pune Warriors','Pune Warriors', 'Delhi Capitals'])
make_count_df(ipl_data, 'team1', 'team', 'No. of appearance in df')<jupyter_output><empty_output><jupyter_text>Removing Null values<jupyter_code>ipl_data.isnull().sum()
drop_columns = ['city', 'result_margin', 'method', 'dismissal_kind', 'player_dismissed', 'fielder', 'extras_type', 'bowling_team']
ipl_data.drop(drop_columns,axis=1, inplace=True)
ipl_data = ipl_data[ipl_data['winner'].notna()]
ipl_data.isnull().sum()<jupyter_output><empty_output><jupyter_text>Feature Engineering<jupyter_code>ipl_data['inning'] = ipl_data['id'].astype(str)+(ipl_data['batting_team']).astype(str)
ipl_data.head()
unique_inning_list = ipl_data['inning'].unique()
ipl_data.loc[(ipl_data['over'] == 10) & (ipl_data['ball'] == 6) & (ipl_data['inning'] == unique_inning_list[0])]
df = ipl_data.copy()
df = df.groupby(by=['inning']).sum()['total_runs'].reset_index()
df.head()
df2 = pd.merge(left=df, right=ipl_data, on='inning', how='right')
print(df2.shape, ipl_data.shape)
df2.head()
df3 = pd.DataFrame()
for inn in unique_inning_list:
    one_inning = df2.loc[df2['inning']==inn]
    one_inning = one_inning.sort_values(['over', 'ball'], ascending=[True, True])
    one_inning['cumsum_runs'] = one_inning['total_runs_y'].cumsum()
    one_inning['cumsum_wickets'] = one_inning['is_wicket'].cumsum()
    df3 = pd.concat([df3, one_inning])
print(df2.shape, df3.shape)
df3.head()
df3['over'] = df3['over']+ (df3['ball'])/10
df3 = df3.drop(['ball'], axis=1)
ipl_data = df3.copy()
ipl_data.head()<jupyter_output><empty_output><jupyter_text>Encoding<jupyter_code>matches_data = ipl_data.copy()
encoder = preprocessing.LabelEncoder()
matches_data['team1'] = encoder.fit_transform(matches_data['team1'])
matches_data['team2'] = encoder.fit_transform(matches_data['team2'])
matches_data['winner'] = encoder.fit_transform(matches_data['winner'].astype(str))
matches_data['toss_winner'] = encoder.fit_transform(matches_data['toss_winner'])
matches_data['venue'] = encoder.fit_transform(matches_data['venue'])
matches_data['batting_team'] = encoder.fit_transform(matches_data['batting_team'])
matches_data['player_of_match'] = encoder.fit_transform(matches_data['player_of_match'])

matches_data.loc[matches_data['winner']==matches_data['team1'], 'team1_win']=1    #"team1_win"
matches_data.loc[matches_data['winner']!=matches_data['team1'], 'team1_win']=0
matches_data.loc[matches_data["toss_winner"]==matches_data["team1"],"team1_toss_win"]=1   #"team1_toss_win" 
matches_data.loc[matches_data["toss_winner"]!=matches_data["team1"],"team1_toss_win"]=0
matches_data["team1_bat"]=0     #"team1_bat"
matches_data.loc[((matches_data["team1_toss_win"]==1) & (matches_data["toss_decision"]=="bat")) | ((matches_data["team1_toss_win"]==0) & (matches_data["toss_decision"]=="field")) ,"team1_bat"]=1

ipl_data = matches_data.copy()
matches_data.head()<jupyter_output><empty_output><jupyter_text>Removing Unnecessary Features<jupyter_code>useful_columns = ['inning', 'id', 'player_of_match', 'player_of_match', 'venue', 'team1', 'team2', 'over', 'batsman_runs', 'year', 'cumsum_runs', 'cumsum_wickets', 'team1_win', 'team1_toss_win', 'team1_bat', 'total_runs_x']
ipl_data = ipl_data[useful_columns]
ipl_data<jupyter_output><empty_output><jupyter_text>Train Test Split<jupyter_code>ipl_data = pd.read_csv('ipl_data.csv', index_col=0)
pred_features = ['cumsum_runs', 'cumsum_wickets', 'over', 'venue', 'team1', 'team2', 'team1_bat']
#venue,team1,team2,over,batsman_runs,team1_toss_win,team1_bat
X = ipl_data[pred_features]
y = ipl_data['total_runs_x'].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
scaler = MinMaxScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)<jupyter_output><empty_output><jupyter_text>Custom Accuracy function<jupyter_code>def custom_accuracy(y_test,y_pred,thresold):
    right = 0
    l = len(y_pred)
    for i in range(0,l):
        if(abs(y_pred[i]-y_test[i]) <= thresold):
            right += 1
    return ((right/l)*100)<jupyter_output><empty_output><jupyter_text>Models  Linear Regression<jupyter_code>lm = LinearRegression()
lm.fit(X_train, y_train)
pred = lm.predict(X_test)
lm_metric = [mean_squared_error(y_test, pred), custom_accuracy(y_test, pred, 10)]
print("Custom accuracy: {:.2f} %".format(lm_metric[1]))<jupyter_output>Custom accuracy: 41.73 %<jupyter_text>Random Forest<jupyter_code>rf = RandomForestRegressor()
rf.fit(X_train, y_train)
pred = rf.predict(X_test)
rf_metric = [mean_squared_error(y_test, pred), custom_accuracy(y_test, pred, 10)]
print("Custom accuracy: {:.2f} %".format(rf_metric[1]))<jupyter_output>Custom accuracy: 76.19 %<jupyter_text>Linear SVR<jupyter_code>svr = LinearSVR()
svr.fit(X_train, y_train)
pred = svr.predict(X_test)
svr_metric = [mean_squared_error(y_test, pred), custom_accuracy(y_test, pred, 10)]
print("Custom accuracy: {:.2f} %".format(svr_metric[1]))<jupyter_output>Custom accuracy: 42.08 %<jupyter_text>Conclusion<jupyter_code>df = [ ['Linear Regression', lm_metric[0], lm_metric[1]], ['Random Forest', rf_metric[0], rf_metric[1]], ['Linear SVR', svr_metric[0], svr_metric[1]] ]
pd.DataFrame(df, columns=['models','mean squared error', 'custom accuracy'])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14191928943811546, 'fraction_numerical': 0.031424985518439856, 'mean_word_length': 5.184179104477612, 'pattern_counts': {'":': 0, '<': 95, '<?xml version=': 0, '>': 95, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 17, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '25', 'dir': 'jupyter-structured-clean-dedup', 'id': '452502', 'license': 'MIT', 'n_tokens_mistral': 7631, 'n_tokens_neox': 7124, 'n_words': 1327, 'path': 'WiDS_IPL_ML_Task2.ipynb', 'repo_name': 'SahilKhan101/IPL-Data-Analysis', 'size': '20726'}