<jupyter_start><jupyter_text>Pet Adaption prediction datasetReference - https://www.kaggle.com/c/petfinder-adoption-prediction/data AdoptionSpeedContestants are required to predict this value. The value is determined by how quickly, if at all, a pet is adopted. The values are determined in the following way:*  0 - Pet was adopted on the same day as it was listed.*  1 - Pet was adopted between 1 and 7 days (1st week) after being listed.*  2 - Pet was adopted between 8 and 30 days (1st month) after being listed.*  3 - Pet was adopted between 31 and 90 days (2nd & 3rd month) after being listed.*  4 - No adoption after 100 days of being listed. (There are no pets in this dataset that waited between 90 and 100 days).<jupyter_code>import numpy as np
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt<jupyter_output><empty_output><jupyter_text>Data Collection and Preparation<jupyter_code>!wget -q 'http://storage.googleapis.com/download.tensorflow.org/data/petfinder-mini.zip'
!unzip "petfinder-mini.zip"
#load the dataset
df = pd.read_csv("/content/petfinder-mini/petfinder-mini.csv")
df.shape
df.head()<jupyter_output><empty_output><jupyter_text>Creating a new target variable = "Adapted" representing whether the pet was adopted or not.for Adoptionspeed=0/1/2/3 = 1, else = 0<jupyter_code>df['Adopted'] = np.where(df['AdoptionSpeed']!=4,1,0)
df.head()
#check for missing values
df.isnull().sum()
#check duplicated rows
df.duplicated().sum()
#dropping duplicated rows
df.drop_duplicates(inplace=True)
# drop unwanted columns
df.drop(columns=['AdoptionSpeed','Description'],inplace=True)
# check for statistical description
df.describe()<jupyter_output><empty_output><jupyter_text>Splitting data into train, validation and test set<jupyter_code>from sklearn.model_selection import train_test_split
train,test = train_test_split(df,test_size=0.2,random_state=6)
train,val = train_test_split(train,test_size=0.2,random_state=6)

print(train.shape,test.shape,val.shape)<jupyter_output>(6614, 14) (2067, 14) (1654, 14)<jupyter_text>Creating a data pipelie using tf.data - creating tf.data.dataset<jupyter_code>def create_dataset(df,batch_size):
  df = df.copy()
  target = df.pop('Adopted')
  ds = tf.data.Dataset.from_tensor_slices((dict(df),target))
  ds = ds.batch(batch_size)
  ds = ds.prefetch(batch_size)
  return ds
train_ds = create_dataset(train,batch_size=10)
[(features,tar)] = train_ds.take(1)
features<jupyter_output><empty_output><jupyter_text>Normalization<jupyter_code>from tensorflow.keras.layers.experimental import preprocessing

def normalization_layer(name,dataset):
  # create a normalization layer
  normalizer = preprocessing.Normalization(axis=None)
  features_ds = dataset.map(lambda x,y:x[name])

  # get the normalization params
  normalizer.adapt(features_ds)
  return normalizer
age = features['Age']
layer = normalization_layer('Age',train_ds)
layer(age)<jupyter_output><empty_output><jupyter_text>Encoding of categorical attributes<jupyter_code>def encoder_layer(name,dataset,dtype="string",max_tokens=None):
  index = preprocessing.StringLookup(max_tokens=max_tokens)
  feature_ds = dataset.map(lambda x,y:x[name])

  # get the categorical columns
  index.adapt(feature_ds)
  # onehot encoding
  encoder = preprocessing.CategoryEncoding(num_tokens=index.vocabulary_size(),output_mode='one_hot')
  return lambda feature:encoder(index(feature))
  
breed1 = features['Type']
layer1 = encoder_layer('Type',train_ds,'string')
layer1(breed1)
batch_size=100
train_ds = create_dataset(train,batch_size=batch_size)
val_ds = create_dataset(val,batch_size=batch_size)
test_ds = create_dataset(test,batch_size=batch_size)
df.columns
df.head()
from tensorflow.keras import layers,models
# initializing a layer which will carry all preprocessing layer
input_layers = []
encoded_features = []

# passing numeric columns to the input layer
for col in ['Age','Fee','PhotoAmt']:
  numeric_col = layers.Input(shape=(1,),name=col)
  norm_layer = normalization_layer(col,train_ds)
  encoded_num_col = norm_layer(numeric_col)
  input_layers.append(numeric_col)
  encoded_features.append(encoded_num_col)
# passing categorical columns to the input layer
for col in ['Type','Breed1', 'Gender', 'Color1', 'Color2', 'MaturitySize','FurLength', 'Vaccinated', 'Sterilized', 'Health']:
  cat_col = layers.Input(shape=(1,),name=col,dtype='string')
  enc_layer = encoder_layer(col,train_ds,dtype='string')
  encoded_cat_col = enc_layer(cat_col)
  input_layers.append(cat_col)
  encoded_features.append(encoded_cat_col)
all_features = layers.concatenate(encoded_features)
# add the first dense layer
h1 = layers.Dense(units=10,activation='relu')(all_features)

# more hidden layers
h2 = layers.Dense(units=10,activation='relu')(h1)
h3 = layers.Dense(units=8,activation='relu')(h2)
h4 = layers.Dense(units=6,activation='relu')(h3)
h5 = layers.Dense(units=3,activation='relu')(h4)

# output layer
op = layers.Dense(1,activation='sigmoid')(h5)

model = models.Model(inputs=input_layers,outputs=op)
model.summary()
from tensorflow.keras.utils import plot_model
plot_model(model,show_shapes=True,rankdir="LR")
batch_size=1000
train_ds = create_dataset(train,batch_size=batch_size)
val_ds = create_dataset(val,batch_size=batch_size)
test_ds = create_dataset(test,batch_size=batch_size)
# compile the model
model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])
#train the model
model.fit(train_ds,epochs=10,validation_data=val_ds)
model.evaluate(test_ds)<jupyter_output>3/3 [==============================] - 0s 11ms/step - loss: 0.5263 - accuracy: 0.7286<jupyter_text>export the trained model<jupyter_code>model.save("classifier")
df.head(1).to_dict()
new_pet = {'Age':3,
 'Breed1':'Tabby',
 'Color1':'Black',
 'Color2':'White',
 'Fee':100,
 'FurLength':'Short',
 'Gender':'Male',
 'Health':'Healthy',
 'MaturitySize':'Small',
 'PhotoAmt':1,
 'Sterilized':'No',
 'Type':'Cat',
 'Vaccinated':'No'}
new_pet = {key:tf.convert_to_tensor([val]) for key,val in new_pet.items()}
model.predict(new_pet)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13191699604743082, 'fraction_numerical': 0.020092226613965744, 'mean_word_length': 7.529494382022472, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '555319', 'license': 'Apache-2.0', 'n_tokens_mistral': 2170, 'n_tokens_neox': 2056, 'n_words': 427, 'path': 'code_binary_Classification_keras_preprocessing_layers.ipynb', 'repo_name': 'anshupandey/Deep-Learning-for-structured-Data', 'size': '6072'}