Q- we have create the First Ml model here : 

Using logistic regression using this code : 
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score
from tabulate import tabulate


def train_and_validate_model(X_train, X_test, y_train, y_test, model=LogisticRegression()):
    """
    Train a model and validate its performance using various metrics.


    Input:
    - X_train: Training features
    - X_test: Testing features
    - y_train: Training labels
    - y_test: Testing labels
    - model: Machine learning model (default: LogisticRegression)


    Output:
    - accuracy: Accuracy score
    - precision: Precision score
    - recall: Recall score
    - f1: F1 score
    - roc_auc: ROC AUC score
    """
    # Train the model
    model.fit(X_train, y_train)


    # Make predictions
    y_pred = model.predict(X_test)
    y_pred_proba = model.predict_proba(X_test)[:, 1]


    # Calculate performance metrics
    accuracy = accuracy_score(y_test, y_pred)
    precision = precision_score(y_test, y_pred)
    recall = recall_score(y_test, y_pred)
    f1 = f1_score(y_test, y_pred)
    roc_auc = roc_auc_score(y_test, y_pred_proba)
   
    return accuracy, precision, recall, f1, roc_auc
"""
Q- now just print the result after calling the method
Q- give the code to it
"""
result = train_and_validate_model(X_train, X_test, y_train, y_test)
metrics = ['Accuracy', 'Precision', 'Recall', 'F1 Score', 'ROC AUC']
for metric, value in zip(metrics, result):
    print(f"{metric}: {value:.4f}")


Q- then i want to introduce MLflow to the picture like this 

import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import mlflow
import mlflow.sklearn


def train_and_validate_model(X_train, X_test, y_train, y_test, model=LogisticRegression()):
    with mlflow.start_run():
        # Log model parameters
        mlflow.log_param("model", "LogisticRegression")
        mlflow.log_param("test_size", 0.2)
        mlflow.log_param("random_state", 42)
       
        # Train the model
        model.fit(X_train, y_train)


        # Make predictions
        y_pred = model.predict(X_test)
        y_pred_proba = model.predict_proba(X_test)[:, 1]


        # Calculate performance metrics
        accuracy = accuracy_score(y_test, y_pred)
        precision = precision_score(y_test, y_pred)
        recall = recall_score(y_test, y_pred)
        f1 = f1_score(y_test, y_pred)
        roc_auc = roc_auc_score(y_test, y_pred_proba)


        # Log metrics
        metrics = ['accuracy', 'precision', 'recall', 'f1_score', 'roc_auc']
        for metric, value in zip(metrics, [accuracy, precision, recall, f1, roc_auc]):
            mlflow.log_metric(metric, value)
            print(f"{metric.capitalize()}: {value:.4f}")


        # Log the model
        mlflow.sklearn.log_model(model, "logistic_regression_model")


        return accuracy, precision, recall, f1, roc_auc


# Call the function
result = train_and_validate_model(X_train, X_test, y_train, y_test)




Q- and i get the this result : 

Accuracy: 0.8282
Precision: 0.8093
Recall: 0.8326
F1_score: 0.8207
Roc_auc: 0.9039


Q- now i want to use another model and test using principle like code reuse or “DRY” principle where i do not need to repeat the same model training pipeline if we have a function that encpsate the logic oky 

Q- so first question what about knn ? is a good choice after logistic regression yes or non?