<jupyter_start><jupyter_text>IBM Employee AttritionData source: https://www.kaggle.com/pavansubhasht/ibm-hr-analytics-attrition-dataset  Dependencies and data<jupyter_code># Dependencies
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from tensorflow import keras

%matplotlib inline
# Data
emp_df = pd.read_csv('data/ibm-employees.csv')
emp_df.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 1470 entries, 0 to 1469
Data columns (total 35 columns):
 #   Column                    Non-Null Count  Dtype 
---  ------                    --------------  ----- 
 0   Age                       1470 non-null   int64 
 1   Attrition                 1470 non-null   object
 2   BusinessTravel            1470 non-null   object
 3   DailyRate                 1470 non-null   int64 
 4   Department                1470 non-null   object
 5   DistanceFromHome          1470 non-null   int64 
 6   Education                 1470 non-null   int64 
 7   EducationField            1470 non-null   object
 8   EmployeeCount             1470 non-null   int64 
 9   EmployeeNumber            1470 non-null   int64 
 10  EnvironmentSatisfaction   1470 non-null   int64 
 11  Gender                    1470 non-null   object
 12  HourlyRate                1470 non-null   int64 
 13  JobInvolvement            1470 non-null   int64 
 14  JobLevel                [...]<jupyter_text>Data preprocessing<jupyter_code># Categorical features
cat_feats = emp_df.dtypes[emp_df.dtypes == object].index.tolist()

# Unique counts
emp_df[cat_feats].nunique()
# Remove `Over18` from list
cat_feats.remove('Over18')

# Drop `Over18`
emp_df.drop(columns='Over18', inplace=True)
emp_df.shape
# One-hot encoding
enc = OneHotEncoder(drop='if_binary', sparse=False)
emp_ohe = enc.fit_transform(emp_df[cat_feats])
emp_ohe = pd.DataFrame(emp_ohe, columns=enc.get_feature_names(cat_feats)) # convert to df
emp_ohe.head()
# Merge data
df = emp_df.merge(emp_ohe, left_index=True, right_index=True)

# Drop categorical columns
df.drop(columns=cat_feats, inplace=True)
df.head()
# Feature/target split
X = df.drop(columns='Attrition_Yes')
y = df['Attrition_Yes']

# Train/test split
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=24)
X_train.shape, X_test.shape, y_train.shape, y_test.shape
# Scale data
scaler = StandardScaler()
X_train_scaled = pd.DataFrame(scaler.fit_transform(X_train), columns=X_train.columns)
X_test_scaled = pd.DataFrame(scaler.transform(X_test), columns=X_test.columns)
X_train_scaled.head()<jupyter_output><empty_output><jupyter_text>Neural network<jupyter_code># Sequential NN
nn = keras.models.Sequential(name='52-25-10-1')

# Layers
nn.add(keras.layers.Dense(units=25, activation='relu', input_dim=X_train_scaled.shape[1])) # input + hidden layer 1 w/ 25 neurons
nn.add(keras.layers.Dense(units=10, activation='relu')) # hidden layer 2 w/ 10 neurons
nn.add(keras.layers.Dense(units=1, activation='sigmoid')) # output layer

nn.summary()
# Compile model
nn.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

# Train model
nn_trained = nn.fit(X_train_scaled, y_train, epochs=100) # 100 iterations

# Evaluate model
print('\nTest set performance:')
nn.evaluate(X_test_scaled, y_test, verbose=2) # loss and accuracy
# Plot training loss and accuracy
nn_history = pd.DataFrame(nn_trained.history, index=range(1, len(nn_trained.history['loss']) + 1))
nn_history.plot(subplots=True, figsize=(12, 6), grid=True, title='Training Epochs')
plt.xticks(rotation=0, ha='center')
plt.show()<jupyter_output><empty_output><jupyter_text>Compare performance to other classifiers<jupyter_code># Logistic regression
lr = LogisticRegression(random_state=52)
lr.fit(X_train_scaled, y_train)
print('Train set accuracy:', lr.score(X_train_scaled, y_train))
print('Test set accuracy:', lr.score(X_test_scaled, y_test))
# Random forest
rf = RandomForestClassifier(random_state=52)
rf.fit(X_train_scaled, y_train)
print('Train set accuracy:', rf.score(X_train_scaled, y_train))
print('Test set accuracy:', rf.score(X_test_scaled, y_test))<jupyter_output>Train set accuracy: 1.0
Test set accuracy: 0.8586956521739131
{'fraction_non_alphanumeric': 0.10976722957553628, 'fraction_numerical': 0.03879507074395253, 'mean_word_length': 4.2178571428571425, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 16, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, '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': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '386436', 'license': 'MIT', 'n_tokens_mistral': 1637, 'n_tokens_neox': 1482, 'n_words': 324, 'path': 'keras-demo/emp-attrition.ipynb', 'repo_name': 'tri-bui/sandbox-dl', 'size': '4382'}