<jupyter_start><jupyter_text>Data Science Unit 4 Sprint Challenge 1 — Tree Ensembles  Chicago Food InspectionsFor this Sprint Challenge, you'll use a dataset with information from inspections of restaurants and other food establishments in Chicago from January 2010 to March 2019. [See this PDF](https://data.cityofchicago.org/api/assets/BAD5301B-681A-4202-9D25-51B2CAE672FF) for descriptions of the data elements included in this dataset.According to [Chicago Department of Public Health — Food Protection Services](https://www.chicago.gov/city/en/depts/cdph/provdrs/healthy_restaurants/svcs/food-protection-services.html), "Chicago is home to 16,000 food establishments like restaurants, grocery stores, bakeries, wholesalers, lunchrooms, mobile food vendors and more. Our business is food safety and sanitation with one goal, to prevent the spread of food-borne disease. We do this by inspecting food businesses, responding to complaints and food recalls."   Your challenge: Predict whether inspections failedThe target is the `Fail` column.- When the food establishment failed the inspection, the target is `1`.- When the establishment passed, the target is `0`.  Run this cell to load the data:<jupyter_code>import pandas as pd

train_url = 'https://drive.google.com/uc?export=download&id=13_tP9JpLcZHSPVpWcua4t2rY44K_s4H5'
test_url  = 'https://drive.google.com/uc?export=download&id=1GkDHjsiGrzOXoF_xcYjdzBTSjOIi3g5a'

train = pd.read_csv(train_url)
test  = pd.read_csv(test_url)

assert train.shape == (51916, 17)
assert test.shape  == (17306, 17)<jupyter_output><empty_output><jupyter_text>Part 1: PreprocessingYou may choose which features you want to use, and whether/how you will preprocess them. If you use categorical features, you may use any tools and techniques for encoding. (Pandas, category_encoders, sklearn.preprocessing, or any other library.)_To earn a score of 3 for this part, find and explain leakage. The dataset has a feature that will give you an ROC AUC score > 0.90 if you process and use the feature. Find the leakage and explain why the feature shouldn't be used in a real-world model to predict the results of future inspections._ Part 2: ModelingFit a Random Forest or Gradient Boosting model with the train set. (You may use scikit-learn, xgboost, or any other library.) Use cross-validation to estimate an ROC AUC validation score.Use your model to predict probabilities for the test set. Get an ROC AUC test score >= 0.60._To earn a score of 3 for this part, get an ROC AUC test score >= 0.70 (without using the feature with leakage)._ Part 3: VisualizationMake one visualization for model interpretation. (You may use any libraries.) Choose one of these types:- Feature Importances- Permutation Importances- Partial Dependence Plot- Shapley Values_To earn a score of 3 for this part, make at least two of these visualization types._<jupyter_code>!pip install category_encoders
!pip install eli5
# imports
import numpy as np
from sklearn.ensemble import GradientBoostingClassifier
from eli5.sklearn import PermutationImportance
import eli5
from sklearn.model_selection import cross_val_score
from sklearn.metrics import roc_auc_score
from sklearn.pipeline import make_pipeline
import category_encoders as ce
import matplotlib.pyplot as plt<jupyter_output><empty_output><jupyter_text>Part 1: Preprocessing<jupyter_code>train.head(3)
train.shape
train.nunique()
train.dtypes
test.isnull().sum()
# wrangle data
def wrangle(X):
  X = X.copy()
  
  # Change NaN to 'Unknown' for Facility Type
  X['Facility Type'] = X['Facility Type'].fillna('Unknown')
  
  # Fill NaN License # with -1
  X['License #'] = X['License #'].fillna(-1)
  
  # Fill NaN Risk with 'Unknown'
  X['Risk'] = X['Risk'].fillna('Unknown')
  
  # Fill NaN lat and long with mean
  X['Latitude'] = X['Latitude'].fillna(X['Latitude'].mean())
  X['Longitude'] = X['Longitude'].fillna(X['Longitude'].mean())
  
  # Fill NaN Inspection Type with 'Unknown'
  X['Inspection Type'] = X['Inspection Type'].fillna('Unknown')
  
  # Fill NaN City with 'Unknown'
  X['City'] = X['City'].fillna('Unknown')
  
  # Fill NaN Zip with -1
  X['Zip'] = X['Zip'].fillna(-1)
  
  # Drop leaky column
  X = X.drop(columns='Violations')
  
  
  # Drop high cardinality and unnecessary columns
  X = X.drop(columns=['Inspection ID', 'AKA Name', 'Address', 'State', 
                      'Inspection Date', 'Location'])
  
  return X
# apply wrangle function
train = wrangle(train)
test = wrangle(test)
# The data leakage was coming from the Violations feature. This column heavily
# indicates whether or not the business failed the inspection. Because the goal is to
# predict pass/fail, we wouldn't know what the violations are at the time of prediction.<jupyter_output><empty_output><jupyter_text>Part 2: Modeling<jupyter_code># See majority class
train['Fail'].value_counts(normalize=True)
# Split into independent and dependent variables
X_train = train.drop(columns='Fail')
y_train = train['Fail']

X_test = test.drop(columns='Fail')
y_test = test['Fail']
# Make pipeline and see crossval scores

pipe = make_pipeline(
    ce.OrdinalEncoder(),
    GradientBoostingClassifier(n_estimators=400)
)

cross_val_score(pipe, X_train, y_train, cv=5, scoring='roc_auc')
# Tune model
pipe2 = make_pipeline(
    ce.OrdinalEncoder(),
    GradientBoostingClassifier(n_estimators=400, max_depth=4)
)
# Prediction with test data
pipe2.fit(X_train, y_train)
y_pred_proba = pipe2.predict_proba(X_test)[:, 1]
print('Test ROC AUC:', roc_auc_score(y_test, y_pred_proba))<jupyter_output>Test ROC AUC: 0.7036300091999605<jupyter_text>Part 3: Visualization<jupyter_code># Feature Importances

def show_feature_importances(pipe, X, y, estimator_name='gradientboostingclassifier',
                             n=X_train.shape[1], figsize=(8, 8)):
  # Fit model
  pipe.fit(X, y)
  
  # Variable with feature importance from pipe
  importances = pd.Series(pipe.named_steps[estimator_name].feature_importances_, X.columns)
  
  # Sort importances
  sort = importances.sort_values(ascending=False)[:n]
  
  plt.figure(figsize=figsize)
  sort.sort_values().plot.barh(color='grey')
  
show_feature_importances(pipe, X_train, y_train)
# Permutation Importances

# Encode
encoder = ce.OrdinalEncoder()
X_train_transformed = encoder.fit_transform(X_train)

# Model
model = GradientBoostingClassifier(n_estimators=400)

# Fit model
model.fit(X_train_transformed, y_train)
# Create permuter with model
permuter = PermutationImportance(model, scoring='roc_auc', n_iter=1, cv='prefit')
# Fit permuter
permuter.fit(X_train_transformed, y_train)

# Show weights
eli5.show_weights(permuter, top=None, feature_names=X_train_transformed.columns.tolist())<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09545049063336307, 'fraction_numerical': 0.01873327386262266, 'mean_word_length': 5.275186567164179, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 23, 'https://': 4, 'lorem ipsum': 0, 'www.': 1, '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': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '529630', 'license': 'MIT', 'n_tokens_mistral': 2237, 'n_tokens_neox': 2076, 'n_words': 678, 'path': 'DS41SC.ipynb', 'repo_name': 'tesseract314/DS-Unit-4-Sprint-1-Tree-Ensembles', 'size': '6726'}