Talha415/synethic_cable
0
1# ========================================2# Cable Recommendation System for Hugging Face3# ========================================4 5import os6import pandas as pd7import numpy as np8from sklearn.model_selection import train_test_split9from sklearn.preprocessing import LabelEncoder10from xgboost import XGBClassifier, XGBRegressor11import joblib12import gradio as gr13 14# ------------------------------15# 1. Load dataset (CSV in repo)16# ------------------------------17csv_path = os.path.join(os.path.dirname(__file__), "synthetic_cable_layout_with_engineers_estimate.csv")18 19if not os.path.exists(csv_path):20 raise FileNotFoundError(21 f"โ CSV file not found at {csv_path}. "22 f"Please upload 'synthetic_cable_layout_with_engineers_estimate.csv' to your Hugging Face Space."23 )24 25df = pd.read_csv(csv_path)26 27# Normalize column names28df.columns = [c.strip().lower() for c in df.columns]29 30# Map dataset columns31col_map = {32 "length": "length_m",33 "distance_m": "length_m",34 "voltage (v)": "voltage_v",35 "voltage_v": "voltage_v",36 "load_kw": "load_kw",37 "load (kw)": "load_kw",38 "material": "material",39 "recommended_cable_size_mm2": "recommended_cable_size_mm2",40 "calculated_current_a": "calculated_current_a",41 "voltage_drop_%": "voltage_drop_pct",42 "voltage_drop_pct": "voltage_drop_pct",43 "is_optimal": "is_optimal",44 "engineer_estimate_1core_cost_per_m": "engineer_estimate_1core_cost_per_m",45 "engineer_estimate_4core_cost_per_m": "engineer_estimate_4core_cost_per_m",46}47df = df.rename(columns={k: v for k, v in col_map.items() if k in df.columns})48 49# ------------------------------50# 2. Encode categorical features51# ------------------------------52le_material = LabelEncoder()53df["material_code"] = le_material.fit_transform(df["material"])54 55le_size = LabelEncoder()56df["size_code"] = le_size.fit_transform(df["recommended_cable_size_mm2"].astype(str))57 58# ------------------------------59# 3. Features & Targets60# ------------------------------61feature_cols = ["length_m", "load_kw", "voltage_v", "material_code"]62X = df[feature_cols]63 64y_size = df["size_code"]65y_current = df["calculated_current_a"]66y_drop = df["voltage_drop_pct"]67y_optimal = df["is_optimal"].apply(lambda x: 1 if str(x).lower() in ["yes", "1", "true"] else 0)68 69# Train-test split70X_train, X_test, y_size_train, y_size_test = train_test_split(X, y_size, test_size=0.2, random_state=42)71_, _, y_current_train, y_current_test = train_test_split(X, y_current, test_size=0.2, random_state=42)72_, _, y_drop_train, y_drop_test = train_test_split(X, y_drop, test_size=0.2, random_state=42)73_, _, y_optimal_train, y_optimal_test = train_test_split(X, y_optimal, test_size=0.2, random_state=42)74 75# ------------------------------76# 4. Train models77# ------------------------------78model_size = XGBClassifier(use_label_encoder=False, eval_metric="mlogloss", n_estimators=50)79model_size.fit(X_train, y_size_train)80 81model_current = XGBRegressor(n_estimators=50)82model_current.fit(X_train, y_current_train)83 84model_drop = XGBRegressor(n_estimators=50)85model_drop.fit(X_train, y_drop_train)86 87model_optimal = XGBClassifier(use_label_encoder=False, eval_metric="logloss", n_estimators=50)88model_optimal.fit(X_train, y_optimal_train)89 90# ------------------------------91# 5. Cost Lookup Table92# ------------------------------93cost_lookup = {}94for _, row in df.iterrows():95 key_1 = (str(row["recommended_cable_size_mm2"]), "1", row["material"])96 key_4 = (str(row["recommended_cable_size_mm2"]), "4", row["material"])97 cost_lookup[key_1] = row.get("engineer_estimate_1core_cost_per_m", np.nan)98 cost_lookup[key_4] = row.get("engineer_estimate_4core_cost_per_m", np.nan)99 100# ------------------------------101# 6. Save models & encoders102# ------------------------------103models = {104 "size": model_size,105 "current": model_current,106 "drop": model_drop,107 "optimal": model_optimal,108 "le_material": le_material,109 "le_size": le_size,110 "cost_lookup": cost_lookup,111}112joblib.dump(models, "cable_model.pkl")113 114# ------------------------------115# 7. Gradio Interface116# ------------------------------117def recommend_cable(voltage, load_kw, length_m, material, cores):118 mat_code = le_material.transform([material])[0]119 X_in = np.array([[length_m, load_kw, voltage, mat_code]])120 121 size_code = model_size.predict(X_in)[0]122 size_mm2 = le_size.inverse_transform([size_code])[0]123 current = model_current.predict(X_in)[0]124 drop = model_drop.predict(X_in)[0]125 opt = model_optimal.predict(X_in)[0]126 127 # Cost lookup128 cost_per_m = cost_lookup.get((str(size_mm2), str(cores), material), np.nan)129 total = cost_per_m * length_m if not np.isnan(cost_per_m) else None130 131 return (132 f"๐ Cable Recommendation ({material})\n\n"133 f"๐น Recommended Size: {size_mm2} mmยฒ ({cores}-Core)\n"134 f"๐น Required Current: {current:.1f} A\n"135 f"๐น Voltage Drop: {drop:.2f}%\n"136 f"๐น Is Optimal: {'โ
Yes' if opt==1 else 'โ No'}\n"137 f"๐น Cost per meter: {'PKR ' + str(int(cost_per_m)) if cost_per_m else 'Not available'}\n"138 f"๐น Total Cost ({length_m} m): {'PKR ' + format(int(total), ',') if total else 'Not available'}"139 )140 141demo = gr.Interface(142 fn=recommend_cable,143 inputs=[144 gr.Number(label="Voltage (V)"),145 gr.Number(label="Load (kW)"),146 gr.Number(label="Length (m)"),147 gr.Dropdown(["Copper", "Aluminium"], label="Material"),148 gr.Dropdown(["1", "4"], label="Cores"),149 ],150 outputs=gr.Textbox(label="Cable Recommendation"),151 title="โก Cable Size Recommendation System",152 description="Enter parameters to get recommended cable size, performance, and cost.",153)154 155demo.launch()