Seamlessly Integrating Machine Learning Model with the MERN Stack

Seamlessly Integrating Machine Learning Model with the MERN Stack

In this blog post, I'll show you how to build a house price prediction web application using the MERN stack (MongoDB, Express, React, Node.js) and a machine learning model created with Python. The application lets users enter house features, like size and number of bedrooms, and then provides an estimated price based on a trained linear regression model.

Overview

This project is divided into 3 parts

  1. Machine Learning: Training a linear regression model using Python to predict house prices based on features like house size and the number of bedrooms.

  2. Backend: Developing a Flask API in Python that serves the trained machine learning model, processes incoming requests, and returns predicted prices.

  3. Frontend: Building a React-based web interface using the MERN stack, which allows users to input house features and displays the predicted price by interacting with the backend API.

Technologies Used

  • MERN Stack: MongoDB, Express.js, React, Node.js

  • Python Libraries: Flask, Flask-CORS, pandas, scikit-learn, pickle

  • Frontend Libraries: Axios, Vite (for bundling React)

Machine Learning

Training the Model

The first step is to train a linear regression model using scikit-learn. This model is trained on a small dataset that includes house sizes, the number of bedrooms, and their corresponding prices.

# train_model.py
import pickle
import pandas as pd
from sklearn import linear_model

# This is a dummy data to train the model, if you wish to add your 
# other data you can add it here or can just read the csv file
def train_and_save_model(): 
    house_data = {
        "sizes": [1200, 1500, 1000, 1800, 1600],
        "bedrooms": [3, 4, 2, 4, 3],
        "prices": [250000, 320000, 180000, 350000, 270000],
    }

    df = pd.DataFrame(house_data)
    reg = linear_model.LinearRegression()
    reg.fit(df[["sizes", "bedrooms"]], df["prices"])

    with open("model.pkl", "wb") as f:
        pickle.dump(reg, f)

    print("Model saved")


if __name__ == "__main__":
    train_and_save_model()

This code trains the model and saves it to a file named model.pkl for future use.

Backend Development

1) Creating the Flask API

The Flask API serves as the link between the machine learning model and the frontend. When it receives data from the frontend, it first loads the pre-trained model to prepare it for predictions. The API then processes the incoming data, making sure it is structured as a 2D array, which is the format needed by the model for accurate predictions. After the model generates the predicted prices, the API sends these results back to the frontend for display.

import pickle
import pandas as pd
from flask_cors import CORS
from flask import Flask, jsonify, request

app = Flask(__name__)
CORS(app)

@app.route("/api/predict/", methods=["POST"])
def index():
    data = request.json
    sizes = data["sizes"]
    bedrooms = data["bedrooms"]

    new_data = pd.DataFrame({"sizes": sizes, "bedrooms": bedrooms})

    with open("model.pkl", "rb") as f:
        model = pickle.load(f)

    prices = model.predict(new_data).tolist()
    results = []

    for size, bedroom, price in zip(sizes, bedrooms, prices):
        results.append({
            "size": size,
            "bedroom": bedroom,
            "predicted_price": f"{price:,.2f}",
        })

    return jsonify({"message": "Prediction results", "results": results})

if __name__ == "__main__":
    host = "localhost"
    port = "5000"
    print(f"Running on http://{host}:{port}/")
    app.run(debug=True, host=host, port=port)
  • Setting debug=True in the Flask application allows for automatic reloading and detailed error messages, making development easier.

  • It's also worth noting that specifying the host and port is optional. By default, Flask will run on localhost and port 5000 if not explicitly set.

2) Running the Flask API

To start the API, simply run the Flask application:

python app.py

Your Flask API will now be running on http://localhost:5000/api/predict/, ready to receive POST requests.

Diagram showing the flow of data between the React frontend, Flask API, and the machine learning model.

Frontend Development

The frontend is built using React, with Vite as the build tool for a faster development experience. It captures user inputs for house size and number of bedrooms and sends this data to the Flask API to get the predicted price.

Creating a Vite + React Application

  1. Install Node.js and npm: Make sure you have Node.js and npm installed. You can download them from nodejs.org.

  2. Create a New Vite + React Project:

    Open your terminal and run the following command to create a new Vite project with React:

     npm create vite@latest my-react-app --template react
    

    Replace my-react-app with your preferred project name. This command sets up a new Vite project with a React template.

  3. Navigate to Your Project Directory:

    Install the necessary dependencies by running:

     npm i vite axios
    
  4. Start the development Server:

     npm run dev
    

Integrating with Flask API

Creating the Input Form:

The form allows users to input the size of the house and the number of bedrooms.

import { useState } from "react";
import axios from "axios";

function App() {
  const [value2, setValue2] = useState({
    sizes: [],
    bedrooms: [],
  });
  const [price, setPrice] = useState("");

  const fetchValue = async () => {
    try {
      const res = await axios.post(
        "http://localhost:5000/api/predict/",
        value2
      );
      setPrice(res.data.results[0].predicted_price);
    } catch (error) {
      console.log(error.message);
    }
  };

  return (
    <>
      <h1 className="text-5xl mt-10 font-bold text-primary">
        Welcome to House Price Prediction
      </h1>
      <div className="flex gap-4 mt-4">
        <input
          type="number"
          value={value2.sizes}
          placeholder="Enter Size"
          className="input input-bordered input-accent w-full max-w-xs"
          onChange={(e) =>
            setValue2({ ...value2, sizes: [Number(e.target.value)] })
          }
        />
        <input
          type="number"
          value={value2.bedrooms}
          placeholder="Enter Bedroom"
          className="input input-bordered input-accent w-full max-w-xs"
          onChange={(e) =>
            setValue2({ ...value2, bedrooms: [Number(e.target.value)] })
          }
        />
        <button className="btn btn-accent" onClick={fetchValue}>
          Predict
        </button>
      </div>
      <div className="flex items-center w-full">
        <h1 className="text-5xl mt-10 font-bold underline">
          {`Predicted Price: ${price}`}
        </h1>
      </div>
    </>
  );
}

export default App;

Fetching Predictions

When the user clicks the "Predict" button, the form data is sent to the Flask API, which returns the predicted price. The result is then displayed on the page.

Final Integration

With the backend and frontend set up, the entire application is now functional. Users can enter house sizes and the number of bedrooms into the form, and the app will display the predicted house price using the machine learning model.

Conclusion

Integrating a machine learning model into a full-stack web application can be an enriching experience, combining the strengths of Python for Machine Learning with the robustness of the MERN stack. This blog has demonstrated how to create a seamless and functional house price prediction application, from training the model to deploying the web app.

Feel free to check out the complete project on my GitHub repository here, and I hope this guide helps you on your journey to integrating machine learning with web development!