<jupyter_start><jupyter_text>The dataset is imbalanced.<jupyter_code>print('Customer exited: {0:.2f} %'.format((x_class[1]/len(df1))*100))
print('Customer with open account: {0:.2f} %'.format((x_class[0]/len(df1))*100))
plt.bar(x=['no churn', 'churn'], height = x_class, width = 0.5)
plt.show()
# check for null values
df2.isna().sum()<jupyter_output><empty_output><jupyter_text>EDA<jupyter_code># plot Gerography wise customer churn
sns.countplot(data=df2, x='Geography', hue='Exited')
plt.title('Churn v/s No Churn - Countrywise', fontsize=15)
# plot Gender wise customer churn
sns.countplot(data=df2, x='Gender', hue='Exited')
plt.title('Churn v/s No Churn - Gender', fontsize=15)
# customer churn v/s number of product
sns.countplot(data=df2, x='NumOfProducts', hue='Exited')
plt.title('Churn v/s No Churn - NumOfProducts', fontsize=15)
# customer churn v/s IsActiveMember
sns.countplot(data=df2, x='IsActiveMember', hue='Exited')
plt.title('Churn v/s No Churn - IsActiveMember', fontsize=15)
# Churn v/s Age
plt.figure(figsize=(12,10))

sns.distplot(df2[df2['Exited'] == 0]["Age"], color='green') # No Churn - green
sns.distplot(df2[df2['Exited'] == 1]["Age"], color='red') # Churn - Red

plt.title('No Churn v/s Churn by Age', fontsize=15)
plt.xlim([18,100])
plt.show()
# Churn v/s Tenure
plt.figure(figsize=(12,10))

sns.distplot(df2[df2['Exited'] == 0]["Tenure"], color='green') # No Churn - green
sns.distplot(df2[df2['Exited'] == 1]["Tenure"], color='red') # Churn - Red

plt.title('No Churn v/s Churn by Tenure', fontsize=15)
plt.xlim([0,10])
plt.show()<jupyter_output><empty_output><jupyter_text>Data Cleaning<jupyter_code>plt.style.use('fivethirtyeight')
outlier= df2.plot(kind='box',figsize=(20,7));
plt.xticks(rotation=70);
plt.title('Outlier in data');<jupyter_output><empty_output><jupyter_text>No Outlier in the dataset  Standardize attributes<jupyter_code># hot encoding
X = df2.drop('Exited', axis=1)  # get only independent variables
y = df2['Exited']  # get output variable

num_cols = X.select_dtypes(include = ['int64', 'float64']).columns.to_list()
cat_cols = X.select_dtypes(include = ['object']).columns.to_list()
def label_encoder(df):
    for i in cat_cols:
        le = LabelEncoder()
        df[i] = le.fit_transform(df[i])
    return df
# robust scaler
rs = RobustScaler()
X[num_cols] = rs.fit_transform(X[num_cols])

# Label encoding
X = label_encoder(X)

X.head()
# Train Test Split

X_train, X_test, y_train, y_test = train_test_split(X, y, stratify = y, test_size=0.25, random_state=seed)
# over sample the minority class
from imblearn.over_sampling import SMOTE

smote = SMOTE()
X_train_balanced, y_train_balanced = smote.fit_resample(X_train, y_train)
# Output class count after oversampling
y_class = y_train_balanced.value_counts()
print(y_class)<jupyter_output>1    5972
0    5972
Name: Exited, dtype: int64<jupyter_text>Random Forest<jupyter_code>params = {'n_estimators': [50, 100, 150, 200],
          'max_depth': [10,20,30,40,50],
          'max_features': ['sqrt', 'log2'],
          'class_weight': ['balanced', None],
           'bootstrap': [True, False]}


rf_grid = GridSearchCV(RandomForestClassifier(random_state=seed),
                       param_grid=params,
                       scoring={'avr': make_scorer(average_precision_score, needs_proba=True),
                                'll': make_scorer(log_loss, greater_is_better=False, needs_proba=True)},
                       n_jobs=-1,
                       cv=5,
                       refit='avr')
rf_grid.fit(X_train_balanced, y_train_balanced)
rf_file = 'rf_model3.sav'  # file name to store RF model
joblib.dump(rf_grid, rf_file)  # stores the model
rf_grid.best_score_, rf_grid.best_params_
from sklearn.calibration import CalibratedClassifierCV, calibration_curve

predictions = rf_grid.predict_proba(X_train_balanced)[:, 1]
binned_true_p, binned_predict_p = calibration_curve(y_train_balanced, predictions, n_bins=10)
plt.scatter(binned_true_p, binned_predict_p)
m, b = np.polyfit(binned_true_p, binned_predict_p, 1)
plt.plot(binned_true_p, m*binned_true_p + b)
plt.show()<jupyter_output><empty_output><jupyter_text>Naive Bayes<jupyter_code>nb_model = GaussianNB()
nb_model.fit(X_train_balanced, y_train_balanced)
params = {'var_smoothing': [1e-9, 1e-10]}

nb_grid= GridSearchCV(cv=5, estimator=GaussianNB(),
             n_jobs=-1,
             param_grid=params,
             refit='avr',
             scoring={'avr': make_scorer(average_precision_score, needs_proba=True),
                      'll': make_scorer(log_loss, greater_is_better=False, needs_proba=True)})
nb_grid.fit(X_train_balanced, y_train_balanced)
nb_file = 'nb_model3.sav'  # file name to store RF model
joblib.dump(rf_grid, rf_file)  # stores the model
nb_grid.best_score_, nb_grid.best_params_<jupyter_output><empty_output><jupyter_text>Artificial Neural Network<jupyter_code>params = [{'solver': ['lbfgs'],
           'max_iter': [100, 200, 300]},
          {'solver': ['sgd'],
           'max_iter': [100, 200, 300],
           'learning_rate_init': [0.001,0.01,1]},
          {'solver': ['adam'],
           'max_iter': [100, 200, 300],
           'learning_rate_init': [0.001,0.01,1]}]

ann_grid = GridSearchCV(MLPClassifier(random_state=seed),
                       param_grid=params,
                       scoring={'avr': make_scorer(average_precision_score, needs_proba=True),
                                'll': make_scorer(log_loss, greater_is_better=False, needs_proba=True)},
                       n_jobs=-1,
                       cv=5,
                       refit='avr')
ann_grid.fit(X_train_balanced, y_train_balanced)
ann_file = 'ann_model3.sav'  # file name to store svc model
joblib.dump(ann_grid, ann_file)  # stores the model
ann_grid.best_score_, ann_grid.best_params_<jupyter_output><empty_output><jupyter_text>Gradient Boosting<jupyter_code>from sklearn.experimental import enable_hist_gradient_boosting
from sklearn.ensemble import HistGradientBoostingClassifier

params = {'learning_rate': [0.1, 0.01, 0.001],
          'max_iter': [1000, 2000, 3000],
          'max_leaf_nodes': [6,8,10],
          'validation_fraction': [0.1,0.2,0.3],
           'n_iter_no_change': [10, 15, 20]}

gb_grid = GridSearchCV(HistGradientBoostingClassifier(random_state=seed),
                       param_grid=params,
                       scoring={'avr': make_scorer(average_precision_score, needs_proba=True),
                                'll': make_scorer(log_loss, greater_is_better=False, needs_proba=True)},
                       n_jobs=-1,
                       cv=5,
                       refit='avr')
gb_grid.fit(X_train_balanced, y_train_balanced)
gb_file = 'gb_model3.sav'  # file name to store svc model
joblib.dump(gb_grid, gb_file)  # stores the model
gb_grid.best_score_, gb_grid.best_params_<jupyter_output><empty_output><jupyter_text>Test<jupyter_code># get f1 matrix after predicting the test set
y_pred = gb_grid.predict(X_test)
from sklearn.metrics import classification_report
target_names = ['no churn', 'churn']
print(classification_report(y_test, y_pred, target_names=target_names))
# get f1 matrix after predicting the test set
y_pred = nb_grid.predict(X_test)
from sklearn.metrics import classification_report
target_names = ['no churn', 'churn']
print(classification_report(y_test, y_pred, target_names=target_names))
# get f1 matrix after predicting the test set
y_pred = ann_grid.predict(X_test)
from sklearn.metrics import classification_report
target_names = ['no churn', 'churn']
print(classification_report(y_test, y_pred, target_names=target_names))
# get f1 matrix after predicting the test set
y_pred = rf_grid.predict(X_test)
from sklearn.metrics import classification_report
target_names = ['no churn', 'churn']
print(classification_report(y_test, y_pred, target_names=target_names))
from sklearn.metrics import confusion_matrix
confusion_matrix(y_test, y_pred)
print(accuracy_score(y_test, y_pred))
print(precision_score(y_test, y_pred))
print(recall_score(y_test, y_pred))
print(f1_score(y_test, y_pred))
# plot precision recall curve
# predict probabilities
yhat = rf_grid.predict_proba(X_test)
# retrieve just the probabilities for the positive class
pos_probs = yhat[:, 1]
# calculate model precision-recall curve
precision, recall, _ = precision_recall_curve(y_test, pos_probs)
# plot the model precision-recall curve
plt.plot(recall, precision, marker='.', label='rf')
# axis labels
plt.xlabel('Recall')
plt.ylabel('Precision')
# show the legend
plt.legend()
# show the plot
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13094682835820895, 'fraction_numerical': 0.025419776119402986, 'mean_word_length': 4.537120723047127, 'pattern_counts': {'":': 0, '<': 36, '<?xml version=': 0, '>': 36, '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': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '171872', 'license': 'CC-BY-3.0', 'n_tokens_mistral': 3264, 'n_tokens_neox': 3009, 'n_words': 594, 'path': 'Customer Churn Prediction/Code/term project3.ipynb', 'repo_name': 'saurabhbiswas1985/Portfolio', 'size': '8576'}