Parth Budhale

Erstelle dein Portfolio mit ProoVErstelle dein Portfolio mit ProoV
ProoV
EN Verifiziertes Arbeitsportfolio

ProoV Portfolio

Parth Budhale

Computer Science AIML · Mumbai University

Zum ProoV-Leaderboard

Projekte

Zertifiziert

Selbstgesteuertes Projekt

Energy and Renewable: Machine Learning for the Power Grid

Junior Machine Learning Engineer · KI / ML · Juli 2026

78/ 100

Built a leakage-aware turbine yield predictor end to end: framed TEY as the target, excluded downstream CO/NOx emissions, compared a LinearRegression baseline with a tuned RandomForest, and evaluated on a locked later-period holdout. Reported honest held-out performance (about 1.5 MWh MAE, 1.94 RMSE, R2≈0.983) and documented limitations, drift risks, and a retraining trigger in a concise model card.

Bewertet nach

  • Build and validate the model correctly35%
  • Optimize and evaluate honestly25%
  • Write the Model Card (clarity + honesty)25%
  • Explain it to a non-expert15%

Bestanden · Bestehensgrenze 60/100

Was herausstach6
  • Correctly excluded CO and NOX as downstream emissions to avoid leakage
  • Used an earlier-years train / later-years test split instead of a random shuffle
  • Reported held-out MAE, RMSE, and R2 for the tuned model
  • Included a concrete monitoring trigger tied to rolling error and input distribution shift
  • Leakage-Free Feature Selection
  • Time-Based Holdout Evaluation
Meine eingereichte Arbeit11 Aufgaben

Problem Frame

Meine Lösung
{"target":"TEY","taskType":"regression","metric":"mae","intendedUse":"The team will read this number, and will determine how much the difference is","passed":true,"attempt":1}

Leakage Flags

Meine Lösung
{"excluded":["CO","NOX","TEY"],"kept":["AT","AP","AH","AFDP","GTEP","TIT","TAT","CDP"],"passed":true,"attempt":2}

Train Validate Baseline

Meine Lösung
{"checkpointId":"turbine-baseline","code":"import pandas as pd\nfrom sklearn.linear_model import LinearRegression\nfrom sklearn.metrics import mean_absolute_error, r2_score\n\ndf = pd.read_csv('gas_turbine.csv')\n\n# The 8 legitimate features. CO and NOX are dropped on purpose: both are\n# measured AFTER the turbine has already made its output, so you would not\n# have them yet at the moment you need to predict TEY.\nfeatures = ['AT', 'AP', 'AH', 'AFDP', 'GTEP', 'TIT', 'TAT', 'CDP']  # fill in the 8th feature\n\ntarget = 'TEY'\n\n# Time-based split: train on 2011-2013, test on 2014-2015.\n# Never shuffle a time-ordered stream at random. That would let the model\n# peek at rows from right next to the ones it gets tested on.\ntrain = df[df['year'] <= 2013]\ntest = df[df['year'] >= 2014]  # fill in: which year should testing start at?\n\nX_train, y_train = train[features], train[target]\nX_test, y_test = test[features], test[target]\n\nmodel = LinearRegression()\nmodel.fit(X_train, y_train)\npreds = model.predict(X_test)\n\nmae = mean_absolute_error(y_test, preds)\nr2 = r2_score(y_test, preds)\n\nprint(\"Baseline: Linear Regression\")\nprint(f\"MAE: {mae:.2f} MWh\")\nprint(f\"R2:  {r2:.3f}\")\n","stdout":"Baseline: Linear Regression\nMAE: 2.90 MWh\nR2:  0.957\n","stderr":"","error":null,"imageCount":0,"durationMs":3806,"ranAt":"2026-07-25T05:45:42.838Z"}

Train Validate Forest

Meine Lösung
{"checkpointId":"turbine-forest","code":"from sklearn.ensemble import RandomForestRegressor\n\n# Same 8 features, same target, same time-based split as Step 1. Only the\n# model changes: a forest of decision trees instead of one straight line.\nmodel_rf = RandomForestRegressor(n_estimators=120, max_depth=15, random_state=42)  # fill in the depth from the brief\nmodel_rf.fit(X_train, y_train)\npreds_rf = model_rf.predict(X_test)\n\nmae_rf = mean_absolute_error(y_test, preds_rf)\nr2_rf = r2_score(y_test, preds_rf)\n\nprint(\"Random Forest (n_estimators=120, max_depth=12)\")\nprint(f\"MAE: {mae_rf:.2f} MWh\")\nprint(f\"R2:  {r2_rf:.3f}\")\nprint(f\"Improvement vs baseline: {mae - mae_rf:.2f} MWh lower MAE\")\n","stdout":"Random Forest (n_estimators=120, max_depth=12)\nMAE: 1.53 MWh\nR2:  0.983\nImprovement vs baseline: 1.38 MWh lower MAE\n","stderr":"","error":null,"imageCount":0,"durationMs":4147,"ranAt":"2026-07-25T05:47:11.158Z"}

Train Validate

Meine Lösung
{"baselinePassed":true,"baselineMae":2.9,"baselineR2":0.957,"rfPassed":true,"rfMae":1.53,"rfR2":0.983,"improvementMae":1.37}

Tune Evaluate Setup

Meine Lösung
{"checkpointId":"tune_evaluate_setup","code":"import pandas as pd\nimport numpy as np\nfrom sklearn.ensemble import RandomForestRegressor\nfrom sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score\n\ndf = pd.read_csv('gas_turbine.csv')\n\nFEATURES = ['AT', 'AP', 'AH', 'AFDP', 'GTEP', 'TIT', 'TAT', 'CDP']\nTARGET = 'TEY'\n\n# Time-based split: train on the earlier years, lock the latest year away as test.\ntrain = df[df['year'] <= 2013]\ntest = df[df['year'] >= 2014]\n\nX_train, y_train = train[FEATURES], train[TARGET]\nX_test, y_test = test[FEATURES], test[TARGET]\n\n# These starter values are deliberately modest. Judge every change ONLY on the\n# held-out numbers printed below, never on how the model looks on training data.\nn_estimators = 125\nmax_depth = 12\n\nmodel = RandomForestRegressor(\n    n_estimators=n_estimators,\n    max_depth=max_depth,\n    random_state=42,\n)\nmodel.fit(X_train, y_train)\npreds = model.predict(X_test)\n\nmae = mean_absolute_error(y_test, preds)\nrmse = mean_squared_error(y_test, preds) ** 0.5\nr2 = r2_score(y_test, preds)\n\nprint(f\"n_estimators={n_estimators}  max_depth={max_depth}\")\nprint(f\"Held-out MAE:  {mae:.3f} MWh\")\nprint(f\"Held-out RMSE: {rmse:.3f}\")\nprint(f\"Held-out R2:   {r2:.4f}\")\n","stdout":"n_estimators=125  max_depth=12\nHeld-out MAE:  1.532 MWh\nHeld-out RMSE: 1.937\nHeld-out R2:   0.9833\n","stderr":"","error":null,"imageCount":0,"durationMs":3510,"ranAt":"2026-07-25T05:51:00.139Z"}

Tune Evaluate Residuals

Meine Lösung
{"checkpointId":"tune_evaluate_residuals","code":"preds = model.predict(X_test)\nresid = y_test.values - preds  # true TEY minus predicted TEY, in MWh\n\nprint(f\"Residual mean: {resid.mean():.3f} MWh\")\nprint(f\"Residual std:  {resid.std():.3f} MWh\")\n\n# A quick text histogram: how spread out are the misses across the held-out year?\ncounts, edges = np.histogram(resid, bins=8)\nfor c, lo, hi in zip(counts, edges[:-1], edges[1:]):\n    print(f\"{lo:6.2f} to {hi:6.2f} MWh | \" + \"#\" * c)\n","stdout":"Residual mean: 1.116 MWh\nResidual std:  1.583 MWh\n -8.49 to  -6.54 MWh | ##\n -6.54 to  -4.60 MWh | ##########\n -4.60 to  -2.65 MWh | ##################################\n -2.65 to  -0.70 MWh | ########################################################################################################################################################################################################################################################################################################################\n -0.70 to   1.24 MWh | #########################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################\n  1.24 to   3.19 MWh | ##########################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################\n  3.19 to   5.14 MWh | ########################
…

Tune Evaluate

Meine Lösung
{"nEstimators":125,"maxDepth":12,"heldOutMAE":1.532,"heldOutRMSE":1.937,"heldOutR2":0.9833,"residualMean":1.116,"residualStd":1.583}

Residual Read

Meine Lösung
{"category":"heteroscedastic","sentence":"while the MAE and RMSE shows my overall avg performance, they hide the fact that the model becomes much less reliable when the turbine starts to operate at heavy loads","passed":true,"attempt":1}

Drift Monitor

Meine Lösung
{"monitorSignal":"distribution","retrainThreshold":4,"exploredDriftC":32,"observedMae":1.5}

Model Card

Meine Lösung
{"predicts":"Predicts Turbine Energy Yield (TEY) in Megawatt-hours (MWh).","features":"Includes 8 intake and pre-combustion sensors(AT,AP,AH,AFDP,GTEP,TIT,TAT,CDP). Excludes downstream emissions (CO and NOX) to prevent data leakage, as those readings are unavailable at prediction time.","accuracy":"Achieved MAE of approx 1.5 MWh on unseen held-out data.","limits":"Model accuracy decreases significantly at higher loads. As a tree-based model, it cannot extrapolate beyond its trained input distribution and will fail silently if it encounters extreme out of range sensor readings.","monitor":"We will monitor the input distribution for out of bounds sensor readings and tack the rolling mean absolute error as real telemetry arrives. A retrain will be triggered if the rolling error crosses the 4 MWh limit of if live inputs consistently shift outside the original training data range.","hits":{"predicts":true,"features":true,"accuracy":true,"limits":true,"monitor":true},"passed":true,"attempt":1}
Verifiziertes ZertifikatFälschungssicher · ausgestellt von ProoV
1Abgeschlossenes Projekt
1Verifiziertes Zertifikat
78Durchschnittsnote
Erstelle dein Portfolio mit ProoV