ML Project - Individual Review Ticket

Introduction

My triangle (Me, Tejas, and Abdullah) decided that we had a shared interest in real estate, so we decided to make a basic machine learning model that could predict the price of a house given user input.

The model is a linear regression model which uses a CSV file to use as training data. This CSV file contains data from more than 500 other sample houses to make a prediction for a house given as input by the user.

Backend/Model

from flask import Flask, request, jsonify
from flask import Blueprint
from flask_restful import Api, Resource
import seaborn as sns
import pandas as pd
from sklearn.preprocessing import OneHotEncoder
from sklearn.linear_model import LogisticRegression
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
import pickle

house_price_api = Blueprint('house_price_api', __name__, url_prefix='/api/house_price')
api = Api(house_price_api)

class HousePriceAPI(Resource):
    def __init__(self):
        # Load the dataset
        data = pd.read_csv('house_prices.csv')
        
        # Preprocessing and feature selection/engineering
        # Remove the 'furnishingstatus' column
        X = data.drop(['price', 'furnishingstatus'], axis=1)
        y = data['price']
        
        # Train the model
        self.model = LinearRegression()
        self.model.fit(X, y)

    def preprocess_inputs(self, area, bedrooms, bathrooms, stories, mainroad, guestroom, basement, hotwaterheating, airconditioning, parking, prefarea):
        # Convert 'yes' or 'no' inputs to 1 or 0
        mainroad = 1 if mainroad.lower() == 'yes' else 0
        guestroom = 1 if guestroom.lower() == 'yes' else 0
        basement = 1 if basement.lower() == 'yes' else 0
        hotwaterheating = 1 if hotwaterheating.lower() == 'yes' else 0
        airconditioning = 1 if airconditioning.lower() == 'yes' else 0
        parking = 1 if parking.lower() == 'yes' else 0
        prefarea = 1 if prefarea.lower() == 'yes' else 0
        
        return area, bedrooms, bathrooms, stories, mainroad, guestroom, basement, hotwaterheating, airconditioning, parking, prefarea

    def predict_house_price(self, area, bedrooms, bathrooms, stories, mainroad, guestroom, basement, hotwaterheating, airconditioning, parking, prefarea):
        # Prepare input data
        input_data = pd.DataFrame({
            'area': [area],
            'bedrooms': [bedrooms],
            'bathrooms': [bathrooms],
            'stories': [stories],
            'mainroad': [mainroad],
            'guestroom': [guestroom],
            'basement': [basement],
            'hotwaterheating': [hotwaterheating],
            'airconditioning': [airconditioning],
            'parking': [parking],
            'prefarea': [prefarea]
        })
        
        # Make prediction
        predicted_price = self.model.predict(input_data)
        return predicted_price[0]

    def post(self):
        try:
            # Get data from request
            data = request.json
            # Extract features
            area = data['area']
            bedrooms = data['bedrooms']
            bathrooms = data['bathrooms']
            stories = data['stories']
            mainroad = data['mainroad']
            guestroom = data['guestroom']
            basement = data['basement']
            hotwaterheating = data['hotwaterheating']
            airconditioning = data['airconditioning']
            parking = data['parking']
            prefarea = data['prefarea']
            # Preprocess inputs
            area, bedrooms, bathrooms, stories, mainroad, guestroom, basement, hotwaterheating, airconditioning, parking, prefarea = self.preprocess_inputs(area, bedrooms, bathrooms, stories, mainroad, guestroom, basement, hotwaterheating, airconditioning, parking, prefarea)
            # Predict house price
            predicted_price = self.predict_house_price(area, bedrooms, bathrooms, stories, mainroad, guestroom, basement, hotwaterheating, airconditioning, parking, prefarea)
            predicted_price = predicted_price/10
            predicted_price = round(predicted_price, 2)

            return jsonify({'predicted_price': predicted_price })
        except Exception as e:
            return jsonify({'error': str(e)})

api.add_resource(HousePriceAPI, '/predict')



Code/Data - Modifed/Added Segments in main.py (added model and API and init):

import threading
from flask import render_template, request, jsonify
from flask.cli import AppGroup
from __init__ import app, db, cors
from api.theme import theme_api
from api.user import user_api
from api.player import player_api
from api.titanic import titanic_api
from api.food import food_api
from api.bakery import bakery_api
from api.stock import stocks_api
from api.house_price import house_price_api
from auth_middleware import token_required

# database migrations
from model.users import initUsers, User
from model.players import initPlayers
from model.bakings import initBakings
from model.themes import initTheme
from model.painting import initImageTable, Painting

# setup APIs from first file
from api.covid import covid_api
from api.joke import joke_api

# setup App pages from second file
from projects.projects import app_projects
#test
# database migrations from second file
from model.foods import initfood
from model.bakeries import initbakery
from api.titanic import titanic_api
from api.food import food_api
from api.bakery import bakery_api
from api.baking import baking_api

# Initialize the SQLAlchemy object to work with the Flask app instance
db.init_app(app)

# setup App pages
from projects.projects import app_projects # Blueprint directory import projects definition

# register URIs from both files
app.register_blueprint(theme_api)
app.register_blueprint(user_api)
app.register_blueprint(player_api)
app.register_blueprint(covid_api)
app.register_blueprint(joke_api)
app.register_blueprint(titanic_api)
app.register_blueprint(food_api)
app.register_blueprint(stocks_api)
app.register_blueprint(bakery_api)
app.register_blueprint(house_price_api)
app.register_blueprint(baking_api)
app.register_blueprint(app_projects)

Frontend

---
title: Housing Prices ML
permalink: /houseprices
layout: base
description: Tejas, Deva, and Abdullah's CUSTOM DATASET ML model.
---

<html lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Elite Estates</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #222;
            margin: 0;
            padding: 0;
            display: block;
            justify-content: center;
            align-items: center;
            height: 100vh;
        }
        .container {
            background-color: #333;
            border-radius: 8px;
            padding: 40px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
            width: 400px;
        }
        h1 {
            text-align: center;
            margin-bottom: 20px;
            color: #fff;
            font-size: 24px;
        }
        label {
            display: block;
            margin-bottom: 10px;
            color: #fff;
            font-size: 16px;
        }
        input[type="text"],
        input[type="password"],
        select {
            width: calc(100% - 20px);
            padding: 10px;
            margin-bottom: 20px;
            border: 1px solid #555;
            border-radius: 4px;
            box-sizing: border-box;
            background-color: #444;
            color: #fff;
            font-size: 16px;
        }
        button {
            width: calc(100% - 20px);
            padding: 10px;
            background-color: #525252;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
        }
        button:hover {
            background-color: #454746;
        }
    </style>
    <header>
        <h1>Elite Estates</h1>
    </header>
    <nav>
    </nav>
    <div class="main-content">
        <h2>Welcome to Elite Estates!</h2>
        <p>Fill in the details below to predict house price:</p>
        <form id="house-price-form">
            <label for="area">Area (in sqft):</label>
            <input type="number" id="area" name="area" required>
            <label for="bedrooms">Number of Bedrooms:</label>
            <input type="number" id="bedrooms" name="bedrooms" required>
            <label for="bathrooms">Number of Bathrooms:</label>
            <input type="number" id="bathrooms" name="bathrooms" required>
            <label for="stories">Number of Stories:</label>
            <input type="number" id="stories" name="stories" required>
            <label for="mainroad">Main Road:</label>
            <select id="mainroad" name="mainroad">
                <option value="choose">Choose</option>
                <option value="yes">Yes</option>
                <option value="no">No</option>
            </select>
            <label for="guestroom">Guest Room:</label>
            <select id="guestroom" name="guestroom">
                <option value="choose">Choose</option>
                <option value="yes">Yes</option>
                <option value="no">No</option>
            </select>
            <label for="basement">Basement:</label>
            <select id="basement" name="basement">
                <option value="choose">Choose</option>
                <option value="yes">Yes</option>
                <option value="no">No</option>
            </select>
            <label for="hotwaterheating">Hot Water Heating:</label>
            <select id="hotwaterheating" name="hotwaterheating">
                <option value="choose">Choose</option>
                <option value="yes">Yes</option>
                <option value="no">No</option>
            </select>
            <label for="airconditioning">Air Conditioning:</label>
            <select id="airconditioning" name="airconditioning">
                <option value="choose">Choose</option>
                <option value="yes">Yes</option>
                <option value="no">No</option>
            </select>
            <label for="parking">Parking:</label>
            <select id="parking" name="parking">
                <option value="choose">Choose</option>
                <option value="yes">Yes</option>
                <option value="no">No</option>
            </select>
            <label for="prefarea">Preferred Area:</label>
            <select id="prefarea" name="prefarea">
                <option value="choose">Choose</option>
                <option value="yes">Yes</option>
                <option value="no">No</option>
            </select>
            <label for="furnishingstatus">Furnishing Status:</label>
            <select id="furnishingstatus" name="furnishingstatus">
                <option value="choose">Choose</option>
                <option value="furnished">Furnished</option>
                <option value="semi-furnished">Semi-Furnished</option>
                <option value="unfurnished">Unfurnished</option>
            </select>
            <input type="submit" value="Predict Price">
        </form>
        <div id="predicted-price" class="predicted-price"></div>
        <div class="sample-images">
        </div>
    </div>
    <script>
        document.getElementById('house-price-form').addEventListener('submit', function(event) {
            event.preventDefault(); // Prevent default form submission
            // Collect form data
            const formData = {
                area: document.getElementById('area').value,
                bedrooms: document.getElementById('bedrooms').value,
                bathrooms: document.getElementById('bathrooms').value,
                stories: document.getElementById('stories').value,
                mainroad: document.getElementById('mainroad').value,
                guestroom: document.getElementById('guestroom').value,
                basement: document.getElementById('basement').value,
                hotwaterheating: document.getElementById('hotwaterheating').value,
                airconditioning: document.getElementById('airconditioning').value,
                parking: document.getElementById('parking').value,
                prefarea: document.getElementById('prefarea').value
            }
            // Make a POST request to the backend API
            fetch('http://127.0.0.1:8008/api/house_price/predict', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(formData)
            })
            .then(response => response.json())
            .then(data => {
                // Display the prediction result
                const predictedPrice = data.predicted_price;
                alert("Predicted price: $" + predictedPrice);
                document.getElementById('predicted-price').innerHTML = '<span class="predicted-price-text">Predicted price: $' + predictedPrice + '</span>';
            })
            .catch(error => {
                console.error('Error:', error);
                alert('An error occurred while processing your request.');
            });
        });
    </script>
</html>