{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1000
        },
        "id": "baPt13m9FRoU",
        "outputId": "4ec54871-81d6-4cc9-8372-f34396942fef"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Requirement already satisfied: pyod in /usr/local/lib/python3.12/dist-packages (3.5.2)\n",
            "Requirement already satisfied: openpyxl in /usr/local/lib/python3.12/dist-packages (3.1.5)\n",
            "Requirement already satisfied: joblib>=1.5 in /usr/local/lib/python3.12/dist-packages (from pyod) (1.5.3)\n",
            "Requirement already satisfied: matplotlib in /usr/local/lib/python3.12/dist-packages (from pyod) (3.10.0)\n",
            "Requirement already satisfied: numpy>=1.19 in /usr/local/lib/python3.12/dist-packages (from pyod) (2.0.2)\n",
            "Requirement already satisfied: numba>=0.51 in /usr/local/lib/python3.12/dist-packages (from pyod) (0.60.0)\n",
            "Requirement already satisfied: scipy>=1.5.1 in /usr/local/lib/python3.12/dist-packages (from pyod) (1.16.3)\n",
            "Requirement already satisfied: scikit-learn>=0.22.0 in /usr/local/lib/python3.12/dist-packages (from pyod) (1.6.1)\n",
            "Requirement already satisfied: et-xmlfile in /usr/local/lib/python3.12/dist-packages (from openpyxl) (2.0.0)\n",
            "Requirement already satisfied: llvmlite<0.44,>=0.43.0dev0 in /usr/local/lib/python3.12/dist-packages (from numba>=0.51->pyod) (0.43.0)\n",
            "Requirement already satisfied: threadpoolctl>=3.1.0 in /usr/local/lib/python3.12/dist-packages (from scikit-learn>=0.22.0->pyod) (3.6.0)\n",
            "Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.12/dist-packages (from matplotlib->pyod) (1.3.3)\n",
            "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.12/dist-packages (from matplotlib->pyod) (0.12.1)\n",
            "Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.12/dist-packages (from matplotlib->pyod) (4.63.0)\n",
            "Requirement already satisfied: kiwisolver>=1.3.1 in /usr/local/lib/python3.12/dist-packages (from matplotlib->pyod) (1.5.0)\n",
            "Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.12/dist-packages (from matplotlib->pyod) (26.2)\n",
            "Requirement already satisfied: pillow>=8 in /usr/local/lib/python3.12/dist-packages (from matplotlib->pyod) (11.3.0)\n",
            "Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.12/dist-packages (from matplotlib->pyod) (3.3.2)\n",
            "Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.12/dist-packages (from matplotlib->pyod) (2.9.0.post0)\n",
            "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.12/dist-packages (from python-dateutil>=2.7->matplotlib->pyod) (1.17.0)\n",
            "Experiment: 20 runs, NNFA with ξ=0, 500 epochs\n",
            "Dataset: California Housing with 400 outliers (200 highest → min, 200 lowest → max).\n",
            "\n",
            "--- Run 1/20, seed = 0 ---\n",
            "  NNFA (ξ=0) F1 = 0.797, AUC = 0.996\n",
            "\n",
            "--- Run 2/20, seed = 1 ---\n",
            "  NNFA (ξ=0) F1 = 0.823, AUC = 0.997\n",
            "\n",
            "--- Run 3/20, seed = 2 ---\n",
            "  NNFA (ξ=0) F1 = 0.800, AUC = 0.997\n",
            "\n",
            "--- Run 4/20, seed = 3 ---\n",
            "  NNFA (ξ=0) F1 = 0.800, AUC = 0.997\n",
            "\n",
            "--- Run 5/20, seed = 4 ---\n",
            "  NNFA (ξ=0) F1 = 0.823, AUC = 0.997\n",
            "\n",
            "--- Run 6/20, seed = 5 ---\n",
            "  NNFA (ξ=0) F1 = 0.792, AUC = 0.996\n",
            "\n",
            "--- Run 7/20, seed = 6 ---\n",
            "  NNFA (ξ=0) F1 = 0.800, AUC = 0.997\n",
            "\n",
            "--- Run 8/20, seed = 7 ---\n",
            "  NNFA (ξ=0) F1 = 0.810, AUC = 0.997\n",
            "\n",
            "--- Run 9/20, seed = 8 ---\n",
            "  NNFA (ξ=0) F1 = 0.807, AUC = 0.997\n",
            "\n",
            "--- Run 10/20, seed = 9 ---\n",
            "  NNFA (ξ=0) F1 = 0.805, AUC = 0.997\n",
            "\n",
            "--- Run 11/20, seed = 10 ---\n",
            "  NNFA (ξ=0) F1 = 0.802, AUC = 0.997\n",
            "\n",
            "--- Run 12/20, seed = 11 ---\n",
            "  NNFA (ξ=0) F1 = 0.815, AUC = 0.997\n",
            "\n",
            "--- Run 13/20, seed = 12 ---\n",
            "  NNFA (ξ=0) F1 = 0.787, AUC = 0.996\n",
            "\n",
            "--- Run 14/20, seed = 13 ---\n",
            "  NNFA (ξ=0) F1 = 0.802, AUC = 0.997\n",
            "\n",
            "--- Run 15/20, seed = 14 ---\n",
            "  NNFA (ξ=0) F1 = 0.800, AUC = 0.997\n",
            "\n",
            "--- Run 16/20, seed = 15 ---\n",
            "  NNFA (ξ=0) F1 = 0.812, AUC = 0.997\n",
            "\n",
            "--- Run 17/20, seed = 16 ---\n",
            "  NNFA (ξ=0) F1 = 0.805, AUC = 0.997\n",
            "\n",
            "--- Run 18/20, seed = 17 ---\n",
            "  NNFA (ξ=0) F1 = 0.795, AUC = 0.996\n",
            "\n",
            "--- Run 19/20, seed = 18 ---\n",
            "  NNFA (ξ=0) F1 = 0.792, AUC = 0.996\n",
            "\n",
            "--- Run 20/20, seed = 19 ---\n",
            "  NNFA (ξ=0) F1 = 0.802, AUC = 0.996\n",
            "\n",
            "================================================================================\n",
            "SUMMARY TABLE (mean ± std) over 20 runs\n",
            "================================================================================\n",
            "                      Method F1 (mean ± std) ROC-AUC (mean ± std)\n",
            "                  NNFA (ξ=0)   0.804 ± 0.009        0.997 ± 0.000\n",
            "      Neural Network (error)   0.779 ± 0.077        0.990 ± 0.008\n",
            "       Random Forest (error)   0.697 ± 0.014        0.980 ± 0.002\n",
            "            Combined (RF+AE)   0.686 ± 0.014        0.980 ± 0.002\n",
            "   Isolation Forest (with y)   0.140 ± 0.014        0.886 ± 0.014\n",
            "                 HBOS (pyod)   0.042 ± 0.001        0.697 ± 0.000\n",
            "      IsolationForest (pyod)   0.081 ± 0.008        0.693 ± 0.011\n",
            "                  kNN (pyod)   0.085 ± 0.000        0.681 ± 0.000\n",
            "                 ABOD (pyod)   0.090 ± 0.000        0.661 ± 0.000\n",
            "                LOF (with y)   0.090 ± 0.000        0.654 ± 0.000\n",
            "Autoencoder (reconstruction)   0.090 ± 0.009        0.653 ± 0.014\n",
            "                COPOD (pyod)   0.060 ± 0.000        0.634 ± 0.000\n",
            "                OCSVM (pyod)   0.085 ± 0.000        0.623 ± 0.000\n",
            "                  LOF (pyod)   0.065 ± 0.000        0.610 ± 0.000\n",
            "                  PCA (pyod)   0.083 ± 0.000        0.578 ± 0.000\n",
            "      One-Class SVM (with y)   0.012 ± 0.003        0.476 ± 0.009\n",
            "\n",
            "================================================================================\n",
            "PAIRWISE WILCOXON P-VALUES (rounded to 4 decimals)\n",
            "================================================================================\n",
            "                             ABOD (pyod) HBOS (pyod) IsolationForest (pyod) kNN (pyod) LOF (pyod) OCSVM (pyod) PCA (pyod) COPOD (pyod) Random Forest (error) Neural Network (error) Autoencoder (reconstruction) Combined (RF+AE) One-Class SVM (with y) Isolation Forest (with y) LOF (with y) NNFA (ξ=0)\n",
            "ABOD (pyod)                          1.0         0.0                 0.0008        0.0        0.0          0.0        0.0          0.0                0.0001                 0.0001                       0.6574           0.0001                 0.0001                    0.0001          1.0     0.0001\n",
            "HBOS (pyod)                          0.0         1.0                 0.0001        0.0        0.0          0.0        0.0          0.0                0.0001                 0.0001                       0.0001           0.0001                 0.0001                    0.0001          0.0     0.0001\n",
            "IsolationForest (pyod)            0.0008      0.0001                    1.0     0.0136     0.0001       0.0136     0.1757       0.0001                0.0001                 0.0001                       0.0013           0.0001                 0.0001                    0.0001       0.0008     0.0001\n",
            "kNN (pyod)                           0.0         0.0                 0.0136        1.0        0.0          1.0        0.0          0.0                0.0001                 0.0001                       0.0399           0.0001                 0.0001                    0.0001          0.0     0.0001\n",
            "LOF (pyod)                           0.0         0.0                 0.0001        0.0        1.0          0.0        0.0          0.0                0.0001                 0.0001                       0.0001           0.0001                 0.0001                    0.0001          0.0     0.0001\n",
            "OCSVM (pyod)                         0.0         0.0                 0.0136        1.0        0.0          1.0        0.0          0.0                0.0001                 0.0001                       0.0399           0.0001                 0.0001                    0.0001          0.0     0.0001\n",
            "PCA (pyod)                           0.0         0.0                 0.1757        0.0        0.0          0.0        1.0          0.0                0.0001                 0.0001                       0.0033           0.0001                 0.0001                    0.0001          0.0     0.0001\n",
            "COPOD (pyod)                         0.0         0.0                 0.0001        0.0        0.0          0.0        0.0          1.0                0.0001                 0.0001                       0.0001           0.0001                 0.0001                    0.0001          0.0     0.0001\n",
            "Random Forest (error)             0.0001      0.0001                 0.0001     0.0001     0.0001       0.0001     0.0001       0.0001                   1.0                 0.0009                       0.0001           0.0001                 0.0001                    0.0001       0.0001     0.0001\n",
            "Neural Network (error)            0.0001      0.0001                 0.0001     0.0001     0.0001       0.0001     0.0001       0.0001                0.0009                    1.0                       0.0001            0.001                 0.0001                    0.0001       0.0001     0.3803\n",
            "Autoencoder (reconstruction)      0.6574      0.0001                 0.0013     0.0399     0.0001       0.0399     0.0033       0.0001                0.0001                 0.0001                          1.0           0.0001                 0.0001                    0.0001       0.6574     0.0001\n",
            "Combined (RF+AE)                  0.0001      0.0001                 0.0001     0.0001     0.0001       0.0001     0.0001       0.0001                0.0001                  0.001                       0.0001              1.0                 0.0001                    0.0001       0.0001     0.0001\n",
            "One-Class SVM (with y)            0.0001      0.0001                 0.0001     0.0001     0.0001       0.0001     0.0001       0.0001                0.0001                 0.0001                       0.0001           0.0001                    1.0                    0.0001       0.0001     0.0001\n",
            "Isolation Forest (with y)         0.0001      0.0001                 0.0001     0.0001     0.0001       0.0001     0.0001       0.0001                0.0001                 0.0001                       0.0001           0.0001                 0.0001                       1.0       0.0001     0.0001\n",
            "LOF (with y)                         1.0         0.0                 0.0008        0.0        0.0          0.0        0.0          0.0                0.0001                 0.0001                       0.6574           0.0001                 0.0001                    0.0001          1.0     0.0001\n",
            "NNFA (ξ=0)                        0.0001      0.0001                 0.0001     0.0001     0.0001       0.0001     0.0001       0.0001                0.0001                 0.3803                       0.0001           0.0001                 0.0001                    0.0001       0.0001        1.0\n",
            "\n",
            "Full pairwise p-value matrix saved to 'pairwise_wilcoxon_matrix.csv'\n",
            "\n",
            "================================================================================\n",
            "DETAILED SIGNIFICANT DIFFERENCES (p < 0.05)\n",
            "================================================================================\n",
            "ABOD (pyod) vs HBOS (pyod): p = 0.000042\n",
            "ABOD (pyod) vs IsolationForest (pyod): p = 0.000754\n",
            "ABOD (pyod) vs kNN (pyod): p = 0.000008\n",
            "ABOD (pyod) vs LOF (pyod): p = 0.000008\n",
            "ABOD (pyod) vs OCSVM (pyod): p = 0.000008\n",
            "ABOD (pyod) vs PCA (pyod): p = 0.000008\n",
            "ABOD (pyod) vs COPOD (pyod): p = 0.000008\n",
            "ABOD (pyod) vs Random Forest (error): p = 0.000088\n",
            "ABOD (pyod) vs Neural Network (error): p = 0.000088\n",
            "ABOD (pyod) vs Combined (RF+AE): p = 0.000087\n",
            "ABOD (pyod) vs One-Class SVM (with y): p = 0.000081\n",
            "ABOD (pyod) vs Isolation Forest (with y): p = 0.000088\n",
            "ABOD (pyod) vs NNFA (ξ=0): p = 0.000086\n",
            "HBOS (pyod) vs IsolationForest (pyod): p = 0.000085\n",
            "HBOS (pyod) vs kNN (pyod): p = 0.000042\n",
            "HBOS (pyod) vs LOF (pyod): p = 0.000042\n",
            "HBOS (pyod) vs OCSVM (pyod): p = 0.000042\n",
            "HBOS (pyod) vs PCA (pyod): p = 0.000042\n",
            "HBOS (pyod) vs COPOD (pyod): p = 0.000042\n",
            "HBOS (pyod) vs Random Forest (error): p = 0.000088\n",
            "HBOS (pyod) vs Neural Network (error): p = 0.000088\n",
            "HBOS (pyod) vs Autoencoder (reconstruction): p = 0.000086\n",
            "HBOS (pyod) vs Combined (RF+AE): p = 0.000088\n",
            "HBOS (pyod) vs One-Class SVM (with y): p = 0.000083\n",
            "HBOS (pyod) vs Isolation Forest (with y): p = 0.000088\n",
            "HBOS (pyod) vs LOF (with y): p = 0.000042\n",
            "HBOS (pyod) vs NNFA (ξ=0): p = 0.000087\n",
            "IsolationForest (pyod) vs kNN (pyod): p = 0.013557\n",
            "IsolationForest (pyod) vs LOF (pyod): p = 0.000085\n",
            "IsolationForest (pyod) vs OCSVM (pyod): p = 0.013557\n",
            "IsolationForest (pyod) vs COPOD (pyod): p = 0.000085\n",
            "IsolationForest (pyod) vs Random Forest (error): p = 0.000088\n",
            "IsolationForest (pyod) vs Neural Network (error): p = 0.000088\n",
            "IsolationForest (pyod) vs Autoencoder (reconstruction): p = 0.001274\n",
            "IsolationForest (pyod) vs Combined (RF+AE): p = 0.000088\n",
            "IsolationForest (pyod) vs One-Class SVM (with y): p = 0.000087\n",
            "IsolationForest (pyod) vs Isolation Forest (with y): p = 0.000088\n",
            "IsolationForest (pyod) vs LOF (with y): p = 0.000754\n",
            "IsolationForest (pyod) vs NNFA (ξ=0): p = 0.000088\n",
            "kNN (pyod) vs LOF (pyod): p = 0.000008\n",
            "kNN (pyod) vs PCA (pyod): p = 0.000008\n",
            "kNN (pyod) vs COPOD (pyod): p = 0.000008\n",
            "kNN (pyod) vs Random Forest (error): p = 0.000088\n",
            "kNN (pyod) vs Neural Network (error): p = 0.000088\n",
            "kNN (pyod) vs Autoencoder (reconstruction): p = 0.039853\n",
            "kNN (pyod) vs Combined (RF+AE): p = 0.000087\n",
            "kNN (pyod) vs One-Class SVM (with y): p = 0.000081\n",
            "kNN (pyod) vs Isolation Forest (with y): p = 0.000088\n",
            "kNN (pyod) vs LOF (with y): p = 0.000008\n",
            "kNN (pyod) vs NNFA (ξ=0): p = 0.000086\n",
            "LOF (pyod) vs OCSVM (pyod): p = 0.000008\n",
            "LOF (pyod) vs PCA (pyod): p = 0.000008\n",
            "LOF (pyod) vs COPOD (pyod): p = 0.000008\n",
            "LOF (pyod) vs Random Forest (error): p = 0.000088\n",
            "LOF (pyod) vs Neural Network (error): p = 0.000088\n",
            "LOF (pyod) vs Autoencoder (reconstruction): p = 0.000087\n",
            "LOF (pyod) vs Combined (RF+AE): p = 0.000087\n",
            "LOF (pyod) vs One-Class SVM (with y): p = 0.000081\n",
            "LOF (pyod) vs Isolation Forest (with y): p = 0.000088\n",
            "LOF (pyod) vs LOF (with y): p = 0.000008\n",
            "LOF (pyod) vs NNFA (ξ=0): p = 0.000086\n",
            "OCSVM (pyod) vs PCA (pyod): p = 0.000008\n",
            "OCSVM (pyod) vs COPOD (pyod): p = 0.000008\n",
            "OCSVM (pyod) vs Random Forest (error): p = 0.000088\n",
            "OCSVM (pyod) vs Neural Network (error): p = 0.000088\n",
            "OCSVM (pyod) vs Autoencoder (reconstruction): p = 0.039853\n",
            "OCSVM (pyod) vs Combined (RF+AE): p = 0.000087\n",
            "OCSVM (pyod) vs One-Class SVM (with y): p = 0.000081\n",
            "OCSVM (pyod) vs Isolation Forest (with y): p = 0.000088\n",
            "OCSVM (pyod) vs LOF (with y): p = 0.000008\n",
            "OCSVM (pyod) vs NNFA (ξ=0): p = 0.000086\n",
            "PCA (pyod) vs COPOD (pyod): p = 0.000008\n",
            "PCA (pyod) vs Random Forest (error): p = 0.000088\n",
            "PCA (pyod) vs Neural Network (error): p = 0.000088\n",
            "PCA (pyod) vs Autoencoder (reconstruction): p = 0.003287\n",
            "PCA (pyod) vs Combined (RF+AE): p = 0.000087\n",
            "PCA (pyod) vs One-Class SVM (with y): p = 0.000081\n",
            "PCA (pyod) vs Isolation Forest (with y): p = 0.000088\n",
            "PCA (pyod) vs LOF (with y): p = 0.000008\n",
            "PCA (pyod) vs NNFA (ξ=0): p = 0.000086\n",
            "COPOD (pyod) vs Random Forest (error): p = 0.000088\n",
            "COPOD (pyod) vs Neural Network (error): p = 0.000088\n",
            "COPOD (pyod) vs Autoencoder (reconstruction): p = 0.000087\n",
            "COPOD (pyod) vs Combined (RF+AE): p = 0.000087\n",
            "COPOD (pyod) vs One-Class SVM (with y): p = 0.000081\n",
            "COPOD (pyod) vs Isolation Forest (with y): p = 0.000088\n",
            "COPOD (pyod) vs LOF (with y): p = 0.000008\n",
            "COPOD (pyod) vs NNFA (ξ=0): p = 0.000086\n",
            "Random Forest (error) vs Neural Network (error): p = 0.000851\n",
            "Random Forest (error) vs Autoencoder (reconstruction): p = 0.000088\n",
            "Random Forest (error) vs Combined (RF+AE): p = 0.000118\n",
            "Random Forest (error) vs One-Class SVM (with y): p = 0.000087\n",
            "Random Forest (error) vs Isolation Forest (with y): p = 0.000088\n",
            "Random Forest (error) vs LOF (with y): p = 0.000088\n",
            "Random Forest (error) vs NNFA (ξ=0): p = 0.000088\n",
            "Neural Network (error) vs Autoencoder (reconstruction): p = 0.000088\n",
            "Neural Network (error) vs Combined (RF+AE): p = 0.001014\n",
            "Neural Network (error) vs One-Class SVM (with y): p = 0.000088\n",
            "Neural Network (error) vs Isolation Forest (with y): p = 0.000088\n",
            "Neural Network (error) vs LOF (with y): p = 0.000088\n",
            "Autoencoder (reconstruction) vs Combined (RF+AE): p = 0.000088\n",
            "Autoencoder (reconstruction) vs One-Class SVM (with y): p = 0.000087\n",
            "Autoencoder (reconstruction) vs Isolation Forest (with y): p = 0.000088\n",
            "Autoencoder (reconstruction) vs NNFA (ξ=0): p = 0.000088\n",
            "Combined (RF+AE) vs One-Class SVM (with y): p = 0.000088\n",
            "Combined (RF+AE) vs Isolation Forest (with y): p = 0.000088\n",
            "Combined (RF+AE) vs LOF (with y): p = 0.000087\n",
            "Combined (RF+AE) vs NNFA (ξ=0): p = 0.000088\n",
            "One-Class SVM (with y) vs Isolation Forest (with y): p = 0.000088\n",
            "One-Class SVM (with y) vs LOF (with y): p = 0.000081\n",
            "One-Class SVM (with y) vs NNFA (ξ=0): p = 0.000088\n",
            "Isolation Forest (with y) vs LOF (with y): p = 0.000088\n",
            "Isolation Forest (with y) vs NNFA (ξ=0): p = 0.000088\n",
            "LOF (with y) vs NNFA (ξ=0): p = 0.000086\n",
            "\n",
            "Results saved to 'california_housing_nnfa0_results.xlsx'\n",
            "\n",
            "================================================================================\n",
            "STATISTICAL SIGNIFICANCE (Wilcoxon test, two-sided, for F1)\n",
            "================================================================================\n",
            "NNFA (ξ=0) vs Neural Network (error): p = 0.380273 -> NOT significant\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<IPython.core.display.Javascript object>"
            ],
            "application/javascript": [
              "\n",
              "    async function download(id, filename, size) {\n",
              "      if (!google.colab.kernel.accessAllowed) {\n",
              "        return;\n",
              "      }\n",
              "      const div = document.createElement('div');\n",
              "      const label = document.createElement('label');\n",
              "      label.textContent = `Downloading \"${filename}\": `;\n",
              "      div.appendChild(label);\n",
              "      const progress = document.createElement('progress');\n",
              "      progress.max = size;\n",
              "      div.appendChild(progress);\n",
              "      document.body.appendChild(div);\n",
              "\n",
              "      const buffers = [];\n",
              "      let downloaded = 0;\n",
              "\n",
              "      const channel = await google.colab.kernel.comms.open(id);\n",
              "      // Send a message to notify the kernel that we're ready.\n",
              "      channel.send({})\n",
              "\n",
              "      for await (const message of channel.messages) {\n",
              "        // Send a message to notify the kernel that we're ready.\n",
              "        channel.send({})\n",
              "        if (message.buffers) {\n",
              "          for (const buffer of message.buffers) {\n",
              "            buffers.push(buffer);\n",
              "            downloaded += buffer.byteLength;\n",
              "            progress.value = downloaded;\n",
              "          }\n",
              "        }\n",
              "      }\n",
              "      const blob = new Blob(buffers, {type: 'application/binary'});\n",
              "      const a = document.createElement('a');\n",
              "      a.href = window.URL.createObjectURL(blob);\n",
              "      a.download = filename;\n",
              "      div.appendChild(a);\n",
              "      a.click();\n",
              "      div.remove();\n",
              "    }\n",
              "  "
            ]
          },
          "metadata": {}
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<IPython.core.display.Javascript object>"
            ],
            "application/javascript": [
              "download(\"download_ffd840b1-eee7-4acf-aeef-8050021feea8\", \"california_housing_nnfa0_results.xlsx\", 7686)"
            ]
          },
          "metadata": {}
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<IPython.core.display.Javascript object>"
            ],
            "application/javascript": [
              "\n",
              "    async function download(id, filename, size) {\n",
              "      if (!google.colab.kernel.accessAllowed) {\n",
              "        return;\n",
              "      }\n",
              "      const div = document.createElement('div');\n",
              "      const label = document.createElement('label');\n",
              "      label.textContent = `Downloading \"${filename}\": `;\n",
              "      div.appendChild(label);\n",
              "      const progress = document.createElement('progress');\n",
              "      progress.max = size;\n",
              "      div.appendChild(progress);\n",
              "      document.body.appendChild(div);\n",
              "\n",
              "      const buffers = [];\n",
              "      let downloaded = 0;\n",
              "\n",
              "      const channel = await google.colab.kernel.comms.open(id);\n",
              "      // Send a message to notify the kernel that we're ready.\n",
              "      channel.send({})\n",
              "\n",
              "      for await (const message of channel.messages) {\n",
              "        // Send a message to notify the kernel that we're ready.\n",
              "        channel.send({})\n",
              "        if (message.buffers) {\n",
              "          for (const buffer of message.buffers) {\n",
              "            buffers.push(buffer);\n",
              "            downloaded += buffer.byteLength;\n",
              "            progress.value = downloaded;\n",
              "          }\n",
              "        }\n",
              "      }\n",
              "      const blob = new Blob(buffers, {type: 'application/binary'});\n",
              "      const a = document.createElement('a');\n",
              "      a.href = window.URL.createObjectURL(blob);\n",
              "      a.download = filename;\n",
              "      div.appendChild(a);\n",
              "      a.click();\n",
              "      div.remove();\n",
              "    }\n",
              "  "
            ]
          },
          "metadata": {}
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<IPython.core.display.Javascript object>"
            ],
            "application/javascript": [
              "download(\"download_5b5ea805-a8ac-4437-bd44-4b6a887bfb3e\", \"pairwise_wilcoxon_matrix.csv\", 5743)"
            ]
          },
          "metadata": {}
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Files downloaded automatically.\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 1400x700 with 1 Axes>"
            ],
            "image/png": "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tdd055136siRI6pRo0ahcWVmZqpbt276/fff9cgjj6hhw4b6+OOPNWzYMJ09e1aPP/64wsPD9e677+qJJ55Q/fr1bUse5P3SX5jz58/nm5nm6+tbopmHRfn222912223qVGjRpo6daoyMzM1f/58derUSbt27VJISIh69+5tK5507drV7vmrVq1S8+bNbetU/vrrr+rUqZPq1aunp59+WpUrV9ZHH32kqKgoffLJJ/rnP/9p9/yHHnpItWrV0uTJk3Xu3LkSx5+cnJxvPHbv3q3WrVvn+xhyu3bt9Oabb2r//v1q0aJFkcfdt2+f7rnnHt1///0aPXq0/vGPf5Q4NunC7LaGDRtqxowZ2rVrl95++23Vrl1bM2fOlFT89ViU7du3q3Xr1nZtGRkZ2rhxo7p06aJrrrnGoRjnzZunvn376t5771V2drY+/PBD3XXXXVq/fr169+7tcK5z587VihUr9Omnn+qNN95QlSpVbEu1TJ06VdOmTVP37t314IMPat++fXrjjTf0008/adu2bXazRIt6f3n//feVlpam+++/XxaLRS+//LL69eunQ4cOFTnT9I033lDz5s3Vt29fVahQQZ999pkeeugh5ebm6uGHH3Yov9OnTxfYfumSBCV933HEAw88oOjoaD3yyCNq1qyZ/vrrL/3nP/9RXFxcvnPgUo6M2eeff66BAweqRYsWmjFjhs6cOaORI0eqXr16JY71YlarVY8++qhGjRpV6DX3yy+/KCcnx+7TI9KFJWAiIyO1e/duW9vu3bvVtGlTu+KudOHali4ssxAcHFxoPMuXL9fw4cN13XXXacaMGTp+/LjmzZunbdu2affu3SWaIV6rVi298cYbevDBB/XPf/7T9keii5cnKk5GRoa6du2qP//8U/fff7+uueYabd++XZMmTdKxY8fyFbqXLVumv//+W2PGjLGtU/3WW2/pscceU//+/fX444/r77//1s8//6wffvhBgwYNsnt+69atHXpvAQCgWAYAALCzbNkyQ5Lx008/FdonICDAuPbaa22Pp0yZYlz8Y/XVV181JBknT54s9Bg//fSTIclYtmxZvn1du3Y1JBmLFi0qcF/Xrl1tjzdt2mRIMurVq2ekpqba2j/66CNDkjFv3jxbW4MGDYyhQ4cWe8yiYhs6dKjRoEED2+M1a9YYkowXXnjBrl///v0Ni8Vi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sWNHvf7663rooYcUFham++67T6GhoUpLS9PmzZu1bt06vfDCC5Iu3IRpzpw5uvXWWzVo0CCdOHFCr7/+upo0aaKff/75svO6WK1atTRp0iRNmzZNt956q/r27at9+/Zp4cKFuu666zR48GCnvE5hevToIS8vL91+++26//77lZ6errfeeku1a9cu8I8LV6ok7zuOnE9paWmqX7+++vfvr1atWqlKlSr69ttv9dNPP2n27NlOiXn69Om644471KlTJw0fPlxnzpzRggULFBERka/wP2zYML3zzjs6fPiw3aclLlazZk1FRUXla587d64k5dv34osvqmPHjuratavGjBmjo0ePavbs2erRo4duvfVWW7/27dvrrrvu0qRJk3TixAk1adJE77zzjhISErRkyZIic6xYsaJmzpyp4cOHq2vXrrrnnnt0/PhxzZs3TyEhIXriiSdsfUeMGKE5c+aoZ8+eGjlypE6cOKFFixapefPmdrN8fXx81KxZM61atUpNmzZV9erVFRERoYiIiCJjyfPUU09p3bp16tOnj4YNG6Y2bdro3Llz+uWXXxQdHa2EhIQC11G+WI8ePVS3bl116tRJderUUVxcnBYsWKDevXvb/eyJiYnR6dOndccddzgUGwAARTIAAICdZcuWGZJsX15eXkbdunWNW265xZg3b56Rmpqa7zlTpkwxLv6xunHjRuOOO+4wgoKCDC8vLyMoKMi45557jP3799s9b+3atUazZs2MChUqGJKMZcuWGYZhGF27djWaN29eYHxdu3Y1unbtanu8adMmQ5LxwQcfGJMmTTJq165t+Pj4GL179zb++OOPfM+fPXu2Ua9ePcPb29vo1KmTsXPnznzHLCq2oUOHGg0aNLDrm5aWZjzxxBNGUFCQUbFiRSM0NNSYNWuWkZuba9dPkvHwww/ni6lBgwbG0KFDC8z3YsePHzeGDx9u1KxZ0/Dy8jJatGhhi+vS4/Xu3bvY45Wkb4MGDezOi4u/Dh8+XOzzv/32W6NTp06Gj4+P4e/vb9x+++3Gb7/9VmDfb775xpBkWCwWIzExscA+Bw8eNIYMGWLUrVvXqFixolGvXj2jT58+RnR0tK1P3rn8008/FRufYfzvPC7sa9OmTXb9T58+bYwcOdKoUaOG4evra3Tt2tXh1ypq3DMyMoyRI0caAQEBhp+fnzFgwADjxIkT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j0u6MAX61KlTkqS4uDidOXNGkhQbG6uUlBRJ0t69e5Weni5J2r17tzIzMyVJO3fuVHZ2tqxWq3bu3Cmr1ars7Gzt3LlTkpSZmandu3dLktLT07V3715JUkpKimJjYyVJZ86cUVxcnG3c9u/fL0k6fvy4Dh48KElKSkrS4cOHyYmcyImcyImcyImcyImcynVOkpSRkeHSOUnSX3/9Va6/T+RETuRETuREThkZGVock62F1rsV12WxYtq+qq9C/qW4Lov147Wv6OuG/1Zcl8X6IXKWNjaZorgui7W9xUv6LnSq4ros1raIGdr8j+cU12WxtjZ7UVubvag97V/TyspjbH2+C52q7S1eUlyXxdrYZIp+iJyluC6L9XXDf+vHa19RXJfF+irkX4pp+6riuizWF8FPa9d1cxXXZbE+rz9Ra+uO0+KYbMXFxTn1++QIi1GSEq8TJSUlqV69etq+fbs6dOhga58wYYK+//77Apc82Lx5s+6++2698MILat++vX7//Xc9/vjjGj16tJ599tkCX6egmbbBwcE6c+aMqlat6jJ/Xbga/2JCTuRETuRETuRETuRETuRUljnt3r1bvbu21cY176lZeLhyrFZ5enrIIott+0IeuXbbFTw9Zciw287NNeTp4WG3nWsYF2IvZluSPCyWArf37dunm+4YpM82/ai2bduWy+8TOZETOZETOZGT1WrV8uXLNXr0aLmD3377TWFhYZKu/Pt07tw5BQQEKCUlRf7+/oW+pmlF2+zsbPn6+io6OlpRUVG29qFDh+rs2bNau3Ztvud07txZ119/vWbNmmVrW7lypcaMGaP09HR5eBQ/cTg1NdWhgQEAAADgXnbt2qV14zpqarcrX8OuNE3dnKW+c7ardevWZocCAIBpTp06pTVr1igsLEy+vr5OOWZcXJwGDx6slStXKjw83CnH9PPzc+pNyBytTZq2pq2Xl5fatGmjjRs32oq2ubm52rhxox555JECn5ORkZGvMJtX2Tap9gwAAADAhSyOydbAycsV/v+zYVxNXHy8Fs8epL5mBwIAgMlq1qypUaNGlcqxw8PD3f6Po6YVbSVp3LhxGjp0qNq2bat27dpp7ty5OnfunIYPHy5JGjJkiOrVq6cZM2ZIkm6//XbNmTNH1157rW15hGeffVa33367rXgLAAAAoPxKTjeUWbWpFBRpdigFykzO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J59U586dS/yaAAAAAAAAAOCqHF4eITAwUKtXr1Zubm6BX7t27bqsAObMmaPRo0dr+PDhatasmRYtWiRfX18tXbq00OdYrVbde++9mjZtmho1anRZrwsAAAAAAAAArsjhom2bNm0UExNT6P7iZuEWJDs7WzExMerevfv/AvLwUPfu3bVjx45Cn/fcc8+pdu3aGjlyZLGvkZWVpdTUVLsvScrNzbX9W9C21Wp1aDsv54u3c3Jy8m0bhpFvW1K+bavVmm87NzfXoW1yIidyIidyIidyIidyIidyIidyIidyIidyIidycu2cHOFw0fapp55Sx44dC93fpEkTbdq0yeEXlqRTp07JarWqTp06du116tRRcnJygc/5z3/+oyVLluitt95y6DVmzJihgIAA21dwcLCkC8srSFJiYqISExMlSYcPH1ZSUpIk6eDBgzp+/Lgkaf/+/Tp16pQkKS4uTmfOnJEkxcbGKiUlRZK0d+9epaenS5J2796tzMxMSdLOnTuVnZ0tq9WqnTt3ymq1Kjs7Wzt37pQkZWZmavfu3ZKk9PR07d27V5KUkpKi2NhYSdKZM2cUFxdnG7P9+/dLko4fP66DBw9KkpKSknT48GFyIidyIidyIidyIidyIidyIidyIidyIidyIidycuGcHGEx8krGJkhKSlK9evW0fft2dejQwdY+YcIEff/99/rhhx/s+qelpally5ZauHChbrvtNknSsGHDdPbs2UJvRJaVlaWsrCzb49TUVAUHB+vMmTOqWrWqraru4eFht221WmWxWIrd9vDwkMVisdvOycmRp6en3bZ0oVp/8XaFChVsFfe87dzcXHl6etpt5+bmyjCMYrcLyoOcyImcyImcyImcyImcyImcyImcyImcyImcyImcXCOnc+fOKSAgQCkpKfL391dhHC7aHjp0SA0bNpTFUvKbjRUmOztbvr6+io6OVlRUlK196NChOnv2rNauXWvXf8+ePbr22mttAyPJ7huxb98+NW7cuMjXTE1NdWhgAAAAAAAAAMCZHK1NOrw8QmhoqE6ePGl7PHDgQNv04svl5eWlNm3aaOPGjba23Nxcbdy40W7mbZ6wsDD98ssv2rNnj+2rb9++uvHGG7Vnzx7b0gcAAAAAAAAA4K4qONrx0gm5X3zxhWbMmHHFAYwbN05Dhw5V27Zt1a5dO82dO1fnzp3T8OHD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DQ01O2yXwzg6D9e283BeOge/4zgP56RzPPbYY3rnnXfUs2fPIsfxww8/lKenp5YtW+bWBZ7Swu+KzsH56Dzl5j3SgCmuv/56Y/369YbVai2y39GjR42JEycac+bMKaPI3E9ISIjx+uuvG2fOnCmy3/bt242BAwcaL774YtkE5mYYR+dZtGiRkZ2d7VDfX3/91fj2229LOSL3VL9+feOuu+4yPv/880LHMyEhwZg+fbrRoEED48033yzjCN0H56Rz3H333UZsbGyx/f7++2/jjTfeMJYsWVIGUbkfxtF5uLadh/PSOfgdx3k4J53j6aefNk6dOuVQ3y+//NL45JNPSjki98Tvis7B+eg85eU9kpm2cHvnz59XxYoVS61/ecE4wtXExcUpPDzcob7nz5/XkSNH1Lhx41KOCgBcj9Vq1bZt29SyZUtVrVrV7HAAAFcZflcEzMECGXB7Jf1hwA+PgjGOcDWOFmylC+cjBVsA5ZWnp6d69OihM2fOmB2K2zt//rwqVKig2NhYs0MBimUYhk6cOGF2GG5jypQp+uOPP8wOwy1d/LvfoUOHStQfBeN8dL6srCxlZWWZHYZTMdPWJOPGjXO475w5c0oxEvf32muvOdz3scceK8VI3Bvj6DzVqlWTxWJxqO/p06dLORr39fPPPzvct2XLlqUYifvjnHSOfv36Odx39erVpRiJe2McS0fbtm01c+ZM3XzzzWaH4vYaNWqkTz/9VK1atTI7FLdmtVq1fPlybdy4USdOnFBubq7d/u+++86kyNyHr6+v/vjjD9u6v71799bbb7+twMBASdLx48cVFBQkq9VqZphuIzIyUrGxseratatGjhzJTbMuk4eHh20M+/fvr0qVKpkdklvifHSOb775Rq+++qp27Nih1NRUSZK/v786dOigcePGqXv37iZHeGUo2prkxhtvtHu8a9cu5eTk6B//+Ickaf/+/fL09FSbNm34D00xGjZsaPf45MmTysjIsH088OzZs/L19VXt2rUd+qtgecU4Os8777xj2/7rr7/0wgsvqGfPnurQoYMkaceOHfrqq6/07LPP6oknnjArTJfn4eEhi8ViuwNoUfhlpWick84xfPhw27ZhGPr0008VEBCgtm3bSpJiYmJ09uxZ9evXT8uWLTMrTJfHOJaODRs2aNKkSXr++efVpk0bVa5c2W6/v7+/SZG5nyVLlmj16tV69913Vb16dbPDcVuPPPKIli9frt69eyswMDDfz/JXX33VpMjch4eHh5KTk1W7dm1Jkp+fn/bu3atGjRpJulC0DQwMzFcQR+F2796tZcuW6YMPPlBOTo7uvvtujRgxgps9lcCePXtsY5idna2BAwdq5MiRateundmhuR3OxyvzzjvvaNSoUerfv7969uypOnXqSLrw3vj1118rOjpaS5Ys0X333WdypFfArMV08T+zZ882br/9duP06dO2ttOnTxt33HGH8corr5gYmft57733jE6dOhnx8fG2tvj4eKNz587GypUrTYzMvTCOztOvXz9j/vz5+drnz59v3HHHHWUfkBtJSEiwfX366adG48aNjUWLFhl79+419u7dayxatMgIDQ01Pv30U7NDdSuck84xYcIEY9SoUUZOTo6tLScnxxgzZozx5JNPmhiZe2Ecncdisdi+PDw8bF95j+G4yMhIo0qVKoa3t7fRtGlT49prr7X7gmNq1KhhfP7552aH4dYsFotx/Phx2+MqVaoYBw8etD1OTk7m+r5M2dnZxieffGL06dPHqFixotGiRQtj7ty5xtmzZ80OzW2cP3/e+OSTT4zbb7/dqFixotG8eXNj9uzZxokTJ8wOze1wPl6e0NBQY8GCBYXuf/31140mTZqUYUTOx0xbF1CvXj19/fXXat68uV17bGysevTooaSkJJMicz+NGzdWdHS0rr32Wrv2mJgY9e/fX4cPHzYpMvfCODpPlSpVtGfPHjVp0sSu/ffff1dkZKTS09NNisy9tGvXTlOnTlWvXr3s2r/44gs9++yziomJMSky98M56Ry1atXSf/7zH9snZPLs27dPHTt21F9//WVSZO6FcXSe77//vsj9Xbt2LaNI3N+0adOK3D9lypQyisS9BQUFafPmzWratKnZobgtR2basjzC5cnOztann36qpUuX6rvvvlPHjh2VlJSk48eP66233tLAgQPNDtFtZGVlaeHChZo0aZKys7Pl5eWlAQMGaObMmbalPFA0zsfLU6lSJe3duzff/yPz7Nu3T5GRkcrMzCzjyJyngtkBQEpNTdXJkyfztZ88eVJpaWkmROS+jh07ppycnHztVqtVx48fNyEi98Q4Ok+NGjW0du1ajR8/3q597dq1qlGjhklRuZ9ffvkl3xIe0oVlPX777TcTInJfnJPOkZOTo/j4+Hz/SYyPj+djqiXAODoPRVnnoSjrHOPHj9e8efO0YMECh9dVhz2LxWI3dpc+RsnFxMTYPo7u7e2tIUOG6PXXX7f9MXv+/Pl67LHHKJI5YOfOnVq6dKk+/PBDVa5cWU8++aRGjhypo0ePatq0abrjjjv0448/mh2mS+N8vDLNmzfXkiVL9PLLLxe4f+nSpWrWrFkZR+VcFG1dwD//+U8NHz5cs2fPtq0D88MPP+ipp54q0c06IN188826//779fbbb6t169aSLrwRPvjgg26/AHVZYhydZ9q0aRo1apQ2b96s9u3bS7pwfW/YsEFvvfWWydG5j/DwcM2YMUNvv/22vLy8JF34i/SMGTMUHh5ucnTuhXPSOYYPH66RI0fq4MGDdj+7X3rpJbs1W1E0xtG5zp49qyVLliguLk7ShV9mRowYoYCAAJMjc08xMTF2Y3npJ5BQtP/85z/atGmTvvzySzVv3jzf3eS50WDxDMNQ06ZNbYXa9PR0XXvttfLw8LDth+NatGih+Ph49ejRQ0uWLNHtt98uT09Puz733HOPHn/8cZMidA9z5szRsmXLtG/fPvXq1UsrVqxQr169bOdlw4YNtXz5coWEhJgbqIvjfLxys2fPVp8+fbRhwwZ1797dbk3bjRs36tChQ/r8889NjvLKsDyCC8jIyNCTTz6ppUuX6vz585KkChUqaOTIkZo1a1a+G0mgcCdPntTQoUO1YcMG238Mc3Jy1LNnTy1fvtz20SIUjXF0rh9++EGvvfaa7Re/8PBwPfbYY7aCGYr3448/6vbbb5dhGGrZsqUk6eeff5bFYtFnn33GjQ9KiHPyyuXm5uqVV17RvHnzdOzYMUlSYGCgHn/8cY0fPz7ff7pRMMbReXbu3KmePXvKx8fH9p74008/KTMzU19//bXtj7Ao3okTJ3T33Xdr8+bNdjdkvfHGG/Xhhx+qVq1a5gboJor7wws3GizexTcSLcrQoUNLOZKrw/PPP68RI0aoXr16Zofi1kJDQzVixAgNGzas0OUPsrOz9cEHH3BuFoHz0TkSEhL0xhtv6L///a+Sk5MlSXXr1lWHDh30wAMPuP0fDyjaupBz587p4MGDki6sKUqx9vLt379fcXFxslgsCgsLYy2ty8Q4wpWcO3dO7733nuLj4yVdKDQOGjSI90qYLjU1VZLk7+9vciTujXG8Mp07d1aTJk301ltvqUKFCx+my8nJ0ahRo3To0CFt2bLF5Ajdx8CBA3Xo0CGtWLHC9mmO3377TUOHDlWTJk30wQcfmBwh8D9Wq5U/cAHAVYqirYs5evSoJKl+/fomR+L+8k5t1n26MozjlbNarVqzZo3dRyz79u3Lf7BhGs5J5zl58qT27dsnSQoLC1PNmjVNjsg9MY5XzsfHR7t371ZYWJhd+2+//aa2bdsqIyPDpMjcT0BAgL799ltdd911du0//vijevToobNnz5oTmJu6+Pr+xz/+wUxlJ9m/f7+WLFmiFStW2D6pAAC4uniYHQAufDTwueeeU0BAgBo0aKAGDRqoatWqev7557kJx2VYsWKFWrRoIR8fH/n4+Khly5Z69913zQ7L7TCOzvH777+rWbNmGjJkiFavXq3Vq1dr8ODBat68uW1mPRxz8OBBPfroo+revbu6d++uxx9/nDG8DJyTznHu3DmNGDFCgYGB6tKli7p06aLAwECNHDmS4lgJMI7O4+/vryNHjuRrT0xMlJ+fnwkRua/c3Nx8669KUsWKFfm/eQkUdH0HBQVxfV+BjIwMLVu2TJ07d1azZs30/fffa9y4cWaHBQCm6927t+0PWBdvuzuKti7gX//6lxYsWKCXXnpJu3fv1u7duzV9+nTNnz9fzz77rNnhuZU5c+bowQcfVK9evfTRRx/po48+0q233qoHHnhAr776qtnhuQ3G0Xkee+wxNWrUSImJidq1a5d27dqlI0eOqGHDhnrsscfMDs9tfPXVV2rWrJl+/PFHtWzZUi1bttR///tfNW/eXN98843Z4bkVzknnGDdunL7//nt99tlnOnv2rM6ePau1a9fq+++/1/jx480Oz20wjs4zcOBAjRw5UqtWrVJiYqISExP14YcfatSoUbrnnnvMDs+t3HTTTXr88ceVlJRka/vzzz/1xBNP6OabbzYxMvfC9e08//3vfzVq1CgFBgZqzpw52rFjhzZt2qT//ve/euqpp8wODwBMt2XLFmVmZubbdnsGTBcYGGisXbs2X/uaNWuMoKAgEyJyXyEhIcY777yTr3358uVGSEiICRG5J8bReXx9fY2ff/45X/uePXuMypUrmxCRe4qMjDQmTpyYr33ixInGtddea0JE7otz0jlq1KhhbNq0KV/7d999Z9SsWbPsA3JTjKPzZGVlGY899pjh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kJ6enotpiOhrDRo0KEfXbdq06RsnIfp+sGhLRERERERERERElIdk//UnERERERER0VdKSUkRHYGIiEh2WLQlIiIiIiIijUpPT8f8+fNRtmxZFC5cGHfv3gUAzJ49G+7u7oLTERER5X0s2hIREREREZFGLVy4EJs3b8bSpUuho6OjGrewsMDGjRsFJiMiIpIHFm2JiIiIiIhIo7Zs2YINGzagb9++0NLSUo1bWVnh1q1bApMRERHJA4u2REREREREpFHR0dGoVq1apvGMjAy8efNGQCIiIiJ5YdGWiIiIiIiINMrMzAx+fn6Zxvfu3Qtra2sBiYiIiORFW3QAIiIiIiIiyl/mzJmDAQMGIDo6GhkZGdi/fz9u376NLVu24MiRI6LjERER5XkKSZIk0SGIiIiIiIgof/Hz84OrqysCAgLw6tUr1K1bF3PmzIG9vb3oaERERHkei7ZEREREREREREREeQjbIxAREREREdE3ceXKFYSEhAAAzM3N2c+WiIgoh1i0JSIiIiIiIo169OgRevXqBR8fHxQrVgwAkJCQgJYtW2Lnzp0wMjISG5CIiCiPU4oOQERERERERPmLs7MzXr58iaCgIDx9+hRPnz7FzZs38eLFC4wdO1Z0PCIiojyPPW2JiIiIiIhIo4oWLQovLy/Ur19fbfzixYuwt7dHQkKCmGBEREQywZW2REREREREpFEZGRkoUKBApvECBQogIyNDQCIiIiJ5YdGWiIiIiIiINKpVq1YYN24cHj58qBqLjo7GhAkT0Lp1a4HJiIiI5IHtEYiIiIiIiEij7t+/j86dOyMoKAjly5dXjVlYWODQoUMoV66c4IRERER5G4u2REREREREpHGSJMHLywu3bt0CANSqVQtt2rQRnIqIiEgeWLQlIiIiIiIijdqyZQt69uyJggULqo2npqZi586d6N+/v6BkRERE8sCiLREREREREWmUlpYWYmJiYGxsrDYeHx8PY2NjpKenC0pGREQkDzyIjIiIiIiIiDRKkiQoFIpM4w8ePEDRokUFJCIiIpIXbdEBiIiIiIiIKH+wtraGQqGAQqFA69atoa39fx8509PTERERgXbt2glMSEREJA8s2hIREREREZFGdO3aFQBw/fp1ODg4oHDhwqo5HR0dVKpUCT/++KOgdERERPLBnrZERERERESkUZ6enujZsyd0dXVFRyEiIpIlFm2JiIiIiIiIiIiI8hC2RyAiIiIiIiKNUiqVWR5E9k56enoupiEiIpIfFm2JiIiIiIhIo/bv369WtH3z5g2uXbsGT09PuLi4CExGREQkD2yPQERERERERLli+/bt2LVrFw4ePCg6ChERUZ7Goi0RERERERHlirt378LS0hKvXr0SHYWIiChPU4oOQERERERERPlfcnIyVq5cibJly4qOQkRElOexpy0RERERERFplKGhoVpPW0mS8PLlS+jr6+Pvv/8WmIyIiEge2B6BiIiIiIiINMrT01PttVKphJGRERo2bAhDQ0NBqYiIiOSDRVsiIiIiIiLKNTdv3oSFhYXoGERERHkae9oSERERERHRN/Xy5Uts2LABDRo0gJWVleg4REREeR6LtkRERERERPRNnDlzBgMGDECZMmXw+++/o1WrVrhw4YLoWERERHkeDyIjIiIiIiIijYmNjcXmzZvh7u6OFy9eoEePHnj9+jX++ecfmJmZiY5HREQkC1xpS0RERERERBrRqVMn1KhRA4GBgXBzc8PDhw+xatUq0bGIiIhkhyttiYiIiIiISCOOHj2KsWPHYuTIkTA1NRUdh4iISLa40paIiIiIiIg04uzZs3j58iXq1auHhg0bYvXq1Xjy5InoWERERLKjkCRJEh2CiIiIiIiI8o/ExETs2rULHh4euHjxItLT07F8+XI4OTnBwMBAdDwiIqI8j0VbIiIiIiIi+mZu374Nd3d3bN26FQkJCWjbti0OHTokOhYREVGexqItERERERERfXPp6ek4fPgwPDw8WLQlIiL6BBZtiYiIiIiIiIiIiPIQHkRGRERERERERERElIewaEtERERERERERESUh7BoS0RERERERERERJSHsGhLRERERERERERElIewaEtERERERERERESUh7BoS0RERERERERERJSHsGhLRERERERERERElIewaEtERERERERERESUh/w/7ZLWmYufld0AAAAASUVORK5CYII=\n"
          },
          "metadata": {}
        }
      ],
      "source": [
        "import sys\n",
        "!{sys.executable} -m pip install pyod openpyxl\n",
        "\n",
        "import numpy as np\n",
        "import pandas as pd\n",
        "import math\n",
        "import torch\n",
        "import torch.nn as nn\n",
        "import torch.optim as optim\n",
        "import random\n",
        "import matplotlib.pyplot as plt\n",
        "from sklearn.preprocessing import StandardScaler\n",
        "from scipy.stats import wilcoxon\n",
        "from sklearn.metrics import roc_auc_score\n",
        "from sklearn.datasets import fetch_california_housing\n",
        "import warnings\n",
        "warnings.filterwarnings('ignore')\n",
        "\n",
        "from pyod.models import abod, hbos, iforest, knn, lof, ocsvm, pca, copod\n",
        "from sklearn.ensemble import IsolationForest as SklearnIForest\n",
        "from sklearn.svm import OneClassSVM\n",
        "from sklearn.neighbors import LocalOutlierFactor\n",
        "from sklearn.ensemble import RandomForestRegressor\n",
        "from sklearn.neural_network import MLPRegressor\n",
        "\n",
        "# ------------------------------------------------------------\n",
        "# 1. Dataset creation (California Housing with 400 outliers)\n",
        "# ------------------------------------------------------------\n",
        "def create_california_dataset(seed_shuffle):\n",
        "    \"\"\"\n",
        "    Создаёт датасет California Housing с 400 структурными выбросами:\n",
        "       200 самых дорогих домов заменяются на минимальную стоимость,\n",
        "       200 самых дешёвых домов заменяются на максимальную стоимость.\n",
        "    \"\"\"\n",
        "    california = fetch_california_housing()\n",
        "    df = pd.DataFrame(california.data, columns=california.feature_names)\n",
        "    df['MedHouseVal'] = california.target\n",
        "\n",
        "    Smax = df['MedHouseVal'].max()\n",
        "    Smin = df['MedHouseVal'].min()\n",
        "\n",
        "    # Сортировка по убыванию стоимости\n",
        "    df_sorted = df.sort_values('MedHouseVal', ascending=False).reset_index(drop=True)\n",
        "\n",
        "    n_outliers_top = 200\n",
        "    n_outliers_bottom = 200\n",
        "    outlier_indices = []\n",
        "\n",
        "    # Первые 200 (самые дорогие) -> заменяем на Smin\n",
        "    for i in range(n_outliers_top):\n",
        "        df_sorted.loc[i, 'MedHouseVal'] = Smin\n",
        "        outlier_indices.append(i)\n",
        "\n",
        "    # Последние 200 (самые дешёвые) -> заменяем на Smax\n",
        "    last_start = len(df_sorted) - n_outliers_bottom\n",
        "    for i in range(last_start, len(df_sorted)):\n",
        "        df_sorted.loc[i, 'MedHouseVal'] = Smax\n",
        "        outlier_indices.append(i)\n",
        "\n",
        "    # Присваиваем метки выбросов\n",
        "    df_sorted['is_outlier'] = 0\n",
        "    df_sorted.loc[outlier_indices, 'is_outlier'] = 1\n",
        "\n",
        "    # Перемешивание\n",
        "    df_shuffled = df_sorted.sample(frac=1, random_state=seed_shuffle).reset_index(drop=True)\n",
        "\n",
        "    X = df_shuffled.drop(['MedHouseVal', 'is_outlier'], axis=1).values.astype(np.float32)\n",
        "    y = df_shuffled['MedHouseVal'].values.astype(np.float32).reshape(-1, 1)\n",
        "    true_outliers = df_shuffled['is_outlier'].values.astype(int)\n",
        "    return X, y, true_outliers\n",
        "\n",
        "# ------------------------------------------------------------\n",
        "# 2. Helper: top‑K outliers\n",
        "# ------------------------------------------------------------\n",
        "def get_top_k_outliers(scores, k):\n",
        "    idx = np.argsort(scores)[-k:]\n",
        "    pred = np.zeros(len(scores), dtype=int)\n",
        "    pred[idx] = 1\n",
        "    return pred\n",
        "\n",
        "# ------------------------------------------------------------\n",
        "# 3. NNFA algorithm – ξ = 0, возвращает (pred, scores)\n",
        "# ------------------------------------------------------------\n",
        "def run_nnfa_original(X, y, n_outliers_desired, random_state):\n",
        "    ksi = 0   # фиксированное значение\n",
        "    torch.manual_seed(random_state)\n",
        "    np.random.seed(random_state)\n",
        "    random.seed(random_state)\n",
        "\n",
        "    Q, N_x = X.shape[0], X.shape[1]\n",
        "    N_y = 1\n",
        "\n",
        "    def scale_to_minus1_1(data):\n",
        "        min_val = data.min(axis=0)\n",
        "        max_val = data.max(axis=0)\n",
        "        range_val = max_val - min_val\n",
        "        range_val[range_val == 0] = 1.0\n",
        "        scaled = 2.0 * (data - min_val) / range_val - 1.0\n",
        "        return scaled, min_val, range_val\n",
        "\n",
        "    X_scaled, _, _ = scale_to_minus1_1(X)\n",
        "    y_scaled, _, _ = scale_to_minus1_1(y)\n",
        "    X_tensor = torch.tensor(X_scaled, dtype=torch.float32)\n",
        "    y_tensor = torch.tensor(y_scaled, dtype=torch.float32)\n",
        "\n",
        "    log2q = math.log2(Q)\n",
        "    N_min = (N_y * Q) / ((1 + log2q) * (N_x + N_y)) + 1\n",
        "    N_max = (N_y / (N_x + N_y)) * ((Q / N_x + 1) * (N_x + N_y + 1) + 1) - 1\n",
        "    if N_max > Q:\n",
        "        N_max = min(Q // 2, 20)\n",
        "    N_lim = N_min + ksi * (N_max - N_min)\n",
        "    N_start = max(1, int(np.ceil(N_min)))\n",
        "    N_end = max(N_start, int(np.ceil(N_lim)))\n",
        "\n",
        "    error_matrix = []\n",
        "    for N in range(N_start, N_end + 1):\n",
        "        model = nn.Sequential(\n",
        "            nn.Linear(N_x, N),\n",
        "            nn.Tanh(),\n",
        "            nn.Linear(N, N_y),\n",
        "        )\n",
        "        criterion = nn.MSELoss()\n",
        "        optimizer = optim.Adam(model.parameters(), lr=0.01)\n",
        "        model.train()\n",
        "        for epoch in range(500):\n",
        "            optimizer.zero_grad()\n",
        "            outputs = model(X_tensor)\n",
        "            loss = criterion(outputs, y_tensor)\n",
        "            loss.backward()\n",
        "            optimizer.step()\n",
        "        model.eval()\n",
        "        with torch.no_grad():\n",
        "            predictions = model(X_tensor).numpy().flatten()\n",
        "            errors = (predictions - y_scaled.flatten()) ** 2\n",
        "        error_matrix.append(errors)\n",
        "\n",
        "    error_matrix = np.array(error_matrix)\n",
        "    scores = np.mean(error_matrix, axis=0)\n",
        "    pred = get_top_k_outliers(scores, n_outliers_desired)\n",
        "    return pred, scores\n",
        "\n",
        "# ------------------------------------------------------------\n",
        "# 4. Wrappers for standard methods – возвращают (pred, scores)\n",
        "# ------------------------------------------------------------\n",
        "def run_pyod_detector(model, X_scaled, n_outliers):\n",
        "    model.fit(X_scaled)\n",
        "    scores = model.decision_scores_\n",
        "    pred = get_top_k_outliers(scores, n_outliers)\n",
        "    return pred, scores\n",
        "\n",
        "def run_random_forest(X, y, n_outliers, rs):\n",
        "    rf = RandomForestRegressor(n_estimators=100, random_state=rs)\n",
        "    rf.fit(X, y.ravel())\n",
        "    scores = (rf.predict(X) - y.ravel()) ** 2\n",
        "    pred = get_top_k_outliers(scores, n_outliers)\n",
        "    return pred, scores\n",
        "\n",
        "def run_neural_network(X, y, n_outliers, rs):\n",
        "    mlp = MLPRegressor(hidden_layer_sizes=(20, 10), random_state=rs, max_iter=500)\n",
        "    mlp.fit(X, y.ravel())\n",
        "    scores = (mlp.predict(X) - y.ravel()) ** 2\n",
        "    pred = get_top_k_outliers(scores, n_outliers)\n",
        "    return pred, scores\n",
        "\n",
        "def run_autoencoder(X_scaled, n_outliers, rs):\n",
        "    torch.manual_seed(rs)\n",
        "    np.random.seed(rs)\n",
        "    random.seed(rs)\n",
        "    input_dim = X_scaled.shape[1]\n",
        "    class AE(nn.Module):\n",
        "        def __init__(self):\n",
        "            super().__init__()\n",
        "            self.encoder = nn.Sequential(nn.Linear(input_dim, 16), nn.ReLU(), nn.Linear(16, 4))\n",
        "            self.decoder = nn.Sequential(nn.Linear(4, 16), nn.ReLU(), nn.Linear(16, input_dim))\n",
        "        def forward(self, x):\n",
        "            return self.decoder(self.encoder(x))\n",
        "    ae = AE()\n",
        "    optimizer = optim.Adam(ae.parameters(), lr=0.01)\n",
        "    criterion = nn.MSELoss()\n",
        "    X_tensor = torch.tensor(X_scaled, dtype=torch.float32)\n",
        "    ae.train()\n",
        "    for _ in range(300):\n",
        "        optimizer.zero_grad()\n",
        "        loss = criterion(ae(X_tensor), X_tensor)\n",
        "        loss.backward()\n",
        "        optimizer.step()\n",
        "    ae.eval()\n",
        "    with torch.no_grad():\n",
        "        recon = ae(X_tensor).numpy()\n",
        "        scores = np.mean((recon - X_scaled) ** 2, axis=1)\n",
        "    pred = get_top_k_outliers(scores, n_outliers)\n",
        "    return pred, scores\n",
        "\n",
        "def run_combined_rf_ae(X, y, X_scaled, n_outliers, rs):\n",
        "    rf = RandomForestRegressor(n_estimators=100, random_state=rs)\n",
        "    rf.fit(X, y.ravel())\n",
        "    rf_err = (rf.predict(X) - y.ravel()) ** 2\n",
        "    torch.manual_seed(rs)\n",
        "    np.random.seed(rs)\n",
        "    random.seed(rs)\n",
        "    input_dim = X_scaled.shape[1]\n",
        "    class AE(nn.Module):\n",
        "        def __init__(self):\n",
        "            super().__init__()\n",
        "            self.encoder = nn.Sequential(nn.Linear(input_dim, 16), nn.ReLU(), nn.Linear(16, 4))\n",
        "            self.decoder = nn.Sequential(nn.Linear(4, 16), nn.ReLU(), nn.Linear(16, input_dim))\n",
        "        def forward(self, x):\n",
        "            return self.decoder(self.encoder(x))\n",
        "    ae = AE()\n",
        "    optimizer = optim.Adam(ae.parameters(), lr=0.01)\n",
        "    criterion = nn.MSELoss()\n",
        "    X_tensor = torch.tensor(X_scaled, dtype=torch.float32)\n",
        "    for _ in range(300):\n",
        "        optimizer.zero_grad()\n",
        "        loss = criterion(ae(X_tensor), X_tensor)\n",
        "        loss.backward()\n",
        "        optimizer.step()\n",
        "    ae.eval()\n",
        "    with torch.no_grad():\n",
        "        ae_err = np.mean((ae(X_tensor).numpy() - X_scaled) ** 2, axis=1)\n",
        "    scores = (rf_err / np.max(rf_err) + ae_err / np.max(ae_err)) / 2\n",
        "    pred = get_top_k_outliers(scores, n_outliers)\n",
        "    return pred, scores\n",
        "\n",
        "def run_oneclass_svm_with_y(X, y, n_outliers):\n",
        "    Xy = np.column_stack((X, y.ravel()))\n",
        "    model = OneClassSVM(kernel='rbf', gamma='auto')\n",
        "    model.fit(Xy)\n",
        "    scores = -model.decision_function(Xy)\n",
        "    scores = np.nan_to_num(scores, nan=0.0, posinf=1.0, neginf=0.0)\n",
        "    pred = get_top_k_outliers(scores, n_outliers)\n",
        "    return pred, scores\n",
        "\n",
        "def run_iforest_with_y(X, y, n_outliers, rs):\n",
        "    Xy = np.column_stack((X, y.ravel()))\n",
        "    model = SklearnIForest(random_state=rs)\n",
        "    model.fit(Xy)\n",
        "    scores = -model.decision_function(Xy)\n",
        "    scores = np.nan_to_num(scores, nan=0.0, posinf=1.0, neginf=0.0)\n",
        "    pred = get_top_k_outliers(scores, n_outliers)\n",
        "    return pred, scores\n",
        "\n",
        "def run_lof_with_y(X, y, n_outliers):\n",
        "    Xy = np.column_stack((X, y.ravel()))\n",
        "    model = LocalOutlierFactor(novelty=True)\n",
        "    model.fit(Xy)\n",
        "    scores = -model.score_samples(Xy)\n",
        "    scores = np.nan_to_num(scores, nan=0.0, posinf=1.0, neginf=0.0)\n",
        "    pred = get_top_k_outliers(scores, n_outliers)\n",
        "    return pred, scores\n",
        "\n",
        "# ------------------------------------------------------------\n",
        "# 5. Main experiment\n",
        "# ------------------------------------------------------------\n",
        "n_runs = 20\n",
        "n_outliers = 400   # всего выбросов в датасете California Housing\n",
        "\n",
        "standard_methods = [\n",
        "    'ABOD (pyod)', 'HBOS (pyod)', 'IsolationForest (pyod)', 'kNN (pyod)',\n",
        "    'LOF (pyod)', 'OCSVM (pyod)', 'PCA (pyod)', 'COPOD (pyod)',\n",
        "    'Random Forest (error)', 'Neural Network (error)', 'Autoencoder (reconstruction)',\n",
        "    'Combined (RF+AE)', 'One-Class SVM (with y)', 'Isolation Forest (with y)',\n",
        "    'LOF (with y)'\n",
        "]\n",
        "nnfa_methods = ['NNFA (ξ=0)']\n",
        "all_methods = standard_methods + nnfa_methods\n",
        "\n",
        "metrics = {method: {'f1': [], 'auc': []} for method in all_methods}\n",
        "\n",
        "print(f\"Experiment: {n_runs} runs, NNFA with ξ=0, 500 epochs\")\n",
        "print(f\"Dataset: California Housing with {n_outliers} outliers (200 highest → min, 200 lowest → max).\")\n",
        "\n",
        "for run_idx in range(n_runs):\n",
        "    seed = run_idx\n",
        "    print(f\"\\n--- Run {run_idx+1}/{n_runs}, seed = {seed} ---\")\n",
        "\n",
        "    X, y, true_outliers = create_california_dataset(seed_shuffle=seed)\n",
        "    scaler = StandardScaler()\n",
        "    X_scaled = scaler.fit_transform(X)\n",
        "\n",
        "    # ---- Standard methods ----\n",
        "    pred_abod, scores_abod = run_pyod_detector(abod.ABOD(), X_scaled, n_outliers)\n",
        "    pred_hbos, scores_hbos = run_pyod_detector(hbos.HBOS(), X_scaled, n_outliers)\n",
        "    pred_knn, scores_knn = run_pyod_detector(knn.KNN(), X_scaled, n_outliers)\n",
        "    pred_lof, scores_lof = run_pyod_detector(lof.LOF(), X_scaled, n_outliers)\n",
        "    pred_ocsvm, scores_ocsvm = run_pyod_detector(ocsvm.OCSVM(), X_scaled, n_outliers)\n",
        "    pred_pca, scores_pca = run_pyod_detector(pca.PCA(), X_scaled, n_outliers)\n",
        "    pred_copod, scores_copod = run_pyod_detector(copod.COPOD(), X_scaled, n_outliers)\n",
        "    iforest_model = iforest.IForest(random_state=seed)\n",
        "    pred_iforest, scores_iforest = run_pyod_detector(iforest_model, X_scaled, n_outliers)\n",
        "\n",
        "    pred_rf, scores_rf = run_random_forest(X, y, n_outliers, rs=seed)\n",
        "    pred_nn, scores_nn = run_neural_network(X, y, n_outliers, rs=seed)\n",
        "    pred_ae, scores_ae = run_autoencoder(X_scaled, n_outliers, rs=seed)\n",
        "    pred_combined, scores_combined = run_combined_rf_ae(X, y, X_scaled, n_outliers, rs=seed)\n",
        "    pred_ocsvm_y, scores_ocsvm_y = run_oneclass_svm_with_y(X, y, n_outliers)\n",
        "    pred_iforest_y, scores_iforest_y = run_iforest_with_y(X, y, n_outliers, rs=seed)\n",
        "    pred_lof_y, scores_lof_y = run_lof_with_y(X, y, n_outliers)\n",
        "\n",
        "    # ---- NNFA (ξ=0) ----\n",
        "    pred_nnfa, scores_nnfa = run_nnfa_original(X, y, n_outliers, random_state=seed)\n",
        "\n",
        "    all_data = {\n",
        "        'ABOD (pyod)': (pred_abod, scores_abod),\n",
        "        'HBOS (pyod)': (pred_hbos, scores_hbos),\n",
        "        'IsolationForest (pyod)': (pred_iforest, scores_iforest),\n",
        "        'kNN (pyod)': (pred_knn, scores_knn),\n",
        "        'LOF (pyod)': (pred_lof, scores_lof),\n",
        "        'OCSVM (pyod)': (pred_ocsvm, scores_ocsvm),\n",
        "        'PCA (pyod)': (pred_pca, scores_pca),\n",
        "        'COPOD (pyod)': (pred_copod, scores_copod),\n",
        "        'Random Forest (error)': (pred_rf, scores_rf),\n",
        "        'Neural Network (error)': (pred_nn, scores_nn),\n",
        "        'Autoencoder (reconstruction)': (pred_ae, scores_ae),\n",
        "        'Combined (RF+AE)': (pred_combined, scores_combined),\n",
        "        'One-Class SVM (with y)': (pred_ocsvm_y, scores_ocsvm_y),\n",
        "        'Isolation Forest (with y)': (pred_iforest_y, scores_iforest_y),\n",
        "        'LOF (with y)': (pred_lof_y, scores_lof_y),\n",
        "        'NNFA (ξ=0)': (pred_nnfa, scores_nnfa)\n",
        "    }\n",
        "\n",
        "    for method, (pred, scores) in all_data.items():\n",
        "        scores = np.nan_to_num(scores, nan=0.0, posinf=1.0, neginf=0.0)\n",
        "        if len(np.unique(scores)) == 1:\n",
        "            auc = 0.5\n",
        "        else:\n",
        "            auc = roc_auc_score(true_outliers, scores)\n",
        "        tp = np.sum((pred == 1) & (true_outliers == 1))\n",
        "        fp = np.sum((pred == 1) & (true_outliers == 0))\n",
        "        fn = np.sum((pred == 0) & (true_outliers == 1))\n",
        "        precision = tp / (tp + fp) if (tp + fp) > 0 else 0.0\n",
        "        recall = tp / (tp + fn) if (tp + fn) > 0 else 0.0\n",
        "        f1 = 2 * precision * recall / (precision + recall) if (precision + recall) > 0 else 0.0\n",
        "        metrics[method]['f1'].append(f1)\n",
        "        metrics[method]['auc'].append(auc)\n",
        "\n",
        "    # Печать результатов для NNFA в этом запуске\n",
        "    print(f\"  NNFA (ξ=0) F1 = {metrics['NNFA (ξ=0)']['f1'][-1]:.3f}, AUC = {metrics['NNFA (ξ=0)']['auc'][-1]:.3f}\")\n",
        "\n",
        "# ------------------------------------------------------------\n",
        "# 6. Summary table (mean ± std)\n",
        "# ------------------------------------------------------------\n",
        "summary_rows = []\n",
        "for method in all_methods:\n",
        "    f1_mean = np.mean(metrics[method]['f1'])\n",
        "    f1_std  = np.std(metrics[method]['f1'])\n",
        "    auc_mean = np.mean(metrics[method]['auc'])\n",
        "    auc_std  = np.std(metrics[method]['auc'])\n",
        "    summary_rows.append({\n",
        "        'Method': method,\n",
        "        'F1 (mean ± std)': f\"{f1_mean:.3f} ± {f1_std:.3f}\",\n",
        "        'ROC-AUC (mean ± std)': f\"{auc_mean:.3f} ± {auc_std:.3f}\"\n",
        "    })\n",
        "df_summary = pd.DataFrame(summary_rows)\n",
        "df_summary = df_summary.sort_values('ROC-AUC (mean ± std)', ascending=False).reset_index(drop=True)\n",
        "\n",
        "print(\"\\n\" + \"=\"*80)\n",
        "print(f\"SUMMARY TABLE (mean ± std) over {n_runs} runs\")\n",
        "print(\"=\"*80)\n",
        "print(df_summary.to_string(index=False))\n",
        "\n",
        "# ------------------------------------------------------------\n",
        "# 7. Pairwise Wilcoxon test for F1\n",
        "# ------------------------------------------------------------\n",
        "p_matrix = pd.DataFrame(index=all_methods, columns=all_methods, dtype=float)\n",
        "for i, m1 in enumerate(all_methods):\n",
        "    for j, m2 in enumerate(all_methods):\n",
        "        if i == j:\n",
        "            p_matrix.loc[m1, m2] = 1.0\n",
        "        else:\n",
        "            if np.all(np.array(metrics[m1]['f1']) == np.array(metrics[m2]['f1'])):\n",
        "                p = 1.0\n",
        "            else:\n",
        "                _, p = wilcoxon(metrics[m1]['f1'], metrics[m2]['f1'])\n",
        "            p_matrix.loc[m1, m2] = p\n",
        "\n",
        "print(\"\\n\" + \"=\"*80)\n",
        "print(\"PAIRWISE WILCOXON P-VALUES (rounded to 4 decimals)\")\n",
        "print(\"=\"*80)\n",
        "p_display = p_matrix.round(4).astype(str)\n",
        "print(p_display.to_string())\n",
        "p_matrix.to_csv(\"pairwise_wilcoxon_matrix.csv\")\n",
        "print(\"\\nFull pairwise p-value matrix saved to 'pairwise_wilcoxon_matrix.csv'\")\n",
        "\n",
        "# ------------------------------------------------------------\n",
        "# 8. Significant differences (p < 0.05)\n",
        "# ------------------------------------------------------------\n",
        "print(\"\\n\" + \"=\"*80)\n",
        "print(\"DETAILED SIGNIFICANT DIFFERENCES (p < 0.05)\")\n",
        "print(\"=\"*80)\n",
        "significant_pairs = []\n",
        "for i, m1 in enumerate(all_methods):\n",
        "    for j, m2 in enumerate(all_methods):\n",
        "        if i < j:\n",
        "            p_val = p_matrix.loc[m1, m2]\n",
        "            if p_val < 0.05:\n",
        "                significant_pairs.append((m1, m2, p_val))\n",
        "                print(f\"{m1} vs {m2}: p = {p_val:.6f}\")\n",
        "if not significant_pairs:\n",
        "    print(\"No significant differences found (p >= 0.05 for all pairs).\")\n",
        "\n",
        "# ------------------------------------------------------------\n",
        "# 9. Save Excel\n",
        "# ------------------------------------------------------------\n",
        "output_file = \"california_housing_nnfa0_results.xlsx\"\n",
        "with pd.ExcelWriter(output_file, engine='openpyxl') as writer:\n",
        "    df_summary.to_excel(writer, sheet_name='summary', index=False)\n",
        "    p_matrix.to_excel(writer, sheet_name='pairwise_wilcoxon')\n",
        "print(f\"\\nResults saved to '{output_file}'\")\n",
        "\n",
        "# ------------------------------------------------------------\n",
        "# 10. Best standard method comparison\n",
        "# ------------------------------------------------------------\n",
        "std_methods_only = [m for m in all_methods if m not in nnfa_methods]\n",
        "best_std = max(std_methods_only, key=lambda m: np.mean(metrics[m]['f1']))\n",
        "print(\"\\n\" + \"=\"*80)\n",
        "print(\"STATISTICAL SIGNIFICANCE (Wilcoxon test, two-sided, for F1)\")\n",
        "print(\"=\"*80)\n",
        "for nnfa_m in nnfa_methods:\n",
        "    p_val = p_matrix.loc[nnfa_m, best_std]\n",
        "    print(f\"{nnfa_m} vs {best_std}: p = {p_val:.6f} -> {'significant (p<0.05)' if p_val < 0.05 else 'NOT significant'}\")\n",
        "\n",
        "# ------------------------------------------------------------\n",
        "# 11. Download files (if in Colab)\n",
        "# ------------------------------------------------------------\n",
        "try:\n",
        "    from google.colab import files\n",
        "    files.download(output_file)\n",
        "    files.download(\"pairwise_wilcoxon_matrix.csv\")\n",
        "    print(\"Files downloaded automatically.\")\n",
        "except ImportError:\n",
        "    print(f\"\\nFiles saved locally: '{output_file}', 'pairwise_wilcoxon_matrix.csv'\")\n",
        "\n",
        "# ------------------------------------------------------------\n",
        "# 12. Boxplot for F1 distribution\n",
        "# ------------------------------------------------------------\n",
        "plt.figure(figsize=(14, 7))\n",
        "f1_data = [metrics[m]['f1'] for m in all_methods]\n",
        "plt.boxplot(f1_data, labels=all_methods)\n",
        "plt.xticks(rotation=90)\n",
        "plt.ylabel('F1 Score')\n",
        "plt.title(f'Distribution of F1 over {n_runs} runs (California Housing, 400 outliers)')\n",
        "plt.grid(axis='y', linestyle=':', alpha=0.7)\n",
        "plt.tight_layout()\n",
        "plt.show()"
      ]
    }
  ]
}