suryateja008 commited on
Commit
7ff1839
·
verified ·
1 Parent(s): 38a0f55

Upload parking_slot_classifier.py

Browse files
Files changed (1) hide show
  1. ai_model/parking_slot_classifier.py +256 -0
ai_model/parking_slot_classifier.py ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Smart Parking Slot Classifier
3
+ A basic classification model to find the optimal parking spot based on:
4
+ - Proximity to destination
5
+ - Slot popularity (historical usage)
6
+ - User feedback scores
7
+ """
8
+
9
+ import numpy as np
10
+ from sklearn.ensemble import RandomForestClassifier
11
+ from sklearn.preprocessing import StandardScaler
12
+ import pickle
13
+ import json
14
+ from typing import List, Dict, Tuple
15
+
16
+
17
+ class ParkingSlotClassifier:
18
+ """
19
+ Basic ML model to classify and rank parking slots based on multiple factors
20
+ """
21
+
22
+ def __init__(self):
23
+ self.model = RandomForestClassifier(
24
+ n_estimators=100,
25
+ max_depth=10,
26
+ random_state=42
27
+ )
28
+ self.scaler = StandardScaler()
29
+ self.is_trained = False
30
+
31
+ def calculate_proximity_score(self, slot_coords: Tuple[float, float],
32
+ user_coords: Tuple[float, float]) -> float:
33
+ """
34
+ Calculate distance-based proximity score using Haversine formula
35
+ Returns score between 0-1 (1 being closest)
36
+ """
37
+ lat1, lon1 = slot_coords
38
+ lat2, lon2 = user_coords
39
+
40
+ # Haversine formula
41
+ R = 6371 # Earth's radius in kilometers
42
+
43
+ lat1_rad = np.radians(lat1)
44
+ lat2_rad = np.radians(lat2)
45
+ delta_lat = np.radians(lat2 - lat1)
46
+ delta_lon = np.radians(lon2 - lon1)
47
+
48
+ a = np.sin(delta_lat/2)**2 + np.cos(lat1_rad) * np.cos(lat2_rad) * np.sin(delta_lon/2)**2
49
+ c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1-a))
50
+ distance = R * c
51
+
52
+ # Convert to score (inverse relationship - closer is better)
53
+ # Max distance considered: 5km
54
+ proximity_score = max(0, 1 - (distance / 5.0))
55
+ return proximity_score
56
+
57
+ def prepare_features(self, slots_data: List[Dict]) -> np.ndarray:
58
+ """
59
+ Prepare feature matrix from slot data
60
+ Features:
61
+ 1. Proximity score (0-1)
62
+ 2. Average feedback score (0-5)
63
+ 3. Popularity score (normalized booking count)
64
+ 4. Availability score (1 if available, 0 if not)
65
+ 5. Price factor (normalized)
66
+ """
67
+ features = []
68
+
69
+ for slot in slots_data:
70
+ feature_vector = [
71
+ slot.get('proximity_score', 0.5),
72
+ slot.get('avg_feedback', 3.0) / 5.0, # Normalize to 0-1
73
+ slot.get('popularity_score', 0.5),
74
+ 1.0 if slot.get('is_available', True) else 0.0,
75
+ slot.get('price_factor', 0.5)
76
+ ]
77
+ features.append(feature_vector)
78
+
79
+ return np.array(features)
80
+
81
+ def train(self, training_data: List[Dict], labels: List[int]):
82
+ """
83
+ Train the model with historical data
84
+ labels: 1 if slot was chosen and user was satisfied, 0 otherwise
85
+ """
86
+ X = self.prepare_features(training_data)
87
+ X_scaled = self.scaler.fit_transform(X)
88
+
89
+ self.model.fit(X_scaled, labels)
90
+ self.is_trained = True
91
+ print(f"Model trained with {len(training_data)} samples")
92
+
93
+ def predict_best_slots(self, slots_data: List[Dict],
94
+ user_location: Tuple[float, float],
95
+ top_k: int = 3) -> List[Dict]:
96
+ """
97
+ Predict and return top K best parking slots
98
+ """
99
+ # Calculate proximity scores for all slots
100
+ for slot in slots_data:
101
+ slot_coords = (slot['latitude'], slot['longitude'])
102
+ slot['proximity_score'] = self.calculate_proximity_score(
103
+ slot_coords, user_location
104
+ )
105
+
106
+ # If model is trained, use it for prediction
107
+ if self.is_trained:
108
+ X = self.prepare_features(slots_data)
109
+ X_scaled = self.scaler.transform(X)
110
+
111
+ # Get probability scores for positive class
112
+ scores = self.model.predict_proba(X_scaled)[:, 1]
113
+ else:
114
+ # Fallback to weighted scoring if model not trained
115
+ scores = self._calculate_weighted_scores(slots_data)
116
+
117
+ # Add scores to slots
118
+ for i, slot in enumerate(slots_data):
119
+ slot['recommendation_score'] = float(scores[i])
120
+
121
+ # Sort by score and return top K
122
+ sorted_slots = sorted(slots_data,
123
+ key=lambda x: x['recommendation_score'],
124
+ reverse=True)
125
+
126
+ return sorted_slots[:top_k]
127
+
128
+ def _calculate_weighted_scores(self, slots_data: List[Dict]) -> np.ndarray:
129
+ """
130
+ Fallback weighted scoring when model is not trained
131
+ """
132
+ scores = []
133
+ for slot in slots_data:
134
+ # Weights for different factors
135
+ score = (
136
+ slot.get('proximity_score', 0.5) * 0.4 + # 40% weight to proximity
137
+ (slot.get('avg_feedback', 3.0) / 5.0) * 0.3 + # 30% to feedback
138
+ slot.get('popularity_score', 0.5) * 0.2 + # 20% to popularity
139
+ (1.0 if slot.get('is_available', True) else 0.0) * 0.1 # 10% availability
140
+ )
141
+ scores.append(score)
142
+
143
+ return np.array(scores)
144
+
145
+ def save_model(self, filepath: str):
146
+ """Save trained model to disk"""
147
+ model_data = {
148
+ 'model': self.model,
149
+ 'scaler': self.scaler,
150
+ 'is_trained': self.is_trained
151
+ }
152
+ with open(filepath, 'wb') as f:
153
+ pickle.dump(model_data, f)
154
+ print(f"Model saved to {filepath}")
155
+
156
+ def load_model(self, filepath: str):
157
+ """Load trained model from disk"""
158
+ with open(filepath, 'rb') as f:
159
+ model_data = pickle.load(f)
160
+
161
+ self.model = model_data['model']
162
+ self.scaler = model_data['scaler']
163
+ self.is_trained = model_data['is_trained']
164
+ print(f"Model loaded from {filepath}")
165
+
166
+
167
+ def generate_training_data(num_samples: int = 100) -> Tuple[List[Dict], List[int]]:
168
+ """
169
+ Generate synthetic training data for initial model training
170
+ In production, this would come from real user feedback
171
+ """
172
+ slots_data = []
173
+ labels = []
174
+
175
+ for i in range(num_samples):
176
+ # Generate random slot data
177
+ slot = {
178
+ 'slot_id': f'SLOT_{i}',
179
+ 'latitude': 28.6139 + np.random.uniform(-0.1, 0.1),
180
+ 'longitude': 77.2090 + np.random.uniform(-0.1, 0.1),
181
+ 'proximity_score': np.random.uniform(0, 1),
182
+ 'avg_feedback': np.random.uniform(2, 5),
183
+ 'popularity_score': np.random.uniform(0, 1),
184
+ 'is_available': np.random.choice([True, False], p=[0.7, 0.3]),
185
+ 'price_factor': np.random.uniform(0.3, 1.0)
186
+ }
187
+
188
+ # Generate label based on features (higher quality slots more likely to be chosen)
189
+ quality_score = (
190
+ slot['proximity_score'] * 0.4 +
191
+ (slot['avg_feedback'] / 5.0) * 0.3 +
192
+ slot['popularity_score'] * 0.2 +
193
+ (1.0 if slot['is_available'] else 0.0) * 0.1
194
+ )
195
+
196
+ label = 1 if quality_score > 0.6 else 0
197
+
198
+ slots_data.append(slot)
199
+ labels.append(label)
200
+
201
+ return slots_data, labels
202
+
203
+
204
+ if __name__ == "__main__":
205
+ # Example usage
206
+ print("Initializing Parking Slot Classifier...")
207
+ classifier = ParkingSlotClassifier()
208
+
209
+ # Generate and train with synthetic data
210
+ print("\nGenerating training data...")
211
+ training_data, labels = generate_training_data(200)
212
+
213
+ print("\nTraining model...")
214
+ classifier.train(training_data, labels)
215
+
216
+ # Example prediction
217
+ print("\nTesting prediction...")
218
+ test_slots = [
219
+ {
220
+ 'slot_id': 'A1',
221
+ 'latitude': 28.6139,
222
+ 'longitude': 77.2090,
223
+ 'avg_feedback': 4.5,
224
+ 'popularity_score': 0.8,
225
+ 'is_available': True,
226
+ 'price_factor': 0.7
227
+ },
228
+ {
229
+ 'slot_id': 'B2',
230
+ 'latitude': 28.6150,
231
+ 'longitude': 77.2100,
232
+ 'avg_feedback': 3.2,
233
+ 'popularity_score': 0.4,
234
+ 'is_available': True,
235
+ 'price_factor': 0.5
236
+ },
237
+ {
238
+ 'slot_id': 'C3',
239
+ 'latitude': 28.6145,
240
+ 'longitude': 77.2095,
241
+ 'avg_feedback': 4.8,
242
+ 'popularity_score': 0.9,
243
+ 'is_available': True,
244
+ 'price_factor': 0.9
245
+ }
246
+ ]
247
+
248
+ user_location = (28.6139, 77.2090)
249
+ best_slots = classifier.predict_best_slots(test_slots, user_location, top_k=3)
250
+
251
+ print("\nTop 3 Recommended Slots:")
252
+ for i, slot in enumerate(best_slots, 1):
253
+ print(f"{i}. {slot['slot_id']} - Score: {slot['recommendation_score']:.3f}")
254
+
255
+ # Save model
256
+ classifier.save_model('parking_model.pkl')