# Experiment 6: Decision Tree Classifier for Multi-Class Credit Risk Assessment
# Requirements: pip install numpy pandas matplotlib seaborn scikit-learn

# Import required libraries
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.tree import DecisionTreeClassifier, export_text, plot_tree
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score, roc_auc_score

# 1. Generate Synthetic Dataset for Credit Risk Assessment
np.random.seed(42)
n_samples = 1000

data = {
    'Debt_to_Income_Ratio': np.random.uniform(0.1, 0.8, n_samples),
    'Credit_Score': np.random.randint(300, 850, n_samples),
    'Annual_Income': np.random.uniform(20000, 150000, n_samples),
    'Missed_Payments_Count': np.random.randint(0, 10, n_samples)
}
df = pd.DataFrame(data)

# Define target: Credit_Risk_Rating (0 = Low Risk, 1 = Moderate Risk, 2 = High Risk)
risk_index = (df['Debt_to_Income_Ratio'] * 2.5) + (df['Missed_Payments_Count'] * 0.4) - (df['Credit_Score'] / 300.0)
df['Credit_Risk_Rating'] = pd.qcut(risk_index, q=3, labels=[0, 1, 2]).astype(int)

# 2. Train-Test Split (80:20 Stratified Ratio)
X = df[['Debt_to_Income_Ratio', 'Credit_Score', 'Annual_Income', 'Missed_Payments_Count']]
y = df['Credit_Risk_Rating']

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

# 3. Train Decision Tree Model with Pre-Pruning (Hyperparameter Control)
dt_model = DecisionTreeClassifier(
    criterion='gini',
    max_depth=4,
    min_samples_split=10,
    min_samples_leaf=5,
    random_state=42
)
dt_model.fit(X_train, y_train)

# 4. Model Prediction and Performance Evaluation
y_pred = dt_model.predict(X_test)
y_probs = dt_model.predict_proba(X_test)

print('--- Confusion Matrix ---')
print(confusion_matrix(y_test, y_pred))

print('\n--- Classification Report ---')
print(classification_report(y_test, y_pred, target_names=['Low Risk', 'Moderate Risk', 'High Risk']))

# 5. Feature Importance Analysis
feature_imp = pd.Series(dt_model.feature_importances_, index=X.columns).sort_values(ascending=False)
print('\n--- Feature Importances ---')
print(feature_imp)

# 6. Decision Rules Extraction (Text-based)
tree_rules = export_text(dt_model, feature_names=list(X.columns))
print('\n--- Decision Tree Rules ---')
print(tree_rules[:500])  # Print top rule paths
