{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceType":"competition","sourceId":50160,"databundleVersionId":7921029}],"dockerImageVersionId":31328,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import StandardScaler, LabelEncoder\nfrom sklearn.metrics import roc_auc_score, confusion_matrix, classification_report\nimport tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Dropout, BatchNormalization, Input\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau\nimport warnings\nwarnings.filterwarnings('ignore')\n\nnp.random.seed(42)\ntf.random.set_seed(42)\n\nprint(\"=\"*60)\nprint(\"HOME CREDIT - CREDIT RISK MODEL\")\nprint(\"=\"*60)\n\nDATA_PATH = \"/kaggle/input/competitions/home-credit-credit-risk-model-stability\"\n\nprint(\"\\nLoading data...\")\n\ncsv_files_path = os.path.join(DATA_PATH, \"csv_files\")\n\nif os.path.exists(csv_files_path):\n    print(\"Found csv_files directory\")\n    files = os.listdir(csv_files_path)\n    print(\"Files:\", files)\n    \n    train_file = None\n    for f in files:\n        if 'train' in f.lower():\n            train_file = f\n            break\n    \n    if train_file:\n        train_path = os.path.join(csv_files_path, train_file)\n        print(\"\\nLoading\", train_file)\n        \n        if train_file.endswith('.csv'):\n            train_df = pd.read_csv(train_path)\n        elif train_file.endswith('.parquet'):\n            train_df = pd.read_parquet(train_path)\n        else:\n            print(\"Unknown file type:\", train_file)\n            train_df = None\n        \n        if train_df is not None:\n            print(\"Train data shape:\", train_df.shape)\n    else:\n        print(\"No train file found\")\n        print(\"Trying to load all files...\")\n        \n        train_df = None\n        for f in files:\n            file_path = os.path.join(csv_files_path, f)\n            print(\"Checking:\", f)\n            \n            if f.endswith('.csv'):\n                temp_df = pd.read_csv(file_path)\n            elif f.endswith('.parquet'):\n                temp_df = pd.read_parquet(file_path)\n            else:\n                continue\n            \n            if 'TARGET' in temp_df.columns:\n                train_df = temp_df\n                print(\"Found TARGET in\", f)\n                break\n            elif 'target' in temp_df.columns:\n                temp_df.rename(columns={'target': 'TARGET'}, inplace=True)\n                train_df = temp_df\n                print(\"Found target in\", f)\n                break\n\nif train_df is None:\n    print(\"\\nSearching entire directory for files with TARGET column...\")\n    for root, dirs, files in os.walk(DATA_PATH):\n        for file in files:\n            if file.endswith('.csv') or file.endswith('.parquet'):\n                file_path = os.path.join(root, file)\n                print(\"Checking:\", file)\n                try:\n                    if file.endswith('.csv'):\n                        temp_df = pd.read_csv(file_path, nrows=5)\n                    else:\n                        temp_df = pd.read_parquet(file_path)\n                    \n                    if 'TARGET' in temp_df.columns:\n                        print(\"Found TARGET in\", file)\n                        if file.endswith('.csv'):\n                            train_df = pd.read_csv(file_path)\n                        else:\n                            train_df = pd.read_parquet(file_path)\n                        break\n                    elif 'target' in temp_df.columns:\n                        print(\"Found target in\", file)\n                        if file.endswith('.csv'):\n                            train_df = pd.read_csv(file_path)\n                        else:\n                            train_df = pd.read_parquet(file_path)\n                        train_df.rename(columns={'target': 'TARGET'}, inplace=True)\n                        break\n                except:\n                    continue\n\nif train_df is not None:\n    print(\"\\nTraining data:\", train_df.shape[0], \"rows,\", train_df.shape[1], \"columns\")\n    print(\"Default rate:\", train_df['TARGET'].mean())\n    \n    print(\"\\nProcessing data...\")\n    df = train_df.copy()\n    \n    threshold = 60\n    cols_to_drop = []\n    for col in df.columns:\n        if df[col].isnull().mean() * 100 > threshold:\n            cols_to_drop.append(col)\n    \n    if cols_to_drop:\n        df = df.drop(columns=cols_to_drop)\n        print(\"Dropped\", len(cols_to_drop), \"columns with >60% missing\")\n    \n    for col in df.columns:\n        if df[col].isnull().any():\n            if df[col].dtype in ['int64', 'float64']:\n                df[col].fillna(df[col].median(), inplace=True)\n            else:\n                mode_val = df[col].mode()[0] if len(df[col].mode()) > 0 else 'Unknown'\n                df[col].fillna(mode_val, inplace=True)\n    \n    print(\"Missing values handled\")\n    \n    print(\"\\nFeature engineering...\")\n    \n    if 'AMT_CREDIT' in df.columns and 'AMT_INCOME_TOTAL' in df.columns:\n        df['CREDIT_TO_INCOME'] = df['AMT_CREDIT'] / (df['AMT_INCOME_TOTAL'] + 1)\n        print(\"  CREDIT_TO_INCOME\")\n    \n    if 'DAYS_BIRTH' in df.columns:\n        df['AGE'] = abs(df['DAYS_BIRTH']) / 365\n        print(\"  AGE\")\n    \n    if 'DAYS_EMPLOYED' in df.columns:\n        df['EMPLOYMENT_YEARS'] = abs(df['DAYS_EMPLOYED']) / 365\n        df['EMPLOYMENT_YEARS'] = df['EMPLOYMENT_YEARS'].clip(upper=50)\n        print(\"  EMPLOYMENT_YEARS\")\n    \n    ext_cols = [col for col in ['EXT_SOURCE_1', 'EXT_SOURCE_2', 'EXT_SOURCE_3'] if col in df.columns]\n    if len(ext_cols) >= 2:\n        df['EXT_SOURCE_AVG'] = df[ext_cols].mean(axis=1)\n        print(\"  EXT_SOURCE_AVG\")\n    \n    if 'AMT_ANNUITY' in df.columns and 'AMT_CREDIT' in df.columns:\n        df['ANNUITY_TO_CREDIT'] = df['AMT_ANNUITY'] / (df['AMT_CREDIT'] + 1)\n        print(\"  ANNUITY_TO_CREDIT\")\n    \n    print(\"\\nPreparing features...\")\n    y = df['TARGET'].values\n    \n    cols_to_remove = ['TARGET', 'SK_ID_CURR'] if 'SK_ID_CURR' in df.columns else ['TARGET']\n    existing_remove = [col for col in cols_to_remove if col in df.columns]\n    X = df.drop(columns=existing_remove)\n    \n    for col in X.select_dtypes(include=['object']).columns:\n        X[col] = LabelEncoder().fit_transform(X[col].astype(str))\n    \n    X = X.fillna(X.median())\n    \n    scaler = StandardScaler()\n    X_scaled = scaler.fit_transform(X)\n    \n    print(\"Features ready:\", X_scaled.shape[1], \"features\")\n    \n    X_train, X_temp, y_train, y_temp = train_test_split(\n        X_scaled, y, test_size=0.3, random_state=42, stratify=y\n    )\n    X_val, X_test, y_val, y_test = train_test_split(\n        X_temp, y_temp, test_size=0.5, random_state=42, stratify=y_temp\n    )\n    \n    print(\"\\nData split:\")\n    print(\"  Train:\", len(X_train))\n    print(\"  Validation:\", len(X_val))\n    print(\"  Test:\", len(X_test))\n    \n    print(\"\\nBuilding model...\")\n    \n    model = Sequential([\n        Input(shape=(X_train.shape[1],)),\n        Dense(256, activation='relu'),\n        BatchNormalization(),\n        Dropout(0.3),\n        Dense(128, activation='relu'),\n        BatchNormalization(),\n        Dropout(0.3),\n        Dense(64, activation='relu'),\n        BatchNormalization(),\n        Dropout(0.2),\n        Dense(32, activation='relu'),\n        Dropout(0.2),\n        Dense(1, activation='sigmoid')\n    ])\n    \n    model.compile(\n        optimizer=Adam(learning_rate=0.001),\n        loss='binary_crossentropy',\n        metrics=['accuracy', tf.keras.metrics.AUC(name='auc')]\n    )\n    \n    model.summary()\n    \n    from sklearn.utils.class_weight import compute_class_weight\n    class_weights = compute_class_weight('balanced', classes=np.unique(y_train), y=y_train)\n    class_weight_dict = {0: class_weights[0], 1: class_weights[1]}\n    print(\"\\nClass weights:\", class_weight_dict)\n    \n    callbacks = [\n        EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True, verbose=1),\n        ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=5, min_lr=1e-6, verbose=1)\n    ]\n    \n    print(\"\\nTraining model...\")\n    history = model.fit(\n        X_train, y_train,\n        validation_data=(X_val, y_val),\n        epochs=50,\n        batch_size=512,\n        class_weight=class_weight_dict,\n        callbacks=callbacks,\n        verbose=1\n    )\n    \n    print(\"\\nEvaluating model...\")\n    y_pred_proba = model.predict(X_test, verbose=0).flatten()\n    y_pred_binary = (y_pred_proba > 0.5).astype(int)\n    \n    auc = roc_auc_score(y_test, y_pred_proba)\n    gini = 2 * auc - 1\n    \n    print(\"\\nRESULTS:\")\n    print(\"  AUC Score:\", auc)\n    print(\"  Gini Coefficient:\", gini)\n    \n    cm = confusion_matrix(y_test, y_pred_binary)\n    print(\"\\nConfusion Matrix:\")\n    print(\"  TN:\", cm[0,0], \" | FP:\", cm[0,1])\n    print(\"  FN:\", cm[1,0], \" | TP:\", cm[1,1])\n    \n    print(\"\\nClassification Report:\")\n    print(classification_report(y_test, y_pred_binary, target_names=['Non-Default', 'Default']))\n    \n    fig, axes = plt.subplots(1, 3, figsize=(15, 4))\n    \n    axes[0].plot(history.history['loss'], label='Train Loss')\n    axes[0].plot(history.history['val_loss'], label='Val Loss')\n    axes[0].set_title('Model Loss')\n    axes[0].set_xlabel('Epoch')\n    axes[0].set_ylabel('Loss')\n    axes[0].legend()\n    axes[0].grid(True)\n    \n    axes[1].plot(history.history['auc'], label='Train AUC')\n    axes[1].plot(history.history['val_auc'], label='Val AUC')\n    axes[1].set_title('Model AUC')\n    axes[1].set_xlabel('Epoch')\n    axes[1].set_ylabel('AUC')\n    axes[1].legend()\n    axes[1].grid(True)\n    \n    axes[2].plot(history.history['accuracy'], label='Train Accuracy')\n    axes[2].plot(history.history['val_accuracy'], label='Val Accuracy')\n    axes[2].set_title('Model Accuracy')\n    axes[2].set_xlabel('Epoch')\n    axes[2].set_ylabel('Accuracy')\n    axes[2].legend()\n    axes[2].grid(True)\n    \n    plt.tight_layout()\n    plt.savefig('training_history.png', dpi=100)\n    plt.show()\n    \n    plt.figure(figsize=(6, 5))\n    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',\n                xticklabels=['Non-Default', 'Default'],\n                yticklabels=['Non-Default', 'Default'])\n    plt.title('Confusion Matrix')\n    plt.ylabel('Actual')\n    plt.xlabel('Predicted')\n    plt.savefig('confusion_matrix.png', dpi=100)\n    plt.show()\n    \n    print(\"\\n\" + \"=\"*60)\n    print(\"PROJECT COMPLETED SUCCESSFULLY\")\n    print(\"Final Test AUC:\", auc)\n    print(\"Final Test Gini:\", gini)\n    print(\"=\"*60)\nelse:\n    print(\"\\nCould not find training data with TARGET column\")\n    print(\"Please check the dataset structure\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-22T19:26:56.619866Z","iopub.execute_input":"2026-04-22T19:26:56.620257Z","iopub.status.idle":"2026-04-22T19:36:47.828276Z","shell.execute_reply.started":"2026-04-22T19:26:56.620194Z","shell.execute_reply":"2026-04-22T19:36:47.82732Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"https://www.linkedin.com/posts/zainab-gamal-62a443314_datascience-machinelearning-deeplearning-ugcPost-7452827141269970944-LCVb?utm_source=share&utm_medium=member_desktop&rcm=ACoAAE_Mi8IBDcFrtf8Tdh_8eXI2d_IMSqELOFI","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}