Implementing ML in predicting the optimum NACA Airfoil parameters.
import pandas as pd
import numpy as np
import joblib
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score, mean_squared_error
from scipy.optimize import differential_evolution
=== Step 1: Load Excel Data ===
df = pd.read_excel(“airfoil_data.xlsx”)
Features and target
X = df[[‘m’, ‘p’, ‘t’]]
y = df[‘L/D’]
=== Step 2: Scale Data ===
scaler_X = StandardScaler()
scaler_y = StandardScaler()
X_scaled = scaler_X.fit_transform(X)
y_scaled = scaler_y.fit_transform(y.values.reshape(-1, 1)).ravel()
=== Step 3: Train Surrogate Model ===
model = RandomForestRegressor(n_estimators=200, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y_scaled, test_size=0.2, random_state=42)
model.fit(X_train, y_train)
y_pred_test = model.predict(X_test)
Evaluate model
print(“R² Score:”, r2_score(y_test, y_pred_test))
print(“MSE:”, mean_squared_error(y_test, y_pred_test))
=== Step 4: Save Model and Scalers (Optional) ===
joblib.dump(model, “surrogate_model.pkl”)
joblib.dump(scaler_X, “scaler_X.pkl”)
joblib.dump(scaler_y, “scaler_y.pkl”)
=== Step 5: Define Optimization Objective ===
def objective_function(x):
# x = [m, p, t]
x_scaled = scaler_X.transform([x])
y_pred_scaled = model.predict(x_scaled)
y_pred = scaler_y.inverse_transform(y_pred_scaled.reshape(-1, 1))[0][0]
return -y_pred # Negative because we minimize
=== Step 6: Define Parameter Bounds ===
bounds = [
(0.00, 0.09), # m: max camber
(0.10, 0.90), # p: camber position
(0.06, 0.18) # t: thickness
]
=== Step 7: Run Optimization ===
result = differential_evolution(
objective_function,
bounds,
strategy=’best1bin’,
maxiter=100,
popsize=15,
tol=1e-6,
seed=42
)
best_x = result.x
best_LD = -result.fun # Convert back to positive
print(“\n Optimal NACA Parameters:”)
print(f”m (max camber): {best_x[0]:.4f}”)
print(f”p (camber location): {best_x[1]:.4f}”)
print(f”t (thickness): {best_x[2]:.4f}”)
print(f”Predicted L/D: {best_LD:.2f}”)