1
Pasted Nov 2, 2026, 1:34 PM·10 files·1,174 lines
Scan to open on your phone
Point a camera at the QR code - it opens this exact paste, no app needed.
https://codepastes.com/hello1Python
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.impute import SimpleImputer
# Sample open-access style dataset (HR/Employee Attrition style)
data = {
'Age': [25, 32, np.nan, 45, 29, 38, np.nan, 51],
'Department': ['Sales', 'IT', 'HR', 'IT', 'Sales', np.nan, 'HR', 'IT'],
'Salary': [40000, 55000, 48000, np.nan, 42000, 60000, 47000, 72000],
'YearsExperience': [1, 5, 3, 12, 2, 8, 4, 15],
'Attrition': ['Yes', 'No', 'No', 'No', 'Yes', 'No', 'Yes', 'No']
}
# Create DataFrame
df = pd.DataFrame(data)
print("Original Dataset:\n")
print(df)
print("\nMissing values per column:\n")
print(df.isnull().sum())
# -------------------------------------------------
# Step 1: Handle Missing Values
# -------------------------------------------------
# Numerical columns - Mean Imputation
num_imputer = SimpleImputer(strategy='mean')
df['Age'] = num_imputer.fit_transform(df[['Age']])
df['Salary'] = num_imputer.fit_transform(df[['Salary']])
# Categorical column - Most Frequent Imputation
cat_imputer = SimpleImputer(strategy='most_frequent')
df['Department'] = cat_imputer.fit_transform(df[['Department']]).ravel()
print("\nAfter Handling Missing Values:\n")
print(df)
# -------------------------------------------------
# Step 2: Encode Categorical Variables
# -------------------------------------------------
# Label Encoding for Target Variable
le = LabelEncoder()
df['Attrition_Encoded'] = le.fit_transform(df['Attrition'])
# One-Hot Encoding for Department
df_encoded = pd.get_dummies(
df,
columns=['Department'],
prefix='Dept'
)
print("\nAfter One-Hot Encoding 'Department':\n")
print(df_encoded)
# -------------------------------------------------
# Step 3: Feature Scaling
# -------------------------------------------------
scaler = StandardScaler()
num_cols = ['Age', 'Salary', 'YearsExperience']
df_encoded[num_cols] = scaler.fit_transform(df_encoded[num_cols])
print("\nAfter Feature Scaling (Standardization):\n")
print(df_encoded[num_cols].round(3))
print("\nFinal Model-Ready Dataset Shape:", df_encoded.shape)2Python
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from sklearn.datasets import load_wine
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
import time
import os
# Create directory if it doesn't exist
os.makedirs("imgs", exist_ok=True)
# Load dataset
wine = load_wine()
X, y = wine.data, wine.target
print("Dataset shape:", X.shape, " Classes:", np.unique(y))
# Standardize features
X_scaled = StandardScaler().fit_transform(X)
# Train-test split
X_train, X_test, y_train, y_test = train_test_split(
X_scaled, y, test_size=0.3, random_state=42
)
# -----------------------------
# Baseline (All 13 Features)
# -----------------------------
t0 = time.time()
clf = LogisticRegression(max_iter=1000)
clf.fit(X_train, y_train)
acc_full = accuracy_score(y_test, clf.predict(X_test))
t_full = time.time() - t0
# -----------------------------
# PCA (2 Components)
# -----------------------------
pca = PCA(n_components=2)
X_train_pca = pca.fit_transform(X_train)
X_test_pca = pca.transform(X_test)
t0 = time.time()
clf_pca = LogisticRegression(max_iter=1000)
clf_pca.fit(X_train_pca, y_train)
acc_pca = accuracy_score(y_test, clf_pca.predict(X_test_pca))
t_pca = time.time() - t0
print("\nPCA Explained Variance Ratio (2 components):")
print(pca.explained_variance_ratio_)
print(f"Total variance retained: {sum(pca.explained_variance_ratio_) * 100:.2f}%")
# -----------------------------
# LDA (2 Components)
# -----------------------------
lda = LinearDiscriminantAnalysis(n_components=2)
X_train_lda = lda.fit_transform(X_train, y_train)
X_test_lda = lda.transform(X_test)
t0 = time.time()
clf_lda = LogisticRegression(max_iter=1000)
clf_lda.fit(X_train_lda, y_train)
acc_lda = accuracy_score(y_test, clf_lda.predict(X_test_lda))
t_lda = time.time() - t0
# -----------------------------
# Results
# -----------------------------
print(f"\nAccuracy with all 13 features : {acc_full:.4f} (train time: {t_full*1000:.2f} ms)")
print(f"Accuracy with PCA (2 comp) : {acc_pca:.4f} (train time: {t_pca*1000:.2f} ms)")
print(f"Accuracy with LDA (2 comp) : {acc_lda:.4f} (train time: {t_lda*1000:.2f} ms)")
# -----------------------------
# Visualization
# -----------------------------
fig, axs = plt.subplots(1, 2, figsize=(11, 4.5))
colors = ['#4C72B0', '#DD8452', '#55A868']
for target, color, label in zip([0, 1, 2], colors, wine.target_names):
axs[0].scatter(
X_train_pca[y_train == target, 0],
X_train_pca[y_train == target, 1],
c=color,
label=label,
s=25
)
axs[1].scatter(
X_train_lda[y_train == target, 0],
X_train_lda[y_train == target, 1],
c=color,
label=label,
s=25
)
axs[0].set_title("PCA - Wine Dataset (2 Components)")
axs[0].set_xlabel("PC1")
axs[0].set_ylabel("PC2")
axs[0].legend()
axs[1].set_title("LDA - Wine Dataset (2 Components)")
axs[1].set_xlabel("LD1")
axs[1].set_ylabel("LD2")
axs[1].legend()
plt.tight_layout()
plt.savefig("imgs/a2_pca_lda.png", dpi=130)
print("\nPlot saved as imgs/a2_pca_lda.png")3Python
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# Load dataset
diabetes = load_diabetes(as_frame=True)
X = diabetes.data
y = diabetes.target
print("Features:", list(X.columns))
print("Dataset shape:", X.shape)
print(X.head(), "\n")
# Split dataset
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42
)
# Create and train model
model = LinearRegression()
model.fit(X_train, y_train)
# Predict
y_pred = model.predict(X_test)
# Evaluation metrics
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)
# Print coefficients
print("Model Coefficients:")
for feature, coefficient in zip(X.columns, model.coef_):
print(f"{feature:>6}: {coefficient:8.3f}")
print(f"Intercept: {model.intercept_:.3f}\n")
print(f"MSE : {mse:.3f}")
print(f"RMSE : {rmse:.3f}")
print(f"R2 : {r2:.4f}")
# Plot Actual vs Predicted
plt.figure(figsize=(6, 5))
plt.scatter(
y_test,
y_pred,
alpha=0.7,
color="#4C72B0",
edgecolor="k"
)
plt.plot(
[y.min(), y.max()],
[y.min(), y.max()],
"r--",
lw=2
)
plt.xlabel("Actual Disease Progression")
plt.ylabel("Predicted Disease Progression")
plt.title("Multiple Linear Regression: Actual vs Predicted")
plt.tight_layout()
plt.savefig("imgs/a3_mlr.png", dpi=130)
print("\nPlot saved.")4Python
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
# Generate synthetic data
np.random.seed(42)
X = np.sort(np.random.rand(80, 1) * 10, axis=0)
y = 0.5 * X.ravel()**2 - 2 * X.ravel() + 5 + np.random.randn(80) * 3
# Split into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
degrees = [1, 2, 4, 8]
# Plot training data
plt.figure(figsize=(7, 5))
plt.scatter(
X_train,
y_train,
color='gray',
s=20,
label='Train data',
alpha=0.6
)
# Points for plotting regression curves
X_plot = np.linspace(0, 10, 200).reshape(-1, 1)
print(f"{'Degree':>7} | {'Train R2':>9} | {'Test R2':>8} | {'Test RMSE':>10}")
print("-" * 45)
# Train polynomial regression models of different degrees
for d in degrees:
poly = PolynomialFeatures(degree=d)
X_train_p = poly.fit_transform(X_train)
X_test_p = poly.transform(X_test)
lr = LinearRegression()
lr.fit(X_train_p, y_train)
train_r2 = r2_score(y_train, lr.predict(X_train_p))
test_pred = lr.predict(X_test_p)
test_r2 = r2_score(y_test, test_pred)
test_rmse = np.sqrt(mean_squared_error(y_test, test_pred))
print(
f"{d:>7} | {train_r2:>9.4f} | {test_r2:>8.4f} | {test_rmse:>10.3f}"
)
# Plot fitted curve
y_plot = lr.predict(poly.transform(X_plot))
plt.plot(X_plot, y_plot, label=f'Degree {d}', linewidth=2)
# Finalize plot
plt.xlabel('X')
plt.ylabel('y')
plt.title('Polynomial Regression: Bias-Variance Trade-off')
plt.legend()
plt.tight_layout()
# Save figure
plt.savefig('imgs/a4_poly.png', dpi=130)
# Observation
print("\nObservation:")
print("Degree 1 underfits (high bias).")
print(
"Degree 8 starts overfitting (high variance), "
"so the test R² drops relative to degrees 2–4 "
"despite having a higher training R²."
)5Python
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, r2_score
# Load the Diabetes dataset
diabetes = load_diabetes(as_frame=True)
X, y = diabetes.data, diabetes.target
# Split the dataset
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42
)
# Standardize the features
scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train)
X_test_s = scaler.transform(X_test)
# Define models
models = {
"Linear Regression": LinearRegression(),
"Ridge (alpha=1.0)": Ridge(alpha=1.0),
"Lasso (alpha=2.0)": Lasso(alpha=2.0)
}
print(
f"{'Model':<20} | {'R2':>8} | {'RMSE':>8} | {'Non-zero coefs':>15}"
)
print("-" * 62)
results = {}
# Train and evaluate each model
for name, model in models.items():
model.fit(X_train_s, y_train)
pred = model.predict(X_test_s)
r2 = r2_score(y_test, pred)
rmse = np.sqrt(mean_squared_error(y_test, pred))
nz = np.sum(np.abs(model.coef_) > 1e-4)
results[name] = model.coef_
print(
f"{name:<20} | {r2:>8.4f} | {rmse:>8.3f} | {nz:>15}"
)
# Display coefficient comparison
print("\nCoefficient comparison (feature shrinkage):")
print(
f"{'Feature':<10}"
+ "".join(f"{name[:12]:>15}" for name in models)
)
for i, feat in enumerate(X.columns):
row = f"{feat:<10}"
for name in models:
row += f"{results[name][i]:>15.2f}"
print(row)
# Plot coefficients
fig, ax = plt.subplots(figsize=(9, 5))
x = np.arange(len(X.columns))
width = 0.25
for i, (name, coefs) in enumerate(results.items()):
ax.bar(x + i * width, coefs, width, label=name)
ax.set_xticks(x + width)
ax.set_xticklabels(X.columns)
ax.set_ylabel("Coefficient value")
ax.set_title("Ridge vs Lasso: Coefficient Shrinkage (Diabetes Dataset)")
ax.legend()
ax.axhline(0, color="black", linewidth=0.8)
plt.tight_layout()
# Save the figure
plt.savefig("imgs/a5_ridge_lasso.png", dpi=130)
# Observation
print("\nObservation:")
print(
"Lasso drives several coefficients to exactly zero "
"(performing feature selection)."
)
print(
"Ridge shrinks all coefficients toward zero but keeps "
"them non-zero, helping reduce the impact of multicollinearity."
)6Python
import numpy as np
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import (
confusion_matrix,
precision_score,
recall_score,
f1_score,
accuracy_score,
classification_report,
)
# -----------------------------
# Load Dataset
# -----------------------------
data = load_breast_cancer()
X, y = data.data, data.target
print("Dataset shape:", X.shape)
print("Classes:", data.target_names)
# -----------------------------
# Split Dataset
# -----------------------------
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.25,
random_state=42,
stratify=y,
)
# -----------------------------
# Feature Scaling
# -----------------------------
scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train)
X_test_s = scaler.transform(X_test)
# -----------------------------
# Train Logistic Regression Model
# -----------------------------
model = LogisticRegression(max_iter=5000)
model.fit(X_train_s, y_train)
# -----------------------------
# Predictions
# -----------------------------
y_pred = model.predict(X_test_s)
# -----------------------------
# Performance Metrics
# -----------------------------
cm = confusion_matrix(y_test, y_pred)
acc = accuracy_score(y_test, y_pred)
prec = precision_score(y_test, y_pred)
rec = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)
print("\nConfusion Matrix:\n")
print(cm)
print(f"\nAccuracy : {acc:.4f}")
print(f"Precision : {prec:.4f}")
print(f"Recall : {rec:.4f}")
print(f"F1-score : {f1:.4f}")
print("\nClassification Report:\n")
print(
classification_report(
y_test,
y_pred,
target_names=data.target_names,
)
)
# -----------------------------
# Plot Confusion Matrix
# -----------------------------
fig, ax = plt.subplots(figsize=(5, 4.5))
im = ax.imshow(cm, cmap="Blues")
for i in range(2):
for j in range(2):
ax.text(
j,
i,
cm[i, j],
ha="center",
va="center",
color="black",
fontsize=14,
)
ax.set_xticks([0, 1])
ax.set_yticks([0, 1])
ax.set_xticklabels(data.target_names)
ax.set_yticklabels(data.target_names)
ax.set_xlabel("Predicted")
ax.set_ylabel("Actual")
ax.set_title(
"Confusion Matrix - Logistic Regression\n"
"(Breast Cancer Dataset)"
)
plt.colorbar(im)
plt.tight_layout()
plt.savefig("imgs/a6_logreg_cm.png", dpi=130)
print("\nPlot saved.")7Python
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, classification_report
# Load Iris dataset
iris = load_iris()
X = iris.data[:, [2, 3]] # Petal length & width for 2D visualization
y = iris.target
# Train-test split
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.25,
random_state=42,
stratify=y
)
# Feature scaling
scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train)
X_test_s = scaler.transform(X_test)
# SVM kernels
kernels = ['linear', 'rbf', 'poly']
results = {}
print(f"{'Kernel':<10} | {'Accuracy':>9}")
print("-" * 23)
# Train and evaluate models
for k in kernels:
clf = SVC(kernel=k, C=1.0, gamma='scale')
clf.fit(X_train_s, y_train)
acc = accuracy_score(y_test, clf.predict(X_test_s))
results[k] = (clf, acc)
print(f"{k:<10} | {acc:>9.4f}")
# Create decision boundary plots
fig, axs = plt.subplots(1, 3, figsize=(15, 4.5))
xx, yy = np.meshgrid(
np.linspace(X_train_s[:, 0].min() - 1, X_train_s[:, 0].max() + 1, 200),
np.linspace(X_train_s[:, 1].min() - 1, X_train_s[:, 1].max() + 1, 200)
)
for ax, k in zip(axs, kernels):
clf, acc = results[k]
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
ax.contourf(xx, yy, Z, alpha=0.3, cmap='viridis')
ax.scatter(
X_train_s[:, 0],
X_train_s[:, 1],
c=y_train,
cmap='viridis',
edgecolor='k',
s=25
)
ax.set_title(f"SVM ({k} kernel)\nAccuracy: {acc:.2f}")
ax.set_xlabel("Petal length (scaled)")
ax.set_ylabel("Petal width (scaled)")
plt.tight_layout()
plt.savefig("imgs/a7_svm.png", dpi=130)
# Display best kernel
print("\nBest kernel:", max(results, key=lambda k: results[k][1]))
# Classification report for RBF kernel
print(
"\nClassification Report (RBF kernel):\n",
classification_report(
y_test,
results['rbf'][0].predict(X_test_s),
target_names=iris.target_names
)
)8Python
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
# Load Iris dataset
iris = load_iris()
X = iris.data
# Standardize the features
X_scaled = StandardScaler().fit_transform(X)
# Lists to store results
wcss = []
sil_scores = []
K_range = range(2, 9)
# Train K-Means for different values of k
for k in K_range:
km = KMeans(
n_clusters=k,
random_state=42,
n_init=10
)
labels = km.fit_predict(X_scaled)
wcss.append(km.inertia_)
sil_scores.append(silhouette_score(X_scaled, labels))
# Display results
print(f"{'k':>3} | {'WCSS (Inertia)':>15} | {'Silhouette Score':>17}")
print("-" * 40)
for k, w, s in zip(K_range, wcss, sil_scores):
print(f"{k:>3} | {w:>15.3f} | {s:>17.4f}")
# Best k based on silhouette score
best_k = list(K_range)[np.argmax(sil_scores)]
print(f"\nOptimal k (highest silhouette score) = {best_k}")
# Final K-Means model
km_final = KMeans(
n_clusters=best_k,
random_state=42,
n_init=10
)
labels_final = km_final.fit_predict(X_scaled)
# Create plots
fig, axs = plt.subplots(1, 3, figsize=(15, 4.5))
# Elbow Method
axs[0].plot(
list(K_range),
wcss,
'o-',
color='#4C72B0'
)
axs[0].set_xlabel('Number of clusters (k)')
axs[0].set_ylabel('WCSS')
axs[0].set_title('Elbow Method')
# Silhouette Method
axs[1].plot(
list(K_range),
sil_scores,
'o-',
color='#DD8452'
)
axs[1].set_xlabel('Number of clusters (k)')
axs[1].set_ylabel('Silhouette Score')
axs[1].set_title('Silhouette Method')
# Cluster Visualization
scatter = axs[2].scatter(
X[:, 2],
X[:, 3],
c=labels_final,
cmap='viridis',
s=30,
edgecolor='k'
)
axs[2].set_xlabel('Petal length')
axs[2].set_ylabel('Petal width')
axs[2].set_title(f'K-Means Clusters (k={best_k})')
plt.tight_layout()
plt.savefig('imgs/a8_kmeans.png', dpi=130)
print("\nPlot saved.")9Python
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import DBSCAN, KMeans
from sklearn.metrics import silhouette_score
# Generate synthetic dataset
X, y_true = make_moons(
n_samples=300,
noise=0.08,
random_state=42
)
# Standardize the data
X_scaled = StandardScaler().fit_transform(X)
# Apply DBSCAN
dbscan = DBSCAN(eps=0.25, min_samples=5)
labels = dbscan.fit_predict(X_scaled)
# Count clusters and noise points
n_clusters = len(set(labels)) - (1 if -1 in labels else 0)
n_noise = list(labels).count(-1)
print(f"Estimated number of clusters: {n_clusters}")
print(f"Estimated number of noise points: {n_noise}")
# Calculate Silhouette Score
if n_clusters > 1:
sil = silhouette_score(X_scaled, labels)
print(f"Silhouette Score: {sil:.4f}")
# Apply K-Means for comparison
km = KMeans(
n_clusters=2,
random_state=42,
n_init=10
)
km.fit(X_scaled)
# Create plots
fig, axs = plt.subplots(1, 2, figsize=(11, 4.5))
# K-Means plot
axs[0].scatter(
X[:, 0],
X[:, 1],
c=km.labels_,
cmap='viridis',
s=25,
edgecolor='k'
)
axs[0].set_title('K-Means (fails on non-convex shapes)')
# DBSCAN plot
axs[1].scatter(
X[:, 0],
X[:, 1],
c=labels,
cmap='viridis',
s=25,
edgecolor='k'
)
# Highlight noise points
noise_mask = labels == -1
axs[1].scatter(
X[noise_mask, 0],
X[noise_mask, 1],
c='red',
marker='x',
s=40,
label='Noise'
)
axs[1].set_title(
f'DBSCAN (clusters={n_clusters}, noise={n_noise})'
)
axs[1].legend()
# Save figure
plt.tight_layout()
plt.savefig('imgs/a9_dbscan.png', dpi=130)
# Observation
print("\nObservation:")
print("DBSCAN correctly separates the two crescent (non-convex) clusters and")
print("flags outliers as noise, while K-Means (assumes spherical clusters)")
print("fails on this shape.")10&11Python
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import (
RandomForestClassifier,
GradientBoostingClassifier
)
from sklearn.metrics import accuracy_score, f1_score
# Load dataset
data = load_breast_cancer()
X, y = data.data, data.target
# Split dataset
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.25,
random_state=42,
stratify=y
)
# Define models
models = {
"Decision Tree (baseline)": DecisionTreeClassifier(
random_state=42
),
"Random Forest (100 trees)": RandomForestClassifier(
n_estimators=100,
random_state=42
),
"Gradient Boosting": GradientBoostingClassifier(
random_state=42
)
}
# Train and evaluate
print(f"{'Model':<28} | {'Accuracy':>9} | {'F1-score':>9}")
print("-" * 52)
accs = {}
for name, model in models.items():
model.fit(X_train, y_train)
pred = model.predict(X_test)
acc = accuracy_score(y_test, pred)
f1 = f1_score(y_test, pred)
accs[name] = acc
print(f"{name:<28} | {acc:>9.4f} | {f1:>9.4f}")
# Feature importance from Random Forest
rf = models["Random Forest (100 trees)"]
importances = rf.feature_importances_
# Top 10 important features
idx = np.argsort(importances)[-10:]
# Plot results
fig, axs = plt.subplots(1, 2, figsize=(12, 5))
# Feature importance chart
axs[0].barh(
range(len(idx)),
importances[idx],
color="#55A868"
)
axs[0].set_yticks(range(len(idx)))
axs[0].set_yticklabels(
[data.feature_names[i] for i in idx]
)
axs[0].set_xlabel("Feature Importance")
axs[0].set_title("Random Forest: Top 10 Important Features")
# Accuracy comparison chart
axs[1].bar(
list(accs.keys()),
list(accs.values()),
color=["#C44E52", "#4C72B0", "#DD8452"]
)
axs[1].set_ylabel("Accuracy")
axs[1].set_ylim(0.85, 1.0)
axs[1].set_title("Baseline vs Ensemble Comparison")
plt.setp(
axs[1].get_xticklabels(),
rotation=15,
ha="right"
)
plt.tight_layout()
plt.savefig("imgs/a10_ensemble.png", dpi=130)
# Observation
print("\nObservation:")
print(
"Both ensemble methods (Random Forest and Gradient Boosting) "
"outperform the single Decision Tree baseline."
)
print(
"Random Forest improves performance by reducing variance "
"through bagging, while Gradient Boosting reduces bias "
"by sequentially improving weak learners."
)
# Practical 11
import numpy as np
import random
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
# --------------------------------------------------
# Simple Grid World
# 4x4 grid
# Agent starts at (0,0)
# Goal at (3,3)
# Obstacle at (1,1)
# --------------------------------------------------
GRID_SIZE = 4
GOAL = (3, 3)
OBSTACLE = (1, 1)
ACTIONS = ["UP", "DOWN", "LEFT", "RIGHT"]
ACTION_EFFECTS = {
"UP": (-1, 0),
"DOWN": (1, 0),
"LEFT": (0, -1),
"RIGHT": (0, 1)
}
# Q-table
Q = np.zeros((GRID_SIZE, GRID_SIZE, len(ACTIONS)))
# Hyperparameters
alpha = 0.1 # Learning rate
gamma = 0.9 # Discount factor
epsilon = 0.2 # Exploration rate
episodes = 500
def step(state, action_idx):
"""Take one action in the environment."""
dr, dc = ACTION_EFFECTS[ACTIONS[action_idx]]
r, c = state
nr = max(0, min(GRID_SIZE - 1, r + dr))
nc = max(0, min(GRID_SIZE - 1, c + dc))
# Obstacle blocks movement
if (nr, nc) == OBSTACLE:
nr, nc = r, c
reward = 10 if (nr, nc) == GOAL else -1
done = (nr, nc) == GOAL
return (nr, nc), reward, done
# -------------------------
# Training
# -------------------------
rewards_per_episode = []
for ep in range(episodes):
state = (0, 0)
total_reward = 0
for t in range(100):
# Epsilon-greedy action selection
if random.random() < epsilon:
action = random.randint(0, 3)
else:
action = np.argmax(Q[state[0], state[1]])
next_state, reward, done = step(state, action)
best_next = np.max(Q[next_state[0], next_state[1]])
# Q-learning update
Q[state[0], state[1], action] += (
alpha
* (
reward
+ gamma * best_next
- Q[state[0], state[1], action]
)
)
state = next_state
total_reward += reward
if done:
break
rewards_per_episode.append(total_reward)
# Decay exploration rate
epsilon = max(0.01, epsilon * 0.995)
# -------------------------
# Results
# -------------------------
print("Training complete over", episodes, "episodes.")
print(
f"Average reward (first 50 episodes): "
f"{np.mean(rewards_per_episode[:50]):.2f}"
)
print(
f"Average reward (last 50 episodes): "
f"{np.mean(rewards_per_episode[-50:]):.2f}"
)
# -------------------------
# Learned Policy
# -------------------------
print("\nLearned Optimal Policy (Grid View):")
policy_symbols = {
"UP": "^",
"DOWN": "v",
"LEFT": "<",
"RIGHT": ">"
}
for r in range(GRID_SIZE):
row_str = ""
for c in range(GRID_SIZE):
if (r, c) == GOAL:
row_str += " G "
elif (r, c) == OBSTACLE:
row_str += " X "
else:
best_action = ACTIONS[np.argmax(Q[r, c])]
row_str += f" {policy_symbols[best_action]} "
print(row_str)
# -------------------------
# Plot Learning Curve
# -------------------------
plt.figure(figsize=(7, 4.5))
window = 20
smoothed = np.convolve(
rewards_per_episode,
np.ones(window) / window,
mode="valid"
)
plt.plot(
rewards_per_episode,
alpha=0.3,
color="gray",
label="Reward per Episode"
)
plt.plot(
range(window - 1, len(rewards_per_episode)),
smoothed,
color="#4C72B0",
linewidth=2,
label=f"{window}-Episode Moving Average"
)
plt.xlabel("Episode")
plt.ylabel("Total Reward")
plt.title("Q-Learning Convergence: Grid World (4×4)")
plt.legend()
plt.tight_layout()
plt.savefig("imgs/a11_qlearning.png", dpi=130)
print(
"\nPlot saved. Agent converges to the shortest "
"obstacle-avoiding path to the goal."
)
26,889 chars · codepastes.com