Hyper-parameters Optimization using Gridsearch and Crossvalidation

Cross-validation estimates how well a model generalizes to unseen data, without relying on a single lucky (or unlucky) train/validation split.

How k-Fold Cross-Validation Works

  1. Hold out test data — Reserve a final test set never used during training or tuning.
  2. Split training data into k folds — e.g. 5 equal partitions.
  3. Rotate validation — For each fold:
    • Use that fold as the validation set
    • Train on the remaining k − 1 folds
    • Record the validation score
  4. Aggregate — Average the k scores for a stable performance estimate.
  5. Tune — Repeat for each hyperparameter combination; pick the best average CV score.
  6. Final evaluation — Retrain on all training data, evaluate once on the test set.

Why Use It?

BenefitExplanation
Less varianceOne random split can mislead; k folds smooth this out.
Better use of dataEvery sample is used for both training and validation.
Safer tuningCV guides hyperparameter search without peeking at the test set.

Common Variants

  • Stratified k-fold — Keeps class proportions in each fold (important for Titanic survival).
  • GridSearchCV / RandomizedSearchCV — Automate hyperparameter search with CV.
  • Leave-one-out (LOOCV) — k = n; expensive but uses maximum data per fold.

Key Rule

Never tune on the test set. Cross-validation uses training data only; the test set is evaluated once at the end.

# =============================================================================
# SECTION 1: DATA PREP, EDA & BASELINE DECISION TREE
# Run this cell to get ALL outputs for the Decision Tree section together.
# =============================================================================
# --- 1.1 Import libraries ---
import numpy as np
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
%matplotlib inline
# --- 1.2 Load Titanic dataset ---
titanic = sns.load_dataset('titanic')
sns.get_dataset_names()
titanic.head()
# --- 1.3 Basic EDA ---
titanic.shape
titanic.info()
titanic.head()
titanic.isna().sum()
# --- 1.4 Drop unused columns ---
titanic.drop(columns=['who', 'adult_male', 'embark_town', 'alone',
'alive', 'class', 'deck'], inplace=True)
titanic.head()
titanic.isna().sum()
titanic.info()
# --- 1.5 Inspect missing embarked values ---
titanic[titanic['embarked'].isna()]
titanic['embarked'].mode()
# --- 1.6 Missing value treatment ---
titanic['embarked'] = titanic['embarked'].fillna(titanic['embarked'].mode()[0])
titanic.iloc[[61, 829], :]
age_missing = titanic[titanic['age'].isna()]
age_missing.sample(10)
age_missing.shape
titanic['age'].median()
titanic['age'] = titanic['age'].fillna(titanic['age'].median())
titanic.info()
titanic.iloc[[667, 368], :]
titanic.info()
# --- 1.7 Rename columns ---
titanic = titanic.rename(columns={"sex": "gender", "SibSp": "siblings", "Parch": "parents_child"})
titanic.head()
titanic.info()
# --- 1.8 Dummy coding of categorical variables ---
for col in titanic.columns:
if titanic[col].dtype == "object":
titanic[col] = pd.Categorical(titanic[col]).codes
titanic.head()
titanic.info()
# --- 1.9 Survival counts ---
titanic.groupby('survived').size()
# --- 1.10 Import sklearn ---
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn import tree
# --- 1.11 Create features and label ---
x = titanic.drop(['survived'], axis=1, inplace=False)
y = titanic['survived']
x.shape
print('\n')
y.shape
# --- 1.12 Train/test split ---
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=999)
x_train.shape
y_train.shape
x_test.shape
y_test.shape
x_train
y_train
# --- 1.13 Survival rate in train vs test ---
np.round(y_train.sum() / y_train.count() * 100, 2)
print('\n')
np.round(y_test.sum() / y_test.count() * 100, 2)
# --- 1.14 Create Decision Tree model ---
mytree = tree.DecisionTreeClassifier(
criterion='gini', max_depth=3, min_samples_leaf=50, min_samples_split=75
)
mytree
# --- 1.15 Fit model ---
mytree.fit(x_train, y_train)
# --- 1.16 Predict ---
predicted = mytree.predict(x_test)
predicted
mytree.predict_proba(x_test)
# --- 1.17 Evaluate model performance ---
print(metrics.classification_report(y_test, predicted))
mytree
# --- 1.18 Confusion matrix and accuracy ---
df_confusion = metrics.confusion_matrix(y_test, predicted)
df_confusion
metrics.accuracy_score(y_test, predicted)
sns.heatmap(df_confusion, cmap='Blues',
xticklabels=['Prediction No', 'Prediction Yes'],
yticklabels=['Actual No', 'Actual Yes'],
annot=True, fmt='d')
plt.show()
# --- 1.19 Feature importance and tree visualization ---
x.columns
mytree.feature_importances_
y
import graphviz
dot_data = tree.export_graphviz(
mytree, out_file=None, feature_names=x.columns,
class_names=['0', '1'], filled=True, rounded=True, special_characters=True
)
graph = graphviz.Source(dot_data)
graph

Output

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 15 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 survived 891 non-null int64
1 pclass 891 non-null int64
2 sex 891 non-null object
3 age 714 non-null float64
4 sibsp 891 non-null int64
5 parch 891 non-null int64
6 fare 891 non-null float64
7 embarked 889 non-null object
8 class 891 non-null category
9 who 891 non-null object
10 adult_male 891 non-null bool
11 deck 203 non-null category
12 embark_town 889 non-null object
13 alive 891 non-null object
14 alone 891 non-null bool
dtypes: bool(2), category(2), float64(2), int64(4), object(5)
memory usage: 80.7+ KB
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 survived 891 non-null int64
1 pclass 891 non-null int64
2 sex 891 non-null object
3 age 714 non-null float64
4 sibsp 891 non-null int64
5 parch 891 non-null int64
6 fare 891 non-null float64
7 embarked 889 non-null object
dtypes: float64(2), int64(4), object(2)
memory usage: 55.8+ KB
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 survived 891 non-null int64
1 pclass 891 non-null int64
2 sex 891 non-null object
3 age 891 non-null float64
4 sibsp 891 non-null int64
5 parch 891 non-null int64
6 fare 891 non-null float64
7 embarked 891 non-null object
dtypes: float64(2), int64(4), object(2)
memory usage: 55.8+ KB
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 survived 891 non-null int64
1 pclass 891 non-null int64
2 sex 891 non-null object
3 age 891 non-null float64
4 sibsp 891 non-null int64
5 parch 891 non-null int64
6 fare 891 non-null float64
7 embarked 891 non-null object
dtypes: float64(2), int64(4), object(2)
memory usage: 55.8+ KB
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 survived 891 non-null int64
1 pclass 891 non-null int64
2 gender 891 non-null object
3 age 891 non-null float64
4 sibsp 891 non-null int64
5 parch 891 non-null int64
6 fare 891 non-null float64
7 embarked 891 non-null object
dtypes: float64(2), int64(4), object(2)
memory usage: 55.8+ KB
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 survived 891 non-null int64
1 pclass 891 non-null int64
2 gender 891 non-null int8
3 age 891 non-null float64
4 sibsp 891 non-null int64
5 parch 891 non-null int64
6 fare 891 non-null float64
7 embarked 891 non-null int8
dtypes: float64(2), int64(4), int8(2)
memory usage: 43.6 KB




precision recall f1-score support

0 0.77 0.99 0.86 115
1 0.97 0.45 0.62 64

accuracy 0.80 179
macro avg 0.87 0.72 0.74 179
weighted avg 0.84 0.80 0.78 179

# =============================================================================
# SECTION 2: CROSS-VALIDATION DEMO
# Requires Section 1 to be run first (mytree, x_train, y_train).
# =============================================================================
from sklearn.model_selection import cross_val_score
# --- 2.1 Default scoring (accuracy) ---
scores_acc = cross_val_score(mytree, x_train, y_train, cv=5)
scores_acc
# --- 2.2 Recall scoring ---
scores = cross_val_score(mytree, x_train, y_train, cv=5, scoring='recall')
scores

Output

array([0.71328671, 0.74125874, 0.78873239, 0.75352113, 0.74647887])
array([0.73214286, 0.67857143, 0.66071429, 0.63636364, 0.69090909])
# =============================================================================
# SECTION 3: HYPERPARAMETER OPTIMIZATION (GridSearchCV — Decision Tree)
# Requires Section 1 to be run first.
# =============================================================================
from sklearn.model_selection import GridSearchCV
# --- 3.1 Reset tree for tuning ---
mytree = tree.DecisionTreeClassifier(random_state=99, class_weight='balanced')
mytree
# --- 3.2 Define hyperparameter search space ---
my_max_depth = [2, 3, 4, 5, 10]
my_criterion = ['gini', 'entropy']
my_min_samples_leaf = [2, 5, 10, 15, 20, 25]
my_min_samples_split = [2, 5, 10, 15, 50, 100]
len(my_max_depth) * len(my_criterion) * len(my_min_samples_leaf) * len(my_min_samples_split)
# --- 3.3 Build GridSearchCV ---
grid = GridSearchCV(
estimator=mytree, cv=5, scoring='recall',
param_grid=dict(
max_depth=my_max_depth, criterion=my_criterion,
min_samples_leaf=my_min_samples_leaf,
min_samples_split=my_min_samples_split
)
)
grid
# --- 3.4 Fit on training data ---
grid.fit(x_train, y_train)
grid
# --- 3.5 Best model results ---
grid.best_params_
grid.best_estimator_.feature_importances_
print()
x.columns
grid.predict(x_test)
np.round(grid.best_score_, 2) * 100
results = pd.DataFrame(grid.cv_results_)
results.to_csv("results.csv")
# --- 3.6 Evaluate tuned model on test set ---
predicted = grid.predict(x_test)
print(metrics.classification_report(y_test, predicted))

Output

DecisionTreeClassifier

?i

DecisionTreeClassifier(class_weight='balanced', random_state=99)
360

GridSearchCV

?i





estimator: DecisionTreeClassifier





DecisionTreeClassifier

?





GridSearchCV

?i





best_estimator_: DecisionTreeClassifier





DecisionTreeClassifier

?





GridSearchCV

?i





best_estimator_: DecisionTreeClassifier





DecisionTreeClassifier

?





{'criterion': 'gini',
 'max_depth': 5,
 'min_samples_leaf': 20,
 'min_samples_split': 50}
array([0.17766848, 0.64657247, 0.08641906, 0.        , 0.        ,
       0.06719105, 0.02214894])




Index(['pclass', 'gender', 'age', 'sibsp', 'parch', 'fare', 'embarked'], dtype='object')
array([0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0,
       0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
       0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
       1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0,
       1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1,
       0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1,
       0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0,
       1, 0, 0])
np.float64(81.0)
              precision    recall  f1-score   support

           0       0.80      0.88      0.84       115
           1       0.74      0.61      0.67        64

    accuracy                           0.78       179
   macro avg       0.77      0.74      0.75       179
weighted avg       0.78      0.78      0.78       179
# =============================================================================
# SECTION 4: PREDICT PROBABILITY OF CLASSES
# Requires Section 3 to be run first (grid, predicted).
# =============================================================================
predicted_prob = grid.predict_proba(x_test)
predicted_prob_df = pd.DataFrame(predicted_prob)
predicted_classes_df = pd.DataFrame(predicted)
y_actual_df = pd.DataFrame(y_test.values)
predicted_df = pd.concat([predicted_prob_df, predicted_classes_df, y_actual_df], axis=1)
predicted_df.columns = ['Prob_0', 'Prob_1', 'Predicted_Class', 'Actual_Class']
predicted_prob
predicted_prob[0, 1]
predicted_df.sample(20)

Output

array([[0.74243323, 0.25756677],
[0.88857796, 0.11142204],
[0.88857796, 0.11142204],
[0.88857796, 0.11142204],
[0.4082232 , 0.5917768 ],
[0.74243323, 0.25756677],
[0.31391147, 0.68608853],
[0.74243323, 0.25756677],
[0.45582562, 0.54417438],
[0.85217984, 0.14782016],
[0.88857796, 0.11142204],
[0. , 1. ],
[0.88857796, 0.11142204],
[0.71187405, 0.28812595],
[0. , 1. ],
[0.30722004, 0.69277996],
[0.15470228, 0.84529772],
[0.71187405, 0.28812595],
[0.85217984, 0.14782016],
[0.88857796, 0.11142204],
[0.88857796, 0.11142204],
[0.56161616, 0.43838384],
[0.88857796, 0.11142204],
[0.88857796, 0.11142204],
[0.45582562, 0.54417438],
[0.88857796, 0.11142204],
[0.71927555, 0.28072445],
[0.88857796, 0.11142204],
[0.88857796, 0.11142204],
[0.88857796, 0.11142204],
[0.85217984, 0.14782016],
[0.88857796, 0.11142204],
[0.56161616, 0.43838384],
[0.56161616, 0.43838384],
[0.88857796, 0.11142204],
[0.88857796, 0.11142204],
[0.74243323, 0.25756677],
[0.88857796, 0.11142204],
[0.88857796, 0.11142204],
[0.88857796, 0.11142204],
[0.88857796, 0.11142204],
[0.10155869, 0.89844131],
[0.88857796, 0.11142204],
[0.56161616, 0.43838384],
[0.74243323, 0.25756677],
[0.88857796, 0.11142204],
[0. , 1. ],
[0.88857796, 0.11142204],
[0.88857796, 0.11142204],
[0.88857796, 0.11142204],
[0. , 1. ],
[0.71187405, 0.28812595],
[0.88857796, 0.11142204],
[0.28589058, 0.71410942],

Prob_0Prob_1Predicted_ClassActual_Class
200.8885780.11142200
880.4558260.54417410
980.8885780.11142200
10.8885780.11142200
590.7118740.28812601
1470.8885780.11142201
50.7424330.25756700
250.8885780.11142200
1420.4082230.59177710
70.7424330.25756700
720.0469590.95304111
1640.8885780.11142200
890.7118740.28812600
90.8521800.14782000
430.5616160.43838401
1200.7118740.28812601
220.8885780.11142200
210.5616160.43838401
1460.4558260.54417410
1440.8885780.11142200
# =============================================================================
# SECTION 5: THRESHOLD OPTIMIZATION
# Requires Section 3 to be run first (grid).
# =============================================================================
predicted_prob = grid.predict_proba(x_test)
predicted_prob
# --- 5.1 Threshold = 0.25 ---
new_y_test = predicted_prob[:, 1] >= 0.25
new_y_test
print(metrics.classification_report(y_test, new_y_test))
# --- 5.2 Threshold = 0.9 ---
new_y_test = predicted_prob[:, 1] >= 0.9
new_y_test
print(metrics.classification_report(y_test, new_y_test))

Output

array([[0.74243323, 0.25756677],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.4082232 , 0.5917768 ],
       [0.74243323, 0.25756677],
       [0.31391147, 0.68608853],
       [0.74243323, 0.25756677],
       [0.45582562, 0.54417438],
       [0.85217984, 0.14782016],
       [0.88857796, 0.11142204],
       [0.        , 1.        ],
       [0.88857796, 0.11142204],
       [0.71187405, 0.28812595],
       [0.        , 1.        ],
       [0.30722004, 0.69277996],
       [0.15470228, 0.84529772],
       [0.71187405, 0.28812595],
       [0.85217984, 0.14782016],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.56161616, 0.43838384],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.45582562, 0.54417438],
       [0.88857796, 0.11142204],
       [0.71927555, 0.28072445],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.85217984, 0.14782016],
       [0.88857796, 0.11142204],
       [0.56161616, 0.43838384],
       [0.56161616, 0.43838384],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.74243323, 0.25756677],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.10155869, 0.89844131],
       [0.88857796, 0.11142204],
       [0.56161616, 0.43838384],
       [0.74243323, 0.25756677],
       [0.88857796, 0.11142204],
       [0.        , 1.        ],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.        , 1.        ],
       [0.71187405, 0.28812595],
       [0.88857796, 0.11142204],
       [0.28589058, 0.71410942],
       [0.4082232 , 0.5917768 ],
       [0.30722004, 0.69277996],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.71187405, 0.28812595],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.04695946, 0.95304054],
       [0.56161616, 0.43838384],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.04695946, 0.95304054],
       [0.71187405, 0.28812595],
       [0.88857796, 0.11142204],
       [0.56161616, 0.43838384],
       [0.04695946, 0.95304054],
       [0.4082232 , 0.5917768 ],
       [0.88857796, 0.11142204],
       [0.71187405, 0.28812595],
       [0.56161616, 0.43838384],
       [0.85217984, 0.14782016],
       [0.88857796, 0.11142204],
       [0.71187405, 0.28812595],
       [0.28589058, 0.71410942],
       [0.71187405, 0.28812595],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.45582562, 0.54417438],
       [0.71187405, 0.28812595],
       [0.88857796, 0.11142204],
       [0.74243323, 0.25756677],
       [0.85217984, 0.14782016],
       [0.88857796, 0.11142204],
       [0.45582562, 0.54417438],
       [0.        , 1.        ],
       [0.85217984, 0.14782016],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.28589058, 0.71410942],
       [0.71187405, 0.28812595],
       [0.88857796, 0.11142204],
       [0.45582562, 0.54417438],
       [0.88857796, 0.11142204],
       [0.4082232 , 0.5917768 ],
       [0.        , 1.        ],
       [0.15470228, 0.84529772],
       [0.88857796, 0.11142204],
       [0.        , 1.        ],
       [0.88857796, 0.11142204],
       [0.04695946, 0.95304054],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.06644359, 0.93355641],
       [0.88857796, 0.11142204],
       [0.28589058, 0.71410942],
       [0.88857796, 0.11142204],
       [0.        , 1.        ],
       [0.88857796, 0.11142204],
       [0.        , 1.        ],
       [0.71187405, 0.28812595],
       [0.        , 1.        ],
       [0.71187405, 0.28812595],
       [0.88857796, 0.11142204],
       [0.71187405, 0.28812595],
       [0.30722004, 0.69277996],
       [0.88857796, 0.11142204],
       [0.        , 1.        ],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.74243323, 0.25756677],
       [0.04695946, 0.95304054],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.        , 1.        ],
       [0.88857796, 0.11142204],
       [0.45582562, 0.54417438],
       [0.56161616, 0.43838384],
       [0.88857796, 0.11142204],
       [0.        , 1.        ],
       [0.71187405, 0.28812595],
       [0.4082232 , 0.5917768 ],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.        , 1.        ],
       [0.45582562, 0.54417438],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.71187405, 0.28812595],
       [0.06644359, 0.93355641],
       [0.10155869, 0.89844131],
       [0.88857796, 0.11142204],
       [0.06644359, 0.93355641],
       [0.71187405, 0.28812595],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.71187405, 0.28812595],
       [0.28589058, 0.71410942],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.30722004, 0.69277996],
       [0.88857796, 0.11142204],
       [0.71927555, 0.28072445],
       [0.88857796, 0.11142204],
       [0.56161616, 0.43838384],
       [0.        , 1.        ],
       [0.4082232 , 0.5917768 ],
       [0.88857796, 0.11142204],
       [0.88857796, 0.11142204],
       [0.71927555, 0.28072445],
       [0.04695946, 0.95304054],
       [0.88857796, 0.11142204],
       [0.56161616, 0.43838384],
       [0.28589058, 0.71410942],
       [0.88857796, 0.11142204],
       [0.10155869, 0.89844131],
       [0.88857796, 0.11142204],
       [0.85217984, 0.14782016]])
array([ True, False, False, False,  True,  True,  True,  True,  True,
       False, False,  True, False,  True,  True,  True,  True,  True,
       False, False, False,  True, False, False,  True, False,  True,
       False, False, False, False, False,  True,  True, False, False,
        True, False, False, False, False,  True, False,  True,  True,
       False,  True, False, False, False,  True,  True, False,  True,
        True,  True, False, False, False,  True, False, False, False,
       False, False, False, False,  True,  True, False, False, False,
        True,  True, False,  True,  True,  True, False,  True,  True,
       False, False,  True,  True,  True, False, False,  True,  True,
       False,  True, False, False,  True,  True, False, False, False,
        True,  True, False,  True, False,  True,  True,  True, False,
        True, False,  True, False, False,  True, False,  True, False,
        True, False,  True,  True,  True,  True, False,  True,  True,
       False,  True, False, False,  True,  True, False, False, False,
        True, False,  True,  True, False,  True,  True,  True, False,
       False,  True,  True, False, False,  True,  True,  True, False,
        True,  True, False, False,  True,  True, False, False,  True,
       False,  True, False,  True,  True,  True, False, False,  True,
        True, False,  True,  True, False,  True, False, False])
              precision    recall  f1-score   support

           0       0.85      0.66      0.75       115
           1       0.57      0.80      0.66        64

    accuracy                           0.71       179
   macro avg       0.71      0.73      0.70       179
weighted avg       0.75      0.71      0.72       179

array([False, False, False, False, False, False, False, False, False,
       False, False,  True, False, False,  True, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False,  True, False, False, False,  True, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False,  True, False, False, False, False,
        True, False, False, False,  True, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False,  True, False, False, False,
       False, False, False, False, False, False,  True, False, False,
        True, False,  True, False, False,  True, False, False, False,
        True, False,  True, False,  True, False, False, False, False,
       False,  True, False, False, False,  True, False, False, False,
        True, False, False, False, False,  True, False, False, False,
       False,  True, False, False, False, False,  True, False, False,
        True, False, False, False, False, False, False, False, False,
       False, False, False, False,  True, False, False, False, False,
        True, False, False, False, False, False, False, False])
              precision    recall  f1-score   support

           0       0.74      1.00      0.85       115
           1       1.00      0.38      0.55        64

    accuracy                           0.78       179
   macro avg       0.87      0.69      0.70       179
weighted avg       0.83      0.78      0.74       179