================================================================================
  Question 50: Breast Cancer Classification (Feature Selection & Model Comparison)
================================================================================

FULL QUESTION:
Task:
Using the Wisconsin Breast Cancer Dataset (Classification), perform the following:
1. Load dataset using sklearn.datasets.load_breast_cancer.
2. Check class distribution and feature shapes.
3. Feature Scaling using StandardScaler.
4. Train/Test split.
5. Visualization: Correlation heatmap.
6. Feature Selection: Rank features using Random Forest and select top features.
7. Model Training & Comparison:
   - Decision Tree
   - Random Forest
   - Logistic Regression
8. Evaluate using Accuracy, Precision, Recall, F1-Score, and Confusion Matrix.

SHORT QUESTION:
Breast cancer classification workflow with Random Forest feature ranking and multi-model performance comparison.

================================================================================
README & SETUP INSTRUCTIONS:
================================================================================
# Question 50: Breast Cancer Classification (Feature Selection & Model Comparison)

- Prerequisites: Python 3.x, Scikit-Learn, Pandas, NumPy, Matplotlib, Seaborn (pip install scikit-learn pandas numpy matplotlib seaborn).
- Setup: Uses sklearn.datasets.load_breast_cancer (built into scikit-learn).
- How to Run: python question_50.py
- Expected Behavior: Loads cancer data, standardizes, ranks features, trains models, and prints comparative accuracy and recall metrics.

================================================================================
SOURCE CODE FILES:
================================================================================

1. question_50.py
--------------------------------------------------------------------------------
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
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.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, recall_score, confusion_matrix, classification_report

data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = pd.Series(data.target, name='target')

print("Dataset Shape:", X.shape)
print("Class Distribution:\n", y.value_counts())
print("(0 = Malignant, 1 = Benign)\n")

plt.figure(figsize=(14, 10))
sns.heatmap(X.corr(), cmap='coolwarm', annot=False)
plt.title("Feature Correlation Heatmap")
plt.show()

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.20, random_state=42, stratify=y
)

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

rf_selector = RandomForestClassifier(n_estimators=100, random_state=42)
rf_selector.fit(X_train_scaled, y_train)

importances = pd.Series(rf_selector.feature_importances_, index=X.columns).sort_values(ascending=False)

plt.figure(figsize=(10, 6))
importances.head(10).plot(kind='barh')
plt.title("Top 10 Feature Importances (Random Forest)")
plt.gca().invert_yaxis()
plt.show()

top_features = importances.head(10).index
X_train_top = pd.DataFrame(X_train_scaled, columns=X.columns)[top_features]
X_test_top = pd.DataFrame(X_test_scaled, columns=X.columns)[top_features]

def evaluate_models(X_tr, X_te, y_tr, y_te, tag="All Features"):
    models = {
        "Decision Tree": DecisionTreeClassifier(random_state=42),
        "Random Forest": RandomForestClassifier(n_estimators=100, random_state=42),
        "Logistic Regression": LogisticRegression(random_state=42)
    }

    results = []

    print(f"\n==================== EVALUATION ({tag}) ====================")
    for name, model in models.items():
        model.fit(X_tr, y_tr)
        y_pred = model.predict(X_te)

        acc = accuracy_score(y_te, y_pred)
        rec = recall_score(y_te, y_pred)
        cm = confusion_matrix(y_te, y_pred)
        fn = cm[1][0]

        results.append({
            "Model": name,
            "Accuracy": acc,
            "Recall": rec,
            "False Negatives": fn
        })

        print(f"\n--- {name} ---")
        print(f"Accuracy: {acc:.4f}")
        print(f"Recall: {rec:.4f}")
        print("Confusion Matrix:\n", cm)

    return pd.DataFrame(results)

results_all = evaluate_models(X_train_scaled, X_test_scaled, y_train, y_test, tag="All Features")
results_top = evaluate_models(X_train_top, X_test_top, y_train, y_test, tag="Top 10 Features")

print("\n--- MODEL PERFORMANCE COMPARISON ---")
print("FULL FEATURES:\n", results_all)
print("\nTOP 10 FEATURES:\n", results_top)

rf_final = RandomForestClassifier(n_estimators=100, random_state=42)
rf_final.fit(X_train_scaled, y_train)

sample_input = X_test_scaled[0].reshape(1, -1)
prediction = rf_final.predict(sample_input)
label = "Benign" if prediction[0] == 1 else "Malignant"

print(f"\nPrediction for Sample 1: {prediction[0]} ({label})")
--------------------------------------------------------------------------------
