diff --git a/EDS_paper/BayesianClassification_Alabama.ipynb b/EDS_paper/BayesianClassification_Alabama.ipynb
deleted file mode 100644
index d5107ff..0000000
--- a/EDS_paper/BayesianClassification_Alabama.ipynb
+++ /dev/null
@@ -1,1268 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "d1bb37a6",
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "2024-02-06 15:25:53.351252: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n",
- "To enable the following instructions: AVX2 AVX512F FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n",
- "2024-02-06 15:25:53.897660: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT\n"
- ]
- }
- ],
- "source": [
- "import pandas as pd\n",
- "\n",
- "import numpy as np\n",
- "import tensorflow as tf\n",
- "import tensorflow_probability as tfp\n",
- "from tensorflow.keras.models import Sequential\n",
- "from tensorflow.keras.layers import Dense\n",
- "from tensorflow.keras.optimizers import Adam\n",
- "\n",
- "import matplotlib.pyplot as plt"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "d9e19465",
- "metadata": {},
- "source": [
- "### Setup and Configuration"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "68eb4db6",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "
\n",
- "\n",
- "
\n",
- " \n",
- " \n",
- " | \n",
- " X | \n",
- " Y | \n",
- " Area | \n",
- " MedianIncomeCounty | \n",
- " HousingUnitsCounty | \n",
- " HousingDensityCounty | \n",
- " Impervious | \n",
- " AgCount | \n",
- " CmCount | \n",
- " GvCount | \n",
- " EdCount | \n",
- " InCount | \n",
- " OsmNearestRoad | \n",
- " BuildingType | \n",
- "
\n",
- " \n",
- " \n",
- " \n",
- " 0 | \n",
- " -86.452369 | \n",
- " 32.454446 | \n",
- " 2168.997509 | \n",
- " 62660.0 | \n",
- " 24170.0 | \n",
- " 2.409557 | \n",
- " 77 | \n",
- " 10.0 | \n",
- " 602.0 | \n",
- " 3.0 | \n",
- " 6.0 | \n",
- " 119.0 | \n",
- " residential | \n",
- " Education | \n",
- "
\n",
- " \n",
- " 1 | \n",
- " -86.451701 | \n",
- " 32.454445 | \n",
- " 3918.400075 | \n",
- " 62660.0 | \n",
- " 24170.0 | \n",
- " 2.409557 | \n",
- " 94 | \n",
- " 10.0 | \n",
- " 602.0 | \n",
- " 3.0 | \n",
- " 6.0 | \n",
- " 119.0 | \n",
- " residential | \n",
- " Education | \n",
- "
\n",
- " \n",
- " 2 | \n",
- " -86.451652 | \n",
- " 32.453549 | \n",
- " 501.138397 | \n",
- " 62660.0 | \n",
- " 24170.0 | \n",
- " 2.409557 | \n",
- " 47 | \n",
- " 10.0 | \n",
- " 602.0 | \n",
- " 3.0 | \n",
- " 6.0 | \n",
- " 119.0 | \n",
- " residential | \n",
- " Education | \n",
- "
\n",
- " \n",
- " 3 | \n",
- " -86.456148 | \n",
- " 32.454743 | \n",
- " 487.162570 | \n",
- " 62660.0 | \n",
- " 24170.0 | \n",
- " 2.409557 | \n",
- " 56 | \n",
- " 10.0 | \n",
- " 602.0 | \n",
- " 3.0 | \n",
- " 6.0 | \n",
- " 119.0 | \n",
- " residential | \n",
- " Education | \n",
- "
\n",
- " \n",
- " 4 | \n",
- " -86.451483 | \n",
- " 32.454827 | \n",
- " 16.444244 | \n",
- " 62660.0 | \n",
- " 24170.0 | \n",
- " 2.409557 | \n",
- " 83 | \n",
- " 10.0 | \n",
- " 602.0 | \n",
- " 3.0 | \n",
- " 6.0 | \n",
- " 119.0 | \n",
- " residential | \n",
- " Education | \n",
- "
\n",
- " \n",
- "
\n",
- "
"
- ],
- "text/plain": [
- " X Y Area MedianIncomeCounty HousingUnitsCounty \\\n",
- "0 -86.452369 32.454446 2168.997509 62660.0 24170.0 \n",
- "1 -86.451701 32.454445 3918.400075 62660.0 24170.0 \n",
- "2 -86.451652 32.453549 501.138397 62660.0 24170.0 \n",
- "3 -86.456148 32.454743 487.162570 62660.0 24170.0 \n",
- "4 -86.451483 32.454827 16.444244 62660.0 24170.0 \n",
- "\n",
- " HousingDensityCounty Impervious AgCount CmCount GvCount EdCount \\\n",
- "0 2.409557 77 10.0 602.0 3.0 6.0 \n",
- "1 2.409557 94 10.0 602.0 3.0 6.0 \n",
- "2 2.409557 47 10.0 602.0 3.0 6.0 \n",
- "3 2.409557 56 10.0 602.0 3.0 6.0 \n",
- "4 2.409557 83 10.0 602.0 3.0 6.0 \n",
- "\n",
- " InCount OsmNearestRoad BuildingType \n",
- "0 119.0 residential Education \n",
- "1 119.0 residential Education \n",
- "2 119.0 residential Education \n",
- "3 119.0 residential Education \n",
- "4 119.0 residential Education "
- ]
- },
- "execution_count": 2,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Alabama data\n",
- "file = \"./ML_Training_01.csv\"\n",
- "\n",
- "# read data into a Pandas dataframe\n",
- "df = pd.read_csv(file)\n",
- "\n",
- "# ignore first few columns, which are FIPs codes, not needed for ML\n",
- "df = df.iloc[:, 3:] \n",
- "\n",
- "df = df.rename( columns={\"OrnlType\":\"BuildingType\"} )\n",
- "df.head()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "999bfa70",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\n",
- "Residential 2060502\n",
- "Commercial 136922\n",
- "Other 110849\n",
- "Name: BuildingType, dtype: int64\n",
- "\n",
- "Residential 1.000000\n",
- "Commercial 15.048728\n",
- "Other 18.588368\n",
- "Name: BuildingType, dtype: float64\n",
- "\n"
- ]
- }
- ],
- "source": [
- "# classify a building as \"Residential\", \"Commercial\", or \"Other\"\n",
- "df.loc[df[\"BuildingType\"] == \"Industrial\", \"BuildingType\"] = 'Other'\n",
- "df.loc[df[\"BuildingType\"] == \"Assembly\", \"BuildingType\"] = 'Other'\n",
- "df.loc[df[\"BuildingType\"] == \"Education\", \"BuildingType\"] = 'Other'\n",
- "df.loc[df[\"BuildingType\"] == \"Government\", \"BuildingType\"] = 'Other'\n",
- "df.loc[df[\"BuildingType\"] == \"Agriculture\", \"BuildingType\"] = 'Other'\n",
- "df.loc[df[\"BuildingType\"] == \"Utility and Misc\", \"BuildingType\"] = 'Other'\n",
- "\n",
- "# building type distributions\n",
- "x = df['BuildingType'].value_counts()\n",
- "print()\n",
- "print( x )\n",
- "print()\n",
- "print( x[0]/df['BuildingType'].value_counts() )\n",
- "print()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "id": "1e299cf1",
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/tmp/ipykernel_33582/1358776107.py:19: DeprecationWarning: In a future version, `df.iloc[:, i] = newvals` will attempt to set the values inplace instead of always setting a new array. To retain the old behavior, use either `df[df.columns[i]] = newvals` or, if columns are non-unique, `df.isetitem(i, newvals)`\n",
- " df.iloc[:, nCols-1] = le.transform( df.iloc[:, nCols-1] )\n",
- "/tmp/ipykernel_33582/1358776107.py:23: DeprecationWarning: In a future version, `df.iloc[:, i] = newvals` will attempt to set the values inplace instead of always setting a new array. To retain the old behavior, use either `df[df.columns[i]] = newvals` or, if columns are non-unique, `df.isetitem(i, newvals)`\n",
- " df.iloc[:, nCols-2] = le2.transform( df.iloc[:, nCols-2] )\n"
- ]
- }
- ],
- "source": [
- "from sklearn import preprocessing\n",
- "\n",
- "df = df.sample(frac=1) # shuffle the dataframe (technically, we randomly resample the entire df)\n",
- "\n",
- "# preprocess the data - scaling\n",
- "scaler = preprocessing.StandardScaler()\n",
- " \n",
- "columns = ['X', 'Y', 'Area', 'MedianIncomeCounty', \n",
- " 'HousingUnitsCounty', 'HousingDensityCounty',\n",
- " 'Impervious', 'AgCount', 'CmCount', 'GvCount',\n",
- " 'EdCount', 'InCount']\n",
- "df[columns] = scaler.fit_transform(df[columns])\n",
- "\n",
- "df = df.dropna()\n",
- "\n",
- "nCols = df.shape[1]\n",
- "le = preprocessing.LabelEncoder()\n",
- "le.fit( df.iloc[:, nCols-1] ) # ornl type\n",
- "df.iloc[:, nCols-1] = le.transform( df.iloc[:, nCols-1] )\n",
- " \n",
- "le2 = preprocessing.LabelEncoder()\n",
- "le2.fit( df.iloc[:, nCols-2] ) # nearest road type\n",
- "df.iloc[:, nCols-2] = le2.transform( df.iloc[:, nCols-2] )"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "958d6b5e",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "\n",
- "\n",
- "
\n",
- " \n",
- " \n",
- " | \n",
- " X | \n",
- " Y | \n",
- " Area | \n",
- " MedianIncomeCounty | \n",
- " HousingUnitsCounty | \n",
- " HousingDensityCounty | \n",
- " Impervious | \n",
- " AgCount | \n",
- " CmCount | \n",
- " GvCount | \n",
- " EdCount | \n",
- " InCount | \n",
- " OsmNearestRoad | \n",
- " BuildingType | \n",
- "
\n",
- " \n",
- " \n",
- " \n",
- " 1591370 | \n",
- " -1.884314 | \n",
- " -1.854621 | \n",
- " -0.105389 | \n",
- " -0.302436 | \n",
- " 0.989616 | \n",
- " 0.370678 | \n",
- " -1.051383 | \n",
- " 2.988046 | \n",
- " 0.781750 | \n",
- " 1.116229 | \n",
- " 0.577660 | \n",
- " 1.041752 | \n",
- " 4 | \n",
- " 2 | \n",
- "
\n",
- " \n",
- " 110322 | \n",
- " -1.098579 | \n",
- " -1.958204 | \n",
- " -0.167053 | \n",
- " 0.943535 | \n",
- " 0.315119 | \n",
- " -1.996190 | \n",
- " -0.109315 | \n",
- " -0.231793 | \n",
- " 0.214207 | \n",
- " -0.844359 | \n",
- " -0.132476 | \n",
- " 0.713686 | \n",
- " 2 | \n",
- " 2 | \n",
- "
\n",
- " \n",
- " 53673 | \n",
- " -1.319796 | \n",
- " -1.860037 | \n",
- " -0.463857 | \n",
- " 0.943535 | \n",
- " 0.315119 | \n",
- " -1.996190 | \n",
- " -0.965740 | \n",
- " -0.231793 | \n",
- " 0.214207 | \n",
- " -0.844359 | \n",
- " -0.132476 | \n",
- " 0.713686 | \n",
- " 4 | \n",
- " 2 | \n",
- "
\n",
- " \n",
- " 1327463 | \n",
- " -0.035719 | \n",
- " 1.256301 | \n",
- " 0.258136 | \n",
- " 1.587182 | \n",
- " 0.812943 | \n",
- " 0.529785 | \n",
- " 0.190434 | \n",
- " -0.415784 | \n",
- " 0.890988 | \n",
- " -0.321536 | \n",
- " 1.007044 | \n",
- " 0.682809 | \n",
- " 4 | \n",
- " 2 | \n",
- "
\n",
- " \n",
- " 1885751 | \n",
- " -0.291156 | \n",
- " 1.129598 | \n",
- " -0.216477 | \n",
- " 0.166470 | \n",
- " -0.426574 | \n",
- " 0.732498 | \n",
- " 0.875574 | \n",
- " -0.691770 | \n",
- " -0.417104 | \n",
- " -0.975065 | \n",
- " -0.644434 | \n",
- " -0.181742 | \n",
- " 4 | \n",
- " 2 | \n",
- "
\n",
- " \n",
- "
\n",
- "
"
- ],
- "text/plain": [
- " X Y Area MedianIncomeCounty HousingUnitsCounty \\\n",
- "1591370 -1.884314 -1.854621 -0.105389 -0.302436 0.989616 \n",
- "110322 -1.098579 -1.958204 -0.167053 0.943535 0.315119 \n",
- "53673 -1.319796 -1.860037 -0.463857 0.943535 0.315119 \n",
- "1327463 -0.035719 1.256301 0.258136 1.587182 0.812943 \n",
- "1885751 -0.291156 1.129598 -0.216477 0.166470 -0.426574 \n",
- "\n",
- " HousingDensityCounty Impervious AgCount CmCount GvCount \\\n",
- "1591370 0.370678 -1.051383 2.988046 0.781750 1.116229 \n",
- "110322 -1.996190 -0.109315 -0.231793 0.214207 -0.844359 \n",
- "53673 -1.996190 -0.965740 -0.231793 0.214207 -0.844359 \n",
- "1327463 0.529785 0.190434 -0.415784 0.890988 -0.321536 \n",
- "1885751 0.732498 0.875574 -0.691770 -0.417104 -0.975065 \n",
- "\n",
- " EdCount InCount OsmNearestRoad BuildingType \n",
- "1591370 0.577660 1.041752 4 2 \n",
- "110322 -0.132476 0.713686 2 2 \n",
- "53673 -0.132476 0.713686 4 2 \n",
- "1327463 1.007044 0.682809 4 2 \n",
- "1885751 -0.644434 -0.181742 4 2 "
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "df.head()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "id": "61b9c6ee",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Number of classes: 3\n"
- ]
- }
- ],
- "source": [
- "nClasses = len(df['BuildingType'].unique())\n",
- "print(\"Number of classes:\", nClasses)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "id": "bb4e5f39",
- "metadata": {},
- "outputs": [],
- "source": [
- "buildingTypes = np.array(df['BuildingType'])\n",
- "df = df.drop( columns=['BuildingType'] )"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "6167606a",
- "metadata": {},
- "source": [
- "### Bayesian Neural Network"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "id": "63f8937e",
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/home/jupyter-narock/.local/lib/python3.9/site-packages/tensorflow_probability/python/layers/util.py:98: UserWarning: `layer.add_variable` is deprecated and will be removed in a future version. Please use the `layer.add_weight()` method instead.\n",
- " loc = add_variable_fn(\n",
- "2024-02-06 15:26:18.259980: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1635] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 5337 MB memory: -> device: 0, name: NVIDIA GeForce GTX TITAN Black, pci bus id: 0000:65:00.0, compute capability: 3.5\n",
- "/home/jupyter-narock/.local/lib/python3.9/site-packages/tensorflow_probability/python/layers/util.py:108: UserWarning: `layer.add_variable` is deprecated and will be removed in a future version. Please use the `layer.add_weight()` method instead.\n",
- " untransformed_scale = add_variable_fn(\n"
- ]
- }
- ],
- "source": [
- "from keras import backend as K \n",
- "\n",
- "# Keras keeps models hanging around in memory. If we retrain a model, Keras will\n",
- "# start from the previously concluded weight values. This resets everything.\n",
- "K.clear_session()\n",
- "\n",
- "# KL divergence weighted by the number of training samples, using\n",
- "# lambda function to pass as input to the kernel_divergence_fn on\n",
- "# flipout layers.\n",
- "kl_divergence_function = (lambda q, p, _: tfd.kl_divergence(q, p) / \n",
- " tf.cast(df.shape[0], dtype=tf.float32))\n",
- "\n",
- "tfd = tfp.distributions\n",
- "\n",
- "# Define a logistic regression model as a Bernoulli distribution\n",
- "# parameterized by logits from a single linear layer. We use the Flipout\n",
- "# Monte Carlo estimator for the layer: this enables lower variance\n",
- "# stochastic gradients than naive reparameterization.\n",
- "input_layer = tf.keras.layers.Input(shape=df.shape[1])\n",
- "\n",
- "#dense_layer = tfp.layers.DenseFlipout(\n",
- "# units=1,\n",
- "# activation='sigmoid',\n",
- "# kernel_posterior_fn=tfp.layers.default_mean_field_normal_fn(),\n",
- "# bias_posterior_fn=tfp.layers.default_mean_field_normal_fn(),\n",
- "# kernel_divergence_fn=kl_divergence_function)(input_layer)\n",
- "\n",
- "layer1 = tfp.layers.DenseFlipout(\n",
- " units=26,\n",
- " activation='sigmoid',\n",
- " kernel_posterior_fn=tfp.layers.default_mean_field_normal_fn(),\n",
- " bias_posterior_fn=tfp.layers.default_mean_field_normal_fn(),\n",
- " kernel_divergence_fn=kl_divergence_function)(input_layer)\n",
- "\n",
- "layer2 = tfp.layers.DenseFlipout(\n",
- " units=13,\n",
- " activation='sigmoid',\n",
- " kernel_posterior_fn=tfp.layers.default_mean_field_normal_fn(),\n",
- " bias_posterior_fn=tfp.layers.default_mean_field_normal_fn(),\n",
- " kernel_divergence_fn=kl_divergence_function)(layer1)\n",
- "\n",
- "layer3 = tfp.layers.DenseFlipout(\n",
- " units=8,\n",
- " activation='sigmoid',\n",
- " kernel_posterior_fn=tfp.layers.default_mean_field_normal_fn(),\n",
- " bias_posterior_fn=tfp.layers.default_mean_field_normal_fn(),\n",
- " kernel_divergence_fn=kl_divergence_function)(layer2)\n",
- "\n",
- "layer4 = tfp.layers.DenseFlipout(\n",
- " units=4,\n",
- " activation='sigmoid',\n",
- " kernel_posterior_fn=tfp.layers.default_mean_field_normal_fn(),\n",
- " bias_posterior_fn=tfp.layers.default_mean_field_normal_fn(),\n",
- " kernel_divergence_fn=kl_divergence_function)(layer3)\n",
- "\n",
- "out = tfp.layers.DenseFlipout(\n",
- " units=3,\n",
- " activation='softmax',\n",
- " kernel_posterior_fn=tfp.layers.default_mean_field_normal_fn(),\n",
- " bias_posterior_fn=tfp.layers.default_mean_field_normal_fn(),\n",
- " kernel_divergence_fn=kl_divergence_function)(layer4)\n",
- "\n",
- "# Model compilation\n",
- "#bnn = tf.keras.Model(inputs=input_layer, outputs=dense_layer)\n",
- "bnn = tf.keras.Model(inputs=input_layer, outputs=out)\n",
- "optimizer = tf.keras.optimizers.Adam(learning_rate=0.01)\n",
- " \n",
- "# We use the binary_crossentropy loss since this toy example contains\n",
- "# two labels. The Keras API will then automatically add the\n",
- "# Kullback-Leibler divergence (contained on the individual layers of\n",
- "# the model), to the cross entropy loss, effectively\n",
- "# calcuating the (negated) Evidence Lower Bound Loss (ELBO)\n",
- "bnn.compile(optimizer, loss='categorical_crossentropy', metrics=['accuracy'])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "id": "6c70029b",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Model: \"model\"\n",
- "_________________________________________________________________\n",
- " Layer (type) Output Shape Param # \n",
- "=================================================================\n",
- " input_1 (InputLayer) [(None, 13)] 0 \n",
- " \n",
- " dense_flipout (DenseFlipout (None, 26) 728 \n",
- " ) \n",
- " \n",
- " dense_flipout_1 (DenseFlipo (None, 13) 702 \n",
- " ut) \n",
- " \n",
- " dense_flipout_2 (DenseFlipo (None, 8) 224 \n",
- " ut) \n",
- " \n",
- " dense_flipout_3 (DenseFlipo (None, 4) 72 \n",
- " ut) \n",
- " \n",
- " dense_flipout_4 (DenseFlipo (None, 3) 30 \n",
- " ut) \n",
- " \n",
- "=================================================================\n",
- "Total params: 1,756\n",
- "Trainable params: 1,756\n",
- "Non-trainable params: 0\n",
- "_________________________________________________________________\n"
- ]
- }
- ],
- "source": [
- "bnn.summary()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "id": "91eefec2",
- "metadata": {},
- "outputs": [],
- "source": [
- "bnn.load_weights(\"bnn.h5\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ae0a0f29",
- "metadata": {},
- "source": [
- "### Analysis"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "id": "af858d85",
- "metadata": {},
- "outputs": [],
- "source": [
- "import numpy as np\n",
- "\n",
- "def getPredictions( model, data, T ):\n",
- "\n",
- " n = data.shape[0]\n",
- " preds = np.zeros( shape=(n,nClasses,T) )\n",
- " \n",
- " for t in range(T):\n",
- " if ( t == 10 ): print(\"Iteration 10...\")\n",
- " if ( t == 30 ): print(\"Iteration 30...\")\n",
- " if ( t == 50 ): print(\"Iteration 50...\")\n",
- " if ( t == 70 ): print(\"Iteration 70...\")\n",
- " if ( t == 90 ): print(\"Iteration 90...\")\n",
- " preds[:,:,t] = model(data)\n",
- " \n",
- " return preds"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "id": "9bf48df9",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Iteration 10...\n",
- "Iteration 30...\n",
- "Iteration 50...\n",
- "Iteration 70...\n",
- "Iteration 90...\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "(1140006, 3, 100)"
- ]
- },
- "execution_count": 12,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "T = 100\n",
- "preds = getPredictions( bnn, df.values, T )\n",
- "preds.shape"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "id": "f6054b90",
- "metadata": {},
- "outputs": [],
- "source": [
- "def getPredictions( preds, T ):\n",
- " \n",
- " n = preds.shape[0]\n",
- " means = np.zeros( shape=(n, nClasses) )\n",
- " \n",
- " for ix in range(n):\n",
- " for j in range(nClasses):\n",
- " \n",
- " means[ix,j] = np.mean( preds[ix,j,:] )\n",
- " \n",
- " bnnPreds = np.argmax( means, axis=1 )\n",
- " \n",
- " return means, bnnPreds"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "id": "9a7053ea",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "((1140006, 3), (1140006,))"
- ]
- },
- "execution_count": 14,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "means, bnnPreds = getPredictions( preds, T )\n",
- "means.shape, bnnPreds.shape"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "id": "ea15ee5b",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "((1140006,), (1140006,))"
- ]
- },
- "execution_count": 16,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "from scipy.stats import entropy\n",
- "\n",
- "base = 2 # work in units of bits\n",
- "en = entropy(means, base=base, axis=1)\n",
- "\n",
- "en.shape, buildingTypes.shape"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "id": "336ff55e",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "Text(0.5, 1.0, 'Entropy of Incorrect Predictions')"
- ]
- },
- "execution_count": 22,
- "metadata": {},
- "output_type": "execute_result"
- },
- {
- "data": {
- "image/png": "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\n",
- "text/plain": [
- "