PickEngine / app /utils.py
shubhendu-ghosh's picture
Upload 2 files
11042a4 verified
import joblib
# Appliance-wise configuration
APPLIANCE_CONFIG = {
'ac': {
'model_path': 'models/ac_knn_model.pkl',
'encoder_path': 'models/ac_encoders.pkl',
'features_path': 'models/ac_features.pkl',
'feature_order': ['ratings', 'actual_price', 'brand', 'power', 'star', 'inverter'],
},
'tv': {
'model_path': 'models/tv_knn_model.pkl',
'encoder_path': 'models/tv_encoders.pkl',
'features_path': 'models/tv_features.pkl',
'feature_order': ['ratings', 'actual_price', 'brand', 'length', 'LED', 'smart', 'ultra_hd'],
},
'fridge': {
'model_path': 'models/fridge_knn_model.pkl',
'encoder_path': 'models/fridge_encoders.pkl',
'features_path': 'models/fridge_features.pkl',
'feature_order': ['ratings', 'actual_price', 'brand', 'capacity', 'energy_star', 'door', 'cooling_tech'],
},
'wash': {
'model_path': 'models/wash_knn_model.pkl',
'encoder_path': 'models/wash_encoders.pkl',
'features_path': 'models/wash_features.pkl',
'feature_order': ['ratings', 'actual_price', 'brand', 'weight', 'load', 'energy_star'],
}
}
# Load everything at startup
loaded_models = {}
for appliance, config in APPLIANCE_CONFIG.items():
loaded_models[appliance] = {
'model': joblib.load(config['model_path']),
'encoders': joblib.load(config['encoder_path']),
'features': joblib.load(config['features_path']),
}
def recommend_product(input_dict, appliance):
model = loaded_models[appliance]['model']
encoders = loaded_models[appliance]['encoders']
train_features = loaded_models[appliance]['features']
# Preprocess input
#processed = preprocess_single_product(input_dict, appliance, encoders)
# Create input vector for KNN model based on feature order
feature_order = {
"ac": ['ratings', 'actual_price', 'brand', 'power', 'star', 'inverter'],
"tv": ['ratings', 'actual_price', 'brand', 'length', 'LED', 'smart', 'ultra_hd'],
"fridge": ['ratings', 'actual_price', 'brand', 'capacity', 'energy_star', 'door', 'cooling_tech'],
"wash": ['ratings', 'actual_price', 'brand', 'weight', 'load', 'energy_star']
}
feature_vector = [input_dict.get(key, 0.0) for key in feature_order[appliance]]
# Predict
distances, indices = model.kneighbors([feature_vector], n_neighbors=6)
recommendations = train_features.iloc[indices[0][1:]].copy()
return recommendations
def preprocess_single_product(input_dict: dict, appliance: str) -> dict:
processed = input_dict.copy()
# Appliance-specific label encoding
appliance_encoding_cols = {
"ac": ['brand', 'power', 'star', 'inverter'],
"tv": ['brand'],
"fridge": ['brand', 'door', 'cooling_tech'],
"wash": ['brand', 'load']
}
model_data = loaded_models[appliance]
label_encoders = model_data['encoders']
encoding_cols = appliance_encoding_cols.get(appliance.lower(), [])
for col in encoding_cols:
value = processed.get(col)
if value is not None:
le = label_encoders.get(col)
if le:
try:
processed[col] = int(le.transform([str(value)])[0])
except ValueError:
# If unseen label, fallback to 0 or similar safe default
processed[col] = 0
else:
processed[col] = 0 # fallback if encoder is missing
else:
processed[col] = 0 # fallback if value is missing
return processed