from flask import Flask, request, jsonify import joblib import numpy as np import pandas as pd import os # Create a Flask application instance app = Flask(__name__) # Define the path to the serialized model file model_filename = 'best_model.joblib' model_path = os.path.join(os.path.dirname(__file__), model_filename) # Load the serialized model try: loaded_model = joblib.load(model_path) print(f"Model loaded successfully from '{model_path}'") except Exception as e: print(f"Error loading model: {e}") loaded_model = None # Set model to None if loading fails # Define the prediction endpoint @app.route('/predict', methods=['POST']) def predict(): if loaded_model is None: return jsonify({'error': 'Model not loaded'}), 500 try: # Get the data from the request data = request.get_json() # Convert the input data to a pandas DataFrame # Assuming the input data is a list of dictionaries, # where each dictionary represents a data point with features. # The order of features should match the training data. input_df = pd.DataFrame(data) # NOTE: The preprocessor object is not available here. # In a real deployment, you would also serialize and load the preprocessor # or recreate it with the exact same steps and parameters. # For this example, we'll assume the input is already preprocessed or # we skip preprocessing for simplicity (not recommended for production). # If preprocessing is needed, you would do: # input_processed = loaded_preprocessor.transform(input_df) # For this example, let's assume the input data is already in the expected # format for the loaded model (which expects processed features). # In a real scenario, ensure the input data format matches the training data. # Assuming the input data is already preprocessed (e.g., one-hot encoded and scaled) # and is in the form of a list of lists or a numpy array that can be # converted to a format compatible with the loaded model's expected input shape. # For simplicity in this example, we will assume the input JSON # directly corresponds to the processed features expected by the model. # In a real-world scenario, you would need to implement the preprocessing steps here # using the serialized preprocessor or by recreating it. # Convert input_df to numpy array or appropriate format if needed by the model # Based on the training code, the model was trained on a processed numpy array # We will assume the input data JSON is structured to represent this processed array. # If the input JSON is raw data, you'll need the preprocessor here. # For now, let's assume the input JSON data can be directly passed to predict # if it's structured correctly as a list of lists or similar. # A safer approach would be to expect raw data and use a loaded preprocessor. # For now, let's assume the input data JSON is a list of dictionaries, # and we convert it to a DataFrame and then to a numpy array for prediction # if the model expects a numpy array. # However, since the model was trained on X_processed which was a sparse matrix initially # from the ColumnTransformer, direct conversion to a numpy array might lose sparsity # or cause issues if the original preprocessor's output format is critical. # A robust solution requires serializing and loading the preprocessor as well. # Given the context of previous cells, X_processed was likely a numpy array after transformation. # Let's assume the input JSON data can be directly used to create a numpy array # with the correct number of features (34 in this case, based on X_processed shape). # Example assuming input data is a list of lists matching the processed features shape input_data_processed = np.array(data['features']) # Make predictions predictions = loaded_model.predict(input_data_processed) # Convert predictions to a list predictions_list = predictions.tolist() # Return the predictions as a JSON response return jsonify({'predictions': predictions_list}) except Exception as e: return jsonify({'error': str(e)}), 400 # To run the Flask application (for local testing) if __name__ == '__main__': # For local testing, you can run: # Ensure the model file is in the same directory or adjust the model_path # app.run(debug=True) pass