<jupyter_start><jupyter_text>My Data Prework<jupyter_code>#Initial Imports
import pandas as pd
from google.colab import files
import numpy as np
import matplotlib.pyplot as plt
!pip install category_encoders==2.*
!pip install eli5
!pip install eli5
!pip install pdpbox
!pip install shap
uploaded = files.upload()
df = pd.read_csv('2018_Central_Park_Squirrel_Census_-_Squirrel_Data.csv')
#Replace all whitespace with underscore
df.columns = df.columns.str.replace(' ', '_')
df.columns = df.columns.str.replace('X', 'Longitude')
df.columns = df.columns.str.replace('Y', 'Latitude')
df.columns<jupyter_output><empty_output><jupyter_text>Define Target<jupyter_code>#Brief Clean to Define Target
indexNames = df[ (df['Runs_from'] == True) & (df['Indifferent'] == True) ].index
df.drop(indexNames , inplace=True)
#This is my target
df['Target'] = df['Approaches'] | df['Indifferent'] == True
df['Target'].value_counts()<jupyter_output><empty_output><jupyter_text>What Accuracy can I get just by guessing?<jupyter_code>print(df['Target'].value_counts(max))
print(f'If I only guessed Majority Class I would be \nright only 52.9% of the time')<jupyter_output>True     0.528586
False    0.471414
Name: Target, dtype: float64
If I only guessed Majority Class I would be 
right only 52.9% of the time<jupyter_text>Train Test Split<jupyter_code>#Train Test Split Classifier
from sklearn.model_selection import train_test_split
#The actual Split
train, test = train_test_split(df, 
                               train_size=0.80,
                               test_size=0.20,
                               random_state=42)

#Train/Val/Test Split
train, val = train_test_split(train, 
                               train_size=0.80,
                               test_size=0.20,
                               random_state=42)

train.shape,val.shape, test.shape<jupyter_output><empty_output><jupyter_text>Models Linear Model<jupyter_code>#Model Imports
import category_encoders as ce
from sklearn.impute import SimpleImputer
from sklearn.pipeline import make_pipeline
from sklearn.linear_model import LogisticRegressionCV
from sklearn.preprocessing import StandardScaler
#Make X features Matrix and y vector 
columns1 = ['Shift', 'Foraging', 'Longitude', 'Latitude', 'Primary_Fur_Color', 'Eating', 'Highlight_Fur_Color']
target = 'Target'
X_train = train[columns1]
y_train = train[target]
X_val = val[columns1]
y_val = val[target]
X_test = test
#One-Hot Encoding everything
encoder = ce.OneHotEncoder(use_cat_names=True)
X_train_encoded = encoder.fit_transform(X_train)
X_val_encoded = encoder.transform(X_val)
#Imputing missing values
imputer = SimpleImputer()
X_train_imputed = imputer.fit_transform(X_train_encoded)
X_val_imputed = imputer.transform(X_val_encoded)
#Scaling everything
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train_imputed)
X_val_scaled = scaler.transform(X_val_imputed)
#Fitting Model and getting score
model = LogisticRegressionCV(cv=5, n_jobs=-1, random_state=42)
model.fit(X_train_scaled, y_train)
print('Validation Accuracy', model.score(X_val_scaled, y_val))<jupyter_output>Validation Accuracy 0.6221294363256785<jupyter_text>Classification Model<jupyter_code>#Model Imports
import category_encoders as ce
from sklearn.impute import SimpleImputer
from sklearn.pipeline import make_pipeline
from sklearn.ensemble import RandomForestClassifier
#Make X features Matrix and y vector 
columns_to_drop = ['Unique_Squirrel_ID', 'Approaches', 'Indifferent', 'Runs_from', 'Target']
target = 'Target'
X_train = train.drop(columns=columns_to_drop)
y_train = train[target]
X_val = val.drop(columns=columns_to_drop)
y_val = val[target]
X_test = test
#Make Pipeline
pipeline = make_pipeline(ce.OrdinalEncoder(), 
                         SimpleImputer(strategy='mean'), 
                         RandomForestClassifier(n_estimators=300, n_jobs=-1, random_state=27))
# Fit on train, score on val
pipeline.fit(X_train, y_train)
print('Validation Accuracy', pipeline.score(X_val, y_val))<jupyter_output>Validation Accuracy 0.6722338204592901<jupyter_text>Feature Permutations<jupyter_code>#Imports
import eli5
from eli5.sklearn import PermutationImportance
#Making transformers
transformers = make_pipeline(
    ce.OrdinalEncoder(), 
    SimpleImputer(strategy='mean')
)
#Fitting transformers to X_train and X_val
X_train_transformed = transformers.fit_transform(X_train)
X_val_transformed = transformers.transform(X_val)

model = RandomForestClassifier(n_estimators=300, random_state=27, n_jobs=-1)
model.fit(X_train_transformed, y_train)
#Calculate Permutatin Importances
permuter = PermutationImportance(
    model, 
    scoring='accuracy', 
    n_iter=5, 
    random_state=27
)

permuter.fit(X_val_transformed, y_val)
#Nice Display of Feature Permutations
feature_names = X_val.columns.tolist()
eli5.show_weights(
    permuter, 
    top=None,
    feature_names=feature_names
)<jupyter_output><empty_output><jupyter_text>The Model I will use for the test<jupyter_code>#Make X features Matrix and y vector 
columns = ['Shift', 'Foraging', 'Longitude', 'Latitude', 'Primary_Fur_Color', 'Eating', 'Highlight_Fur_Color']
target = 'Target'
X_train = train[columns]
y_train = train[target]
X_val = val[columns]
y_val = val[target]
X_test = test[columns]
y_test = test[target]
#Make Pipeline
new_pipeline = make_pipeline(ce.OrdinalEncoder(), 
                         SimpleImputer(strategy='mean'), 
                         RandomForestClassifier(n_estimators=300, n_jobs=-1, random_state=27))
# Fit on train, score on val
new_pipeline.fit(X_train, y_train)
print('Validation Accuracy', new_pipeline.score(X_val, y_val))
# Fit on train, score on test
new_pipeline.fit(X_train, y_train)
print('Validation Accuracy', new_pipeline.score(X_test, y_test))<jupyter_output>Validation Accuracy 0.6043405676126878<jupyter_text>Feature paramaters<jupyter_code>df['X'].describe()
df['Y'].describe()
df['Primary_Fur_Color'].value_counts()
df['Highlight_Fur_Color'].value_counts()
df['Age'].value_counts()<jupyter_output><empty_output><jupyter_text>Practice Prediction<jupyter_code>def predict(Shift, Foraging, X, Y, Primary_Fur_Color, Eating, Highlight_Fur_Color):
    df = pd.DataFrame(
        columns=['Shift', 'Foraging', 'X', 'Y', 'Primary_Fur_Color', 'Eating', 'Highlight_Fur_Color'], 
        data=[[Shift, Foraging, X, Y, Primary_Fur_Color, Eating, Highlight_Fur_Color]]
    )
    y_pred = new_pipeline.predict(df)[0]
    return f'{y_pred}'
predict('AM', True, 40.78, -73.96, 'Gray', True, 'Black')<jupyter_output><empty_output><jupyter_text>Visuals   Partial Dependence Plots<jupyter_code>#Imports
import matplotlib.pyplot as plt
from pdpbox.pdp import pdp_isolate, pdp_plot
#So the Graphs aren't fuzzy 
plt.rcParams['figure.dpi'] = 72
#First Isolated Feature 

feature = 'Longitude'

isolated = pdp_isolate(
    model=new_pipeline, 
    dataset=X_val, 
    model_features=X_val.columns, 
    feature=feature
)
#PDP plot for Longitude
ax1 = pdp_plot(isolated, feature_name=feature);
#Second Isolated Feature
feature = 'Latitude'

isolated = pdp_isolate(
    model=new_pipeline, 
    dataset=X_val, 
    model_features=X_val.columns, 
    feature=feature
)
#PDP plot for Latitude
pdp_plot(isolated, feature_name=feature);<jupyter_output><empty_output><jupyter_text>Double Partial Dependence Plot<jupyter_code>#Imports 
from pdpbox.pdp import pdp_interact, pdp_interact_plot
#Latitude and Longitude Comparison
features = ['Longitude', 'Latitude']

interaction = pdp_interact(
    model=new_pipeline,
    dataset=X_val, 
    model_features=X_val.columns, 
    features=features
)
#The Actual Plot
pdp_interact_plot(interaction, plot_type='grid', 
                  feature_names=features);<jupyter_output><empty_output><jupyter_text>Confusion Matrix<jupyter_code>y_pred = new_pipeline.predict(X_test)
#SKLearn's function
from sklearn.metrics import confusion_matrix
from sklearn.utils.multiclass import unique_labels
import seaborn as sns
confusion_matrix(y_test, y_pred)
#Reader friendly
def plot_confusion_matrix(y_true, y_pred):
    labels = unique_labels(y_true)
    columns = [f'Predicted {label}' for label in labels]
    index = [f'Actual {label}' for label in labels]
    table = pd.DataFrame(confusion_matrix(y_true, y_pred), 
                         columns=columns, index=index)
    return sns.heatmap(table, annot=True, fmt='d', cmap='viridis')

plot_confusion_matrix(y_test, y_pred);<jupyter_output><empty_output><jupyter_text>Pickle the Pipeline<jupyter_code>#The Pickle 
from joblib import dump
dump(new_pipeline, 'pipeline.joblib', compress=True)
#Download the file
files.download('pipeline.joblib')
#What version did I use?
import joblib
import sklearn
import category_encoders as ce
print(f'joblib=={joblib.__version__}')
print(f'scikit-learn=={sklearn.__version__}')
print(f'category_encoders=={ce.__version__}')<jupyter_output>joblib==0.14.1
scikit-learn==0.22.1
category_encoders==2.1.0
{'fraction_non_alphanumeric': 0.1062542030934768, 'fraction_numerical': 0.016812373907195696, 'mean_word_length': 5.634200743494424, 'pattern_counts': {'":': 0, '<': 52, '<?xml version=': 0, '>': 52, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '88550', 'license': 'MIT', 'n_tokens_mistral': 3231, 'n_tokens_neox': 3072, 'n_words': 631, 'path': 'notebooks/Unit_2_Build.ipynb', 'repo_name': 'ethanmjansen/Central_Park_Squirrels', 'size': '8922'}