help@rskworld.in +91 93305 39277
RSK World
  • Home
  • Development
    • Web Development
    • Mobile Apps
    • Software
    • Games
    • Project
  • Technologies
    • Data Science
    • AI Development
    • Cloud Development
    • Blockchain
    • Cyber Security
    • Dev Tools
    • Testing Tools
  • Blog
  • About
  • Contact

Theme Settings

Color Scheme
Display Options
Font Size
100%
Back to Project
RSK World
real-estate-bot
/
src
RSK World
real-estate-bot
Real Estate Bot - Python + Flask + OpenAI + SQLite + Property Search + AI Chatbot + Viewing Scheduler
src
  • __pycache__
  • __init__.py476 B
  • ai_recommendation_engine.py20.6 KB
  • app.py7.8 KB
  • blockchain_integration.py1.5 KB
  • chatbot.py15.5 KB
  • database.py18.4 KB
  • image_enhancer.py7.9 KB
  • multilang_support.py8.8 KB
  • neighborhood_analyzer.py6.1 KB
  • price_prediction_engine.py25.1 KB
  • property_search.py15.6 KB
  • virtual_tour_manager.py21.8 KB
  • voice_assistant.py27.6 KB
price_prediction_engine.py
src/price_prediction_engine.py
Raw Download
Find: Go to:
"""
Real-Time Price Prediction and Market Analysis Engine
Author: RSK World (https://rskworld.in)
Founded by: Molla Samser
Designer & Tester: Rima Khatun
Contact: info@rskworld.com, +91 93305 39277
Year: 2026
Description: Advanced AI-powered price prediction and real estate market analysis
"""

import numpy as np
import pandas as pd
from typing import List, Dict, Any, Tuple, Optional
from datetime import datetime, timedelta
import json
import requests
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
import joblib
import os
import warnings
warnings.filterwarnings('ignore')

class PricePredictionEngine:
    def __init__(self, database_manager):
        """
        Initialize Price Prediction Engine
        
        Args:
            database_manager: Database manager instance
        """
        self.db_manager = database_manager
        self.models_dir = 'data/prediction_models'
        os.makedirs(self.models_dir, exist_ok=True)
        
        # Initialize models
        self.price_model = None
        self.trend_model = None
        self.scaler = StandardScaler()
        self.label_encoders = {}
        
        # Market data cache
        self.market_data_cache = {}
        self.last_cache_update = None
        
        # Load or train models
        self._initialize_models()
    
    def _initialize_models(self):
        """Initialize or load prediction models"""
        try:
            self._load_models()
        except:
            self._train_models()
            self._save_models()
    
    def _train_models(self):
        """Train prediction models using historical data"""
        # Get historical property data
        properties = self.db_manager.search_properties({})
        
        if len(properties) < 10:
            # Not enough data for training
            self._create_simple_models()
            return
        
        # Prepare training data
        X, y = self._prepare_training_data(properties)
        
        if X is None or len(X) == 0:
            self._create_simple_models()
            return
        
        # Train price prediction model
        self.price_model = GradientBoostingRegressor(
            n_estimators=100,
            learning_rate=0.1,
            max_depth=6,
            random_state=42
        )
        
        self.price_model.fit(X, y)
        
        # Train trend analysis model
        self.trend_model = RandomForestRegressor(
            n_estimators=50,
            max_depth=4,
            random_state=42
        )
        
        # Create trend data (price changes over time)
        trend_data = self._create_trend_data(properties)
        if trend_data is not None:
            X_trend, y_trend = trend_data
            self.trend_model.fit(X_trend, y_trend)
    
    def _create_simple_models(self):
        """Create simple rule-based models when data is insufficient"""
        self.price_model = SimplePriceModel()
        self.trend_model = SimpleTrendModel()
    
    def _prepare_training_data(self, properties: List[Dict[str, Any]]) -> Tuple[np.ndarray, np.ndarray]:
        """Prepare training data for price prediction"""
        features = []
        prices = []
        
        for prop in properties:
            feature_vector = self._extract_features(prop)
            if feature_vector is not None:
                features.append(feature_vector)
                prices.append(prop.get('price', 0))
        
        if not features:
            return None, None
        
        X = np.array(features)
        y = np.array(prices)
        
        # Scale features
        X = self.scaler.fit_transform(X)
        
        return X, y
    
    def _extract_features(self, property: Dict[str, Any]) -> Optional[List[float]]:
        """Extract numerical features from property data"""
        try:
            features = [
                property.get('bedrooms', 0),
                property.get('bathrooms', 0),
                property.get('area_sqft', 0) / 1000,  # Convert to thousands
                property.get('year_built', 2020),
                len(property.get('amenities', [])),
                self._get_property_type_encoded(property.get('property_type', '')),
                self._get_location_score(property.get('location', '')),
                self._get_price_per_sqft(property),
                self._get_age_factor(property.get('year_built', 2020)),
                self._get_amenity_score(property.get('amenities', []))
            ]
            
            return features
            
        except Exception as e:
            print(f"Error extracting features: {e}")
            return None
    
    def _get_property_type_encoded(self, property_type: str) -> float:
        """Encode property type as numerical value"""
        type_mapping = {
            'apartment': 1.0,
            'house': 2.0,
            'villa': 3.0,
            'penthouse': 4.0,
            'condo': 1.5,
            'townhouse': 2.5
        }
        return type_mapping.get(property_type.lower(), 1.0)
    
    def _get_location_score(self, location: str) -> float:
        """Get location desirability score"""
        premium_locations = {
            'mumbai': 4.0,
            'delhi': 3.8,
            'bangalore': 3.9,
            'pune': 3.2,
            'chennai': 3.1,
            'gurgaon': 3.7,
            'noida': 3.5,
            'hyderabad': 3.4,
            'kolkata': 3.0
        }
        
        location_lower = location.lower()
        for city, score in premium_locations.items():
            if city in location_lower:
                return score
        
        return 2.5  # Default score for other locations
    
    def _get_price_per_sqft(self, property: Dict[str, Any]) -> float:
        """Calculate price per square foot"""
        price = property.get('price', 0)
        area = property.get('area_sqft', 1)
        return price / max(area, 1)
    
    def _get_age_factor(self, year_built: int) -> float:
        """Calculate age factor (newer properties get higher scores)"""
        current_year = datetime.now().year
        age = current_year - year_built
        return max(0, 1 - age / 50)  # Normalize to 0-1 scale
    
    def _get_amenity_score(self, amenities: List[str]) -> float:
        """Calculate amenity score based on quality and quantity"""
        premium_amenities = {
            'swimming_pool': 3.0,
            'gym': 2.5,
            'parking': 2.0,
            'security': 2.0,
            'garden': 2.5,
            'power_backup': 1.5,
            'concierge': 3.0,
            'jacuzzi': 3.0,
            'terrace': 2.0,
            'solar_panels': 2.5
        }
        
        score = 0
        for amenity in amenities:
            score += premium_amenities.get(amenity.lower(), 1.0)
        
        return min(score / 10, 1.0)  # Normalize to 0-1 scale
    
    def _create_trend_data(self, properties: List[Dict[str, Any]]) -> Optional[Tuple[np.ndarray, np.ndarray]]:
        """Create trend analysis data"""
        # For trend analysis, we would need historical price data
        # For now, create synthetic trend data
        
        trend_features = []
        trend_prices = []
        
        for prop in properties:
            # Create time-based features
            base_features = self._extract_features(prop)
            if base_features is not None:
                # Add time features (synthetic for demo)
                time_features = [
                    datetime.now().month / 12,  # Month of year
                    datetime.now().day / 30,     # Day of month
                    np.random.uniform(0.8, 1.2)  # Market factor
                ]
                
                trend_features.append(base_features + time_features)
                trend_prices.append(prop.get('price', 0))
        
        if not trend_features:
            return None, None
        
        return np.array(trend_features), np.array(trend_prices)
    
    def predict_property_price(self, property_data: Dict[str, Any], prediction_horizon: int = 30) -> Dict[str, Any]:
        """
        Predict property price for given horizon
        
        Args:
            property_data: Property information
            prediction_horizon: Days into future to predict
            
        Returns:
            Prediction results with confidence intervals
        """
        try:
            # Extract features
            features = self._extract_features(property_data)
            if features is None:
                return self._get_fallback_prediction(property_data)
            
            # Scale features
            features_scaled = self.scaler.transform([features])
            
            # Make prediction
            predicted_price = self.price_model.predict(features_scaled)[0]
            
            # Calculate confidence interval
            confidence_interval = self._calculate_confidence_interval(
                predicted_price, property_data
            )
            
            # Predict future price based on trend
            future_price = self._predict_future_price(
                predicted_price, prediction_horizon, property_data
            )
            
            # Calculate price appreciation
            appreciation_rate = ((future_price - predicted_price) / predicted_price) * 100
            
            return {
                'success': True,
                'current_predicted_price': round(predicted_price, 2),
                'future_predicted_price': round(future_price, 2),
                'prediction_horizon_days': prediction_horizon,
                'appreciation_rate': round(appreciation_rate, 2),
                'confidence_interval': {
                    'lower': round(confidence_interval[0], 2),
                    'upper': round(confidence_interval[1], 2)
                },
                'model_confidence': self._calculate_model_confidence(property_data),
                'prediction_date': (datetime.now() + timedelta(days=prediction_horizon)).isoformat(),
                'factors': self._get_price_factors(property_data)
            }
            
        except Exception as e:
            print(f"Error in price prediction: {e}")
            return self._get_fallback_prediction(property_data)
    
    def _get_fallback_prediction(self, property_data: Dict[str, Any]) -> Dict[str, Any]:
        """Get fallback prediction using simple rules"""
        base_price = property_data.get('price', 0)
        if base_price == 0:
            # Estimate based on area and location
            area = property_data.get('area_sqft', 1000)
            location_multiplier = self._get_location_score(property_data.get('location', ''))
            base_price = area * 5000 * location_multiplier
        
        # Add appreciation
        future_price = base_price * 1.05  # 5% appreciation
        
        return {
            'success': True,
            'current_predicted_price': round(base_price, 2),
            'future_predicted_price': round(future_price, 2),
            'prediction_horizon_days': 30,
            'appreciation_rate': 5.0,
            'confidence_interval': {
                'lower': round(base_price * 0.9, 2),
                'upper': round(base_price * 1.1, 2)
            },
            'model_confidence': 0.7,
            'prediction_date': (datetime.now() + timedelta(days=30)).isoformat(),
            'factors': ['Rule-based estimation']
        }
    
    def _calculate_confidence_interval(self, predicted_price: float, property_data: Dict[str, Any]) -> Tuple[float, float]:
        """Calculate confidence interval for prediction"""
        # Simple confidence interval based on property characteristics
        base_confidence = 0.1  # 10% base confidence interval
        
        # Adjust confidence based on data quality
        if property_data.get('bedrooms') and property_data.get('area_sqft'):
            confidence = base_confidence * 0.8  # Better data, tighter interval
        else:
            confidence = base_confidence * 1.2  # Poorer data, wider interval
        
        lower = predicted_price * (1 - confidence)
        upper = predicted_price * (1 + confidence)
        
        return lower, upper
    
    def _predict_future_price(self, current_price: float, days: int, property_data: Dict[str, Any]) -> float:
        """Predict future price based on market trends"""
        # Get market trend factor
        trend_factor = self._get_market_trend(property_data.get('location', ''))
        
        # Calculate daily appreciation rate
        annual_rate = 0.06  # 6% annual appreciation
        daily_rate = annual_rate / 365
        
        # Apply trend adjustment
        adjusted_rate = daily_rate * trend_factor
        
        # Calculate future price
        future_price = current_price * (1 + adjusted_rate) ** days
        
        return future_price
    
    def _get_market_trend(self, location: str) -> float:
        """Get market trend factor for location"""
        # This would typically use real market data
        # For now, use location-based assumptions
        location_lower = location.lower()
        
        hot_markets = ['mumbai', 'bangalore', 'pune', 'gurgaon']
        stable_markets = ['delhi', 'chennai', 'hyderabad']
        emerging_markets = ['noida', 'kolkata']
        
        if any(market in location_lower for market in hot_markets):
            return 1.2  # 20% above average
        elif any(market in location_lower for market in stable_markets):
            return 1.0  # Average
        elif any(market in location_lower for market in emerging_markets):
            return 1.1  # 10% above average
        else:
            return 0.9  # Below average
    
    def _calculate_model_confidence(self, property_data: Dict[str, Any]) -> float:
        """Calculate confidence score for the prediction"""
        confidence = 0.5  # Base confidence
        
        # Increase confidence based on data completeness
        if property_data.get('bedrooms'):
            confidence += 0.1
        if property_data.get('area_sqft'):
            confidence += 0.1
        if property_data.get('location'):
            confidence += 0.1
        if property_data.get('amenities'):
            confidence += 0.1
        
        # Adjust based on property type
        prop_type = property_data.get('property_type', '').lower()
        if prop_type in ['apartment', 'house']:
            confidence += 0.1
        
        return min(confidence, 0.95)  # Cap at 95%
    
    def _get_price_factors(self, property_data: Dict[str, Any]) -> List[str]:
        """Get factors influencing the price prediction"""
        factors = []
        
        if property_data.get('bedrooms'):
            factors.append(f"{property_data['bedrooms']} bedrooms")
        
        if property_data.get('area_sqft'):
            factors.append(f"{property_data['area_sqft']} sqft area")
        
        location_score = self._get_location_score(property_data.get('location', ''))
        if location_score > 3.5:
            factors.append("Premium location")
        elif location_score > 3.0:
            factors.append("Good location")
        
        if len(property_data.get('amenities', [])) > 5:
            factors.append("Well-equipped with amenities")
        
        year_built = property_data.get('year_built', 2020)
        if year_built >= 2022:
            factors.append("Newly constructed")
        
        return factors
    
    def get_market_analysis(self, location: str, property_type: str = None) -> Dict[str, Any]:
        """
        Get comprehensive market analysis for a location
        
        Args:
            location: Location to analyze
            property_type: Specific property type to focus on
            
        Returns:
            Market analysis data
        """
        try:
            # Get properties in the location
            search_criteria = {'location': location}
            if property_type:
                search_criteria['property_type'] = property_type
            
            properties = self.db_manager.search_properties(search_criteria)
            
            if not properties:
                return self._get_empty_market_analysis(location)
            
            # Calculate market metrics
            prices = [prop.get('price', 0) for prop in properties]
            areas = [prop.get('area_sqft', 0) for prop in properties]
            
            market_analysis = {
                'location': location,
                'property_type': property_type,
                'analysis_date': datetime.now().isoformat(),
                'total_properties': len(properties),
                'price_metrics': {
                    'average_price': np.mean(prices),
                    'median_price': np.median(prices),
                    'min_price': np.min(prices),
                    'max_price': np.max(prices),
                    'price_per_sqft_avg': np.mean([p/a for p, a in zip(prices, areas) if a > 0])
                },
                'market_trends': self._analyze_market_trends(properties),
                'inventory_analysis': self._analyze_inventory(properties),
                'price_distribution': self._analyze_price_distribution(prices),
                'recommendations': self._generate_market_recommendations(properties, location),
                'competitor_analysis': self._analyze_competitors(properties)
            }
            
            return {
                'success': True,
                'market_analysis': market_analysis
            }
            
        except Exception as e:
            print(f"Error in market analysis: {e}")
            return {'success': False, 'error': str(e)}
    
    def _get_empty_market_analysis(self, location: str) -> Dict[str, Any]:
        """Return empty market analysis when no data available"""
        return {
            'success': True,
            'market_analysis': {
                'location': location,
                'analysis_date': datetime.now().isoformat(),
                'total_properties': 0,
                'message': 'No properties found in this location',
                'recommendations': ['Consider expanding search area', 'Check back later for new listings']
            }
        }
    
    def _analyze_market_trends(self, properties: List[Dict[str, Any]]) -> Dict[str, Any]:
        """Analyze market trends"""
        # Price trends by property type
        type_prices = {}
        for prop in properties:
            prop_type = prop.get('property_type', 'unknown')
            if prop_type not in type_prices:
                type_prices[prop_type] = []
            type_prices[prop_type].append(prop.get('price', 0))
        
        trends = {}
        for prop_type, prices in type_prices.items():
            trends[prop_type] = {
                'average_price': np.mean(prices),
                'price_volatility': np.std(prices) / np.mean(prices) if np.mean(prices) > 0 else 0,
                'trend_direction': 'stable'  # Would need historical data for real trends
            }
        
        return trends
    
    def _analyze_inventory(self, properties: List[Dict[str, Any]]) -> Dict[str, Any]:
        """Analyze property inventory"""
        bedroom_counts = {}
        property_types = {}
        
        for prop in properties:
            # Count by bedrooms
            bedrooms = prop.get('bedrooms', 0)
            bedroom_counts[bedrooms] = bedroom_counts.get(bedrooms, 0) + 1
            
            # Count by property type
            prop_type = prop.get('property_type', 'unknown')
            property_types[prop_type] = property_types.get(prop_type, 0) + 1
        
        return {
            'bedroom_distribution': bedroom_counts,
            'property_type_distribution': property_types,
            'inventory_level': 'moderate' if len(properties) < 20 else 'high'
        }
    
    def _analyze_price_distribution(self, prices: List[float]) -> Dict[str, Any]:
        """Analyze price distribution"""
        if not prices:
            return {}
        
        percentiles = np.percentile(prices, [25, 50, 75])
        
        return {
            'q1': percentiles[0],
            'median': percentiles[1],
            'q3': percentiles[2],
            'iqr': percentiles[2] - percentiles[0],
            'outliers': len([p for p in prices if p < percentiles[0] - 1.5 * (percentiles[2] - percentiles[0]) or 
                           p > percentiles[2] + 1.5 * (percentiles[2] - percentiles[0])])
        }
    
    def _generate_market_recommendations(self, properties: List[Dict[str, Any]], location: str) -> List[str]:
        """Generate market recommendations"""
        recommendations = []
        
        avg_price = np.mean([prop.get('price', 0) for prop in properties])
        
        if avg_price > 10000000:  # > 1 crore
            recommendations.append("Premium market - consider value-added properties")
        elif avg_price > 5000000:  # > 50 lakhs
            recommendations.append("Mid-range market - good investment potential")
        else:
            recommendations.append("Affordable market - suitable for first-time buyers")
        
        if len(properties) < 10:
            recommendations.append("Low inventory - prices may increase")
        elif len(properties) > 50:
            recommendations.append("High inventory - buyers have negotiating power")
        
        return recommendations
    
    def _analyze_competitors(self, properties: List[Dict[str, Any]]) -> Dict[str, Any]:
        """Analyze competing properties"""
        # Sort by price and get top competitors
        sorted_props = sorted(properties, key=lambda x: x.get('price', 0))
        
        competitors = []
        for i, prop in enumerate(sorted_props[:5]):  # Top 5 competitors
            competitors.append({
                'rank': i + 1,
                'property_id': prop.get('id'),
                'title': prop.get('title', 'Property'),
                'price': prop.get('price', 0),
                'price_per_sqft': prop.get('price', 0) / max(prop.get('area_sqft', 1), 1),
                'key_features': prop.get('amenities', [])[:3]  # Top 3 amenities
            })
        
        return {
            'total_competitors': len(properties),
            'top_competitors': competitors
        }
    
    def _save_models(self):
        """Save trained models"""
        model_data = {
            'price_model': self.price_model,
            'trend_model': self.trend_model,
            'scaler': self.scaler,
            'label_encoders': self.label_encoders
        }
        
        joblib.dump(model_data, os.path.join(self.models_dir, 'price_models.pkl'))
    
    def _load_models(self):
        """Load pre-trained models"""
        model_data = joblib.load(os.path.join(self.models_dir, 'price_models.pkl'))
        
        self.price_model = model_data['price_model']
        self.trend_model = model_data['trend_model']
        self.scaler = model_data['scaler']
        self.label_encoders = model_data.get('label_encoders', {})


class SimplePriceModel:
    """Simple rule-based price model for fallback"""
    
    def predict(self, X):
        """Simple price prediction based on features"""
        # Feature indices: bedrooms, bathrooms, area, year, amenities, type, location, price/sqft, age, amenity_score
        base_price = X[0][2] * 8000  # Area * base rate
        
        # Adjust for bedrooms
        base_price *= (1 + X[0][0] * 0.1)
        
        # Adjust for location
        base_price *= X[0][6]
        
        # Adjust for amenities
        base_price *= (1 + X[0][9] * 0.2)
        
        return np.array([base_price])


class SimpleTrendModel:
    """Simple trend model for fallback"""
    
    def predict(self, X):
        """Simple trend prediction"""
        return X[:, -1] * 1.05  # 5% appreciation


# Market data API integration
class MarketDataAPI:
    """Integration with external market data sources"""
    
    def __init__(self):
        self.api_keys = {
            'magicbricks': os.getenv('MAGICBRICKS_API_KEY'),
            '99acres': os.getenv('99ACRES_API_KEY'),
            'housing': os.getenv('HOUSING_API_KEY')
        }
    
    def get_market_data(self, location: str) -> Dict[str, Any]:
        """Get market data from external APIs"""
        # This would integrate with real estate APIs
        # For now, return mock data
        return {
            'location': location,
            'average_price_per_sqft': 8000,
            'price_trend': 'increasing',
            'inventory_level': 'moderate',
            'days_on_market': 45,
            'last_updated': datetime.now().isoformat()
        }
657 lines•25.1 KB
python

About RSK World

Founded by Molla Samser, with Designer & Tester Rima Khatun, RSK World is your one-stop destination for free programming resources, source code, and development tools.

Founder: Molla Samser
Designer & Tester: Rima Khatun

Development

  • Game Development
  • Web Development
  • Mobile Development
  • AI Development
  • Development Tools

Legal

  • Terms & Conditions
  • Privacy Policy
  • Disclaimer

Contact Info

Nutanhat, Mongolkote
Purba Burdwan, West Bengal
India, 713147

+91 93305 39277

hello@rskworld.in
support@rskworld.in

© 2026 RSK World. All rights reserved.

Content used for educational purposes only. View Disclaimer