<jupyter_start><jupyter_text>Pitch Prediciton Model BuildingI'll use a logistic regression model to perform the actual pitch prediction.Thoughts:- Stratified test/train split- OvR multi-class method- Need to encode categorical variables- Feature scaling??- CV and GridSearch<jupyter_code>#Import packages

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
#Load data

kluber = pd.read_csv('kluber.csv')
kluber.head()<jupyter_output><empty_output><jupyter_text>Preparing the DataThere are a few data preparation steps required before training a model. 1. Decide what columns to use for initial model, remove the remainder2. Separate the dependent variable (pitch_type)3. Encode any categorical variables4. Split the data into testing and training sets5. Standardize dataFor my initial model, the predictor variables I'm going to use are:- Batter handedness: 'stand'- Men on base: 'on_1b', 'on_2b', 'on_3b'- Balls: 'b'- Strikes: 's'- Times-through-order: TTO- Previous pitch: 'prev_pitch'- Interactions between these variables<jupyter_code>#Remove unneccessary columns

cols_to_drop = ['pitcher_name','batter_name','p_throws','inning_side','count','x','y','type_confidence']
x = kluber.drop(cols_to_drop, axis = 1)
x.head()
#Split off pitch_type into separate dataframe

y = x['pitch_type']
x.drop(['pitch_type'], axis = 1, inplace = True)
x.head()<jupyter_output><empty_output><jupyter_text>Encode Categorical VariablesAll of my variables are categorical, even those with numeric values. I'll use pandas get_dummies function to perform one-hot encoding<jupyter_code>x = pd.get_dummies(x, columns = x.columns.tolist())
x.head()<jupyter_output><empty_output><jupyter_text>Split training and test set<jupyter_code>from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.33, random_state=1, stratify = y)<jupyter_output><empty_output><jupyter_text>Building the ModelFirst attempt: L2 regularized logistic regression with cross-validation using one-vs-rest, no interactions<jupyter_code>from sklearn.linear_model import LogisticRegressionCV

ovr = LogisticRegressionCV(cv = 10, max_iter = 10000)
ovr_fit = ovr.fit(x_train, y_train)
ovr_fit.score(x_test, y_test)
#Compute confusion matrix

pd.crosstab(y_test, ovr_fit.predict(x_test), rownames=['True'], colnames=['Predicted'])<jupyter_output><empty_output><jupyter_text>Let's see if multinomial does any better<jupyter_code>mn = LogisticRegressionCV(cv = 10, max_iter = 10000, multi_class = 'multinomial')
mn_fit = mn.fit(x_train, y_train)
mn_fit.score(x_test, y_test)
#Compute confusion matrix

pd.crosstab(y_test, mn_fit.predict(x_test), rownames=['True'], colnames=['Predicted'])<jupyter_output><empty_output><jupyter_text>Consider interaction terms!<jupyter_code>from sklearn.preprocessing import PolynomialFeatures

poly = PolynomialFeatures(interaction_only=True, include_bias = False)
x_train_poly = poly.fit_transform(x_train)
x_test_poly = poly.fit_transform(x_test)
#Re-try Logistic Regression with one-vs-rest

ovr_poly = LogisticRegressionCV(cv = 5, max_iter = 10000)
ovr_poly_fit = ovr_poly.fit(x_train_poly, y_train)
ovr_poly_fit.score(x_test_poly, y_test)
#Confusion Matrix

pd.crosstab(y_test, ovr_poly_fit.predict(x_test_poly), rownames=['True'], colnames=['Predicted'])
#Multinomial

mn_poly = LogisticRegressionCV(cv = 5, max_iter = 10000, multi_class = 'multinomial')
mn_poly_fit = mn_poly.fit(x_train_poly, y_train)
mn_poly_fit.score(x_test_poly, y_test)
pd.crosstab(y_test, mn_poly_fit.predict(x_test_poly), rownames=['True'], colnames=['Predicted'])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10609357997823722, 'fraction_numerical': 0.011153427638737758, 'mean_word_length': 7.860240963855421, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '155092', 'license': 'MIT', 'n_tokens_mistral': 1338, 'n_tokens_neox': 1265, 'n_words': 305, 'path': 'pitch_prediction/Pitch Prediction LogReg.ipynb', 'repo_name': 'EPripstein/baseball', 'size': '3676'}