{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "4l2AItnCizvk" }, "source": [ "# FairSVM\n", "\n", "[![Slides](https://img.shields.io/badge/🦌-ReHLine-blueviolet)](https://rehline-python.readthedocs.io/en/latest//)\n", "\n", "The FairSVM solves the following optimization problem:\n", "\n", "$$\n", "\\begin{aligned}\n", "\\min_{\\beta \\in \\mathbb{R}^d}\\quad &\n", "\\frac{C}{n}\\sum_{i=1}^n (1-y_i\\beta^\\top x_i)_+ + \\frac{1}{2}\\|\\beta\\|_2^2, \\\\[1ex]\n", "\\text{subject to}\\quad &\n", "\\frac{1}{n}\\sum_{i=1}^n z_i\\,\\beta^\\top x_i \\le \\rho,\\quad\n", "\\frac{1}{n}\\sum_{i=1}^n z_i\\,\\beta^\\top x_i \\ge -\\rho.\n", "\\end{aligned}\n", "$$\n", "\n", "where:\n", "\n", "- $x_i \\in \\mathbb{R}^d$ is a feature vector\n", "- $y_i \\in \\{-1,1\\}$ is a binary label\n", "- $z_i$ is a collection of **centered sensitive features**, such as gender and/or race, satisfying\n", " $$\n", " \\sum_{i=1}^n z_{ij}=0\n", " $$\n", "- $z_i \\in \\mathbb{R}^{d_0}$ is a $d_0$-length sensitive feature vector\n", "- $\\rho \\in \\mathbb{R}_+^{d_0}$ is a vector of constants that trade off predictive accuracy and fairness\n", "\n", "The constraints limit the correlation between the sensitive features and the decision function, helping ensure fairness in predictions.\n", "\n", "> **Note.** Since the hinge loss is a plq function and the fairness constraints are linear, we can optimize this model using `rehline.plq_Ridge_Classifier`." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "id": "CdpIoLwYNrOE" }, "outputs": [], "source": [ "## install rehline\n", "%pip install rehline -q" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "id": "FcaI-p84K6m4" }, "outputs": [], "source": [ "## simulate data\n", "import numpy as np\n", "from sklearn.datasets import make_classification\n", "from sklearn.preprocessing import StandardScaler\n", "\n", "scaler = StandardScaler()\n", "\n", "n, d = 10000, 5\n", "X, y = make_classification(n_samples=n, n_features=d, n_redundant=2, random_state=42)\n", "y = 2 * y - 1\n", "X = scaler.fit_transform(X)\n", "\n", "## we take the first column of X as sensitive features, and tol is 0.1\n", "sen_idx = [0]\n", "tol_sen = 0.1" ] }, { "cell_type": "markdown", "metadata": { "id": "VEQKzCdrM3ii" }, "source": [ "## SVM as baseline" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 80 }, "id": "uUMv2d0ZM1X5", "outputId": "26300c19-6800-4537-ee51-455d2415c54d" }, "outputs": [ { "data": { "text/html": [ "
plq_Ridge_Classifier(loss={'name': 'svm'}, max_iter=50000)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" ], "text/plain": [ "plq_Ridge_Classifier(loss={'name': 'svm'}, max_iter=50000)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "## we first run a SVM\n", "from rehline import plq_Ridge_Classifier\n", "\n", "clf = plq_Ridge_Classifier(loss={\"name\": \"svm\"}, C=1.0, max_iter=50000)\n", "clf.fit(X=X, y=y)" ] }, { "cell_type": "markdown", "metadata": { "id": "4S9GFijHNPCC" }, "source": [ "## FairSVM" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 114 }, "id": "F17oa5oUNGed", "outputId": "e162d128-0ba8-4b7b-96f6-b6a7c7ba58ae" }, "outputs": [ { "data": { "text/html": [ "
plq_Ridge_Classifier(constraint=[{'name': 'fair', 'sen_idx': [0],\n",
       "                                  'tol_sen': 0.1}],\n",
       "                     loss={'name': 'svm'}, max_iter=50000)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" ], "text/plain": [ "plq_Ridge_Classifier(constraint=[{'name': 'fair', 'sen_idx': [0],\n", " 'tol_sen': 0.1}],\n", " loss={'name': 'svm'}, max_iter=50000)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "## solve FairSVM via `plq_Ridge_Classifier` by adding `constraint`\n", "import warnings\n", "\n", "warnings.filterwarnings(\"ignore\")\n", "fclf = plq_Ridge_Classifier(\n", " loss={\"name\": \"svm\"}, constraint=[{\"name\": \"fair\", \"sen_idx\": sen_idx, \"tol_sen\": tol_sen}], C=1.0, max_iter=50000\n", ")\n", "fclf.fit(X=X, y=y)" ] }, { "cell_type": "markdown", "metadata": { "id": "4PsZ5ASPO2lN" }, "source": [ "## Results" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "WNhi1tI_NJc_", "outputId": "6be1b2f1-b860-4756-d686-1d527e48e6b3" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " Model Train Performance Correlation with Sensitive Features\n", " SVM 0.8927 2.417714\n", "FairSVM 0.5278 0.100728\n" ] } ], "source": [ "import pandas as pd\n", "\n", "## sensitive features\n", "X_sen = X[:, sen_idx]\n", "\n", "## score\n", "score = clf.decision_function(X)\n", "fscore = fclf.decision_function(X)\n", "\n", "svm_perf = len(y[score * y > 0]) / n\n", "fsvm_perf = len(y[fscore * y > 0]) / n\n", "\n", "svm_corr = score.dot(X_sen) / n\n", "fsvm_corr = fscore.dot(X_sen) / n\n", "\n", "# Create a pandas DataFrame to store the results\n", "results = pd.DataFrame(\n", " {\n", " \"Model\": [\"SVM\", \"FairSVM\"],\n", " \"Train Performance\": [svm_perf, fsvm_perf],\n", " \"Correlation with Sensitive Features\": [svm_corr[0], fsvm_corr[0]],\n", " }\n", ")\n", "\n", "# Print the results as a table\n", "print(results.to_string(index=False))" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 885 }, "id": "rKNP993vNMAo", "outputId": "1ca8ba1f-60f9-446f-99a2-61fbfe039f65" }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjsAAAHHCAYAAABZbpmkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAN9NJREFUeJzt3Xl8FfW9//F3AlnYkhSysSQBAQkBBGQNqBWISSG9iqCiICIiVhqoglUai4K0giIVahqgtRj0llRKq60CiiEsKgkRo1j2K15sMDvFENYknMzvD2/Or8fkJCQ5Ocvwej4e59Ge+X5n5vPNGHgz850ZL8MwDAEAAJiUt6sLAAAAaEmEHQAAYGqEHQAAYGqEHQAAYGqEHQAAYGqEHQAAYGqEHQAAYGqEHQAAYGqEHQAAYGqEHQAAYGqEHQBu7+DBg7rrrrsUFRUlf39/de3aVbfddptSUlL02WefycvLS4sWLbK7/pdffikvLy8tWLBAkrRkyRJ5eXnJ29tbp06dqtW/vLxcbdq0kZeXl+bOndti4wLgHIQdAG4tKytLQ4cO1RdffKHZs2frd7/7nR5++GF5e3vrt7/9rW688UZFR0frz3/+s91tpKenS5Luv/9+m+V+fn51rvfWW285dhAAXKq1qwsAgPo8//zzCgwM1P79+xUUFGTTVlJSIkmaNm2annnmGe3bt08jR46stY0///nPio6O1o033mizfMKECfrzn/+sp556ymZ5enq6EhMT9be//c2xgwHgEpzZAeDWvvrqK/Xr169W0JGk0NBQSd+FHen/n8H5T7m5uTp+/Li1z3+aOnWqDhw4oGPHjlmXFRUVaefOnZo6daqDRgDA1Qg7ANxaVFSUcnNzdejQIbt9evTooVGjRukvf/mLLBaLTVtNAKorvNxyyy3q1q2bTUjatGmT2rdvr8TERAeNAICrEXYAuLWf//znunjxogYNGqRRo0Zp4cKF+uCDD1RVVWXTb9q0aSouLlZmZqZ1WXV1tTZt2qTY2Fhdd911tbbt5eWle++912bezsaNGzVp0iT5+fm13KAAOBVhB4Bbu+2225Sdna3bb79dX3zxhVasWKGEhAR17dpV77zzjrXflClT5OPjY3OWZs+ePcrPz6/zElaNqVOn6sSJE9q/f7/1f7mEBZgLYQeA2xs2bJjeeustffvtt/rkk0+UnJysc+fO6a677tKRI0ckSZ06dVJCQoLefvttXb58WdJ3l7Bat26te+65x+62Bw8erOjoaKWnp2vjxo0KDw/X2LFjnTIuAM5B2AHgMXx9fTVs2DAtW7ZMa9euVVVVlTZv3mxtv//++1VeXq4tW7aosrJSf/vb3xQfH6+QkJB6tzt16lRt2rRJ6enpmjJliry9+aMRMBN+owF4pKFDh0qSCgsLrctuv/12dejQQenp6Xrvvff07bff1nsJq8bUqVNVWFio//mf/+ESFmBCPGcHgFvbtWuXbr31Vnl5edks37ZtmySpT58+1mVt2rTRnXfeqU2bNunixYtq166d7rjjjgb30bNnT61evVqXLl3S8OHDHTsAAC5H2AHg1ubNm6eLFy/qzjvvVHR0tCorK5WVlaVNmzape/fumjlzpk3/+++/X2+88Ya2b9+uadOmqV27dle1n8cee6wlygfgBgg7ANzaypUrtXnzZm3btk1/+MMfVFlZqcjISP30pz/VokWLaj1scOzYsercubMKCwuv6hIWAPPzMgzDcHURAAAALYUJygAAwNQIOwAAwNQIOwAAwNQIOwAAwNQIOwAAwNQIOwAAwNR4zo6k6upqFRQUqEOHDrWe0goAANyTYRg6d+6cunTpUu877Qg7kgoKChQREeHqMgAAQBOcOnVK3bp1s9tO2JHUoUMHSd/9sAICAlxcDQAAuBrl5eWKiIiw/j1uD2FHsl66CggIIOwAAOBhGpqCwgRlAABgaoQdAABgaoQdAABgaszZAQDAQ1gsFlVVVbm6DKfx8fFRq1atmr0dwg4AAG7OMAwVFRWprKzM1aU4XVBQkMLDw5v1HDzCDgAAbq4m6ISGhqpt27bXxANwDcPQxYsXVVJSIknq3Llzk7dF2AEAwI1ZLBZr0OnUqZOry3GqNm3aSJJKSkoUGhra5EtaTFAGAMCN1czRadu2rYsrcY2acTdnrhJhBwAAD3AtXLqqiyPGTdgBAACmRtgBAACmRtgBAACmRtgBAACmRtgBAAA23njjDXXq1EkVFRU2yydOnKjp06e7qKqmI+wAAAAbd999tywWi9555x3rspKSEm3dulUPPfSQCytrGh4qCMCpxo4Zo9LSUrvtISEh2rlrlxMrAvB9bdq00dSpU5WWlqa7775bkvSnP/1JkZGRuvXWW11bXBMQdgA4VWlpqXJ2bLfbPiIuwYnVALBn9uzZGjZsmPLz89W1a1dt2LBBDz74oEc+74ewAwAAahk8eLAGDhyoN954Q/Hx8Tp8+LC2bt3q6rKahLADAADq9PDDD2v16tXKz89XXFycIiIiXF1SkzBBGQAA1Gnq1Kn65ptv9Oqrr3rkxOQanNkB4Fby8/M1oH9/u+1MYAacJzAwUJMnT9bWrVs1ceJEV5fTZIQdAG7FMKqZwAy4kfz8fE2bNk1+fn6uLqXJCDsAAKCWb7/9Vrt379bu3bu1Zs0aV5fTLIQdAABQy+DBg/Xtt9/qxRdfVJ8+fVxdTrMQdgAAQC1ff/21q0twGO7GAgAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApsbdWADggW4afbOKi4vstoeFhevjvR85sSLAfRF2AMADFRcXaX7S03bbV6Uuc2I1cJW8vDydPn3aKfsKDg5WZGSkU/blaIQdADCh/PwC9e7V2247Z348X15envr27auLFy86ZX9t27bV0aNHmxV43nrrLa1bt065ubk6c+aMPv/8cw0aNMhxRdpB2AEAE7JYLJz5MbnTp0/r4sWLWv+7V9Snt/1g6wjHv/xSs+b+TKdPn25W2Llw4YJuuukm3XPPPZo9e7YDK6wfYQcAAA/Wp3dvDb5hgKvLuCrTp0+X5PynM3M3FgAAMDXCDgAAMDXCDgAAcLiNGzeqffv21s9HH7luQjxzdgAAgMPdfvvtGjFihPV7165dXVYLYQeAQ40dM0alpaV22wsLCpxYDQBX6dChgzp06ODqMiQRdgA4WGlpqXJ2bLfb3jU6xonVAHAnZ86cUV5engr+7x89x48flySFh4crPDy8xfZL2AEAwIMd//JLj9nHO++8o5kzZ1q/33vvvZKkxYsXa8mSJQ7ZR10IOwAAeKDg4GC1bdtWs+b+zCn7a9u2rYKDg5u1jQcffFAPPvigYwpqBMIOAAAeKDIyUkePHuXdWFeBsAMAgIeKjIz02ADiTDxnBwAAmBphBwAAmBphBwAAmBphBwAAmBphBwAAmBphBwAAmBphBwAAmBrP2QEAwEPl5eXxUMGrQNgBAMAD5eXlKTo6WpcuXXLK/tq0aaNjx441KvB8+OGHeumll5Sbm6vCwkK9/fbbmjhxYssVaQdhBwAAD3T69GldunRJM6bNVnhYlxbdV1FxgV7f+KpOnz7dqLBz4cIFDRw4UA899JAmTZrUghXWj7ADAIAHCw/roshuUa4uo07jx4/X+PHjXV0GE5QBAIC5EXYAAICpEXYAAICpEXYAAICpMUEZQKOMHTNGpaWldtsLCwqcWA2aKj+/QL179a63T1hYuD7e+5GTKgJaDmEHgFVDQUb6LszkHTlot71rdIyjy0ILsFgsmp/0dL19VqUuc1I1MKvz58/rxIkT1u8nT57UgQMH1LFjR6c+oJCwA8CqtLRUOTu219uHMAO4l6Lilj+b2tR9fPrppxozZoz1+4IFCyRJM2bM0IYNGxxR2lVxm7DzwgsvKDk5WY899phWr14tSbp8+bKeeOIJvfnmm6qoqFBCQoLWrFmjsLAw63p5eXmaM2eOdu3apfbt22vGjBlavny5Wrd2m6EBAOBwwcHBatOmjV7f+KpT9temTRsFBwc3ap1bb71VhmG0UEVXzy0Swf79+/X73/9eN9xwg83y+fPna+vWrdq8ebMCAwM1d+5cTZo0SXv37pX03WnYxMREhYeHKysrS4WFhXrggQfk4+OjZcs4/QoAMK/IyEgdO3aMd2NdBZeHnfPnz2vatGl69dVX9etf/9q6/OzZs1q/fr3S09M1duxYSVJaWpr69u2rffv2aeTIkfrggw905MgR7dixQ2FhYRo0aJB+9atfaeHChVqyZIl8fX1dNSwAaJabRt+s4uIiu+35+UwEx3eBx1MDiDO5POwkJSUpMTFRcXFxNmEnNzdXVVVViouLsy6Ljo5WZGSksrOzNXLkSGVnZ2vAgAE2l7USEhI0Z84cHT58WIMHD65znxUVFaqoqLB+Ly8vb4GRAUDTFRcX1TuBeP7COU6sBvBsLg07b775pj777DPt37+/VltRUZF8fX0VFBRkszwsLExFRUXWPv8ZdGraa9rsWb58uZ577rlmVg8ATceZG8B5XBZ2Tp06pccee0wZGRny9/d36r6Tk5OtM8Kl787sREREOLUGANc2ztygsdxhoq8rOGLcLnuCcm5urkpKSnTjjTeqdevWat26tfbs2aNXXnlFrVu3VlhYmCorK1VWVmazXnFxscLDwyVJ4eHhKi4urtVe02aPn5+fAgICbD4AALgjHx8fSdLFixddXIlr1Iy75ufQFC47szNu3DgdPGj7YLKZM2cqOjpaCxcuVEREhHx8fJSZmanJkydLko4fP668vDzFxsZKkmJjY/X888+rpKREoaGhkqSMjAwFBAQoJoZngQAAPF+rVq0UFBSkkpISSVLbtm3l5eXl4qpanmEYunjxokpKShQUFKRWrVo1eVsuCzsdOnRQ//79bZa1a9dOnTp1si6fNWuWFixYoI4dOyogIEDz5s1TbGysRo4cKUmKj49XTEyMpk+frhUrVqioqEiLFi1SUlKS/Pz8nD4mAABaQs3ViprAcy0JCgqq92rN1XD53Vj1WbVqlby9vTV58mSbhwrWaNWqlbZs2aI5c+YoNjZW7dq104wZM7R06VIXVg0AgGN5eXmpc+fOCg0NVVVVlavLcRofH59mndGp4VZhZ/fu3Tbf/f39lZqaqtTUVLvrREVFadu2bS1cGQAArteqVSuH/OV/rXHZBGUAAABnIOwAAABTI+wAAABTI+wAAABTI+wAAABTI+wAAABTI+wAAABTI+wAAABTI+wAAABTI+wAAABTI+wAAABTI+wAAABTI+wAAABTc6u3ngNAQ/Lz8zWgf/96+4SEhGjnrl1OqgiAuyPsAPAohlGtnB3b6+0zIi7BSdUA8ARcxgIAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKbW2tUFAIDZ3DT6ZhUXF9XbJz+/wEnVACDsAICDFRcXaX7S0/X2mb9wjpOqAcBlLAAAYGqc2QFgOvn5+RrQv7/d9pCQEO3ctcuJFQFwJcIOANMxjGrl7Nhut31EXIITq/Fc+fkF6t2rt932sLBwfbz3IydWBDQNYQcAUCeLxVLv3KNVqcucWA3QdMzZAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAAptba1QUAgKe5afTNKi4ustuen1/gxGoANISwAwCNVFxcpPlJT9ttn79wjhOrAdAQLmMBAABTI+wAAABTI+wAAABTI+wAAABTI+wAAABT424sAECT5OcXqHev3nbbw8LC9fHej5xYEVA3wg4AoEksFku9t+CvSl3mxGoA+1x6GWvt2rW64YYbFBAQoICAAMXGxuq9996ztl++fFlJSUnq1KmT2rdvr8mTJ6u4uNhmG3l5eUpMTFTbtm0VGhqqJ598UleuXHH2UAAAgJtyadjp1q2bXnjhBeXm5urTTz/V2LFjdccdd+jw4cOSpPnz5+vdd9/V5s2btWfPHhUUFGjSpEnW9S0WixITE1VZWamsrCy9/vrr2rBhg5599llXDQkAALgZl17G+q//+i+b788//7zWrl2rffv2qVu3blq/fr3S09M1duxYSVJaWpr69u2rffv2aeTIkfrggw905MgR7dixQ2FhYRo0aJB+9atfaeHChVqyZIl8fX1dMSwAAOBG3OZuLIvFojfffFMXLlxQbGyscnNzVVVVpbi4OGuf6OhoRUZGKjs7W5KUnZ2tAQMGKCwszNonISFB5eXl1rNDdamoqFB5ebnNBwAAmJPLw87BgwfVvn17+fn56dFHH9Xbb7+tmJgYFRUVydfXV0FBQTb9w8LCVFT03Qv4ioqKbIJOTXtNmz3Lly9XYGCg9RMREeHYQQEAALfh8rDTp08fHThwQDk5OZozZ45mzJihI0eOtOg+k5OTdfbsWevn1KlTLbo/AADgOi6/9dzX11e9evWSJA0ZMkT79+/Xb3/7W02ZMkWVlZUqKyuzObtTXFys8PBwSVJ4eLg++eQTm+3V3K1V06cufn5+8vPzc/BIAACAO3L5mZ3vq66uVkVFhYYMGSIfHx9lZmZa244fP668vDzFxsZKkmJjY3Xw4EGVlJRY+2RkZCggIEAxMTFOrx0AALgfl57ZSU5O1vjx4xUZGalz584pPT1du3fv1vbt2xUYGKhZs2ZpwYIF6tixowICAjRv3jzFxsZq5MiRkqT4+HjFxMRo+vTpWrFihYqKirRo0SIlJSVx5gYAAEhycdgpKSnRAw88oMLCQgUGBuqGG27Q9u3bddttt0mSVq1aJW9vb02ePFkVFRVKSEjQmjVrrOu3atVKW7Zs0Zw5cxQbG6t27dppxowZWrp0qauGBAAA3IxLw8769evrbff391dqaqpSU1Pt9omKitK2bdscXRoAADAJt5uzAwAA4EiEHQAAYGqEHQAAYGqEHQAAYGqEHQAAYGqEHQAAYGqEHQAAYGqEHQAAYGoufxEoALibm0bfrOLiIrvt+fkFTqwGQHMRdgDge4qLizQ/6Wm77fMXznFiNQCai8tYAADA1Ag7AADA1Ag7AADA1Ag7AADA1Ag7AADA1JoUdq677jr9+9//rrW8rKxM1113XbOLAgAAcJQmhZ2vv/5aFoul1vKKigrl5+c3uygAAABHadRzdt555x3r/9++fbsCAwOt3y0WizIzM9W9e3eHFQfAscaOGaPS0lK77YUFPCwPgPk0KuxMnDhRkuTl5aUZM2bYtPn4+Kh79+76zW9+47DiADhWaWmpcnZst9veNTrGidUAgHM0KuxUV1dLknr06KH9+/crODi4RYoCAABwlCa9LuLkyZOOrgOAA3CZCgBqa/K7sTIzM5WZmamSkhLrGZ8ar732WrMLA9B4XKYCgNqaFHaee+45LV26VEOHDlXnzp3l5eXl6LoAAAAcoklhZ926ddqwYYOmT5/u6HoAAAAcqknP2amsrNSoUaMcXQsAAIDDNSnsPPzww0pPT3d0LQAAAA7XpMtYly9f1h/+8Aft2LFDN9xwg3x8fGzaX375ZYcUBwAA0FxNCjv//Oc/NWjQIEnSoUOHbNqYrAwAANxJk8LOrl27HF0HAABAi2jSnB0AAABP0aQzO2PGjKn3ctXOnTubXBAAAIAjNSns1MzXqVFVVaUDBw7o0KFDtV4QCgAA4EpNCjurVq2qc/mSJUt0/vz5ZhUEAADgSA6ds3P//ffzXiwAAOBWHBp2srOz5e/v78hNAgAANEuTLmNNmjTJ5rthGCosLNSnn36qZ555xiGFAQAAOEKTwk5gYKDNd29vb/Xp00dLly5VfHy8QwoDAABwhCaFnbS0NEfXAQAA0CKaFHZq5Obm6ujRo5Kkfv36afDgwQ4pCgAAwFGaFHZKSkp07733avfu3QoKCpIklZWVacyYMXrzzTcVEhLiyBoBAACarEl3Y82bN0/nzp3T4cOHdebMGZ05c0aHDh1SeXm5fvaznzm6RgAAgCZr0pmd999/Xzt27FDfvn2ty2JiYpSamsoEZQAA4FaadGanurpaPj4+tZb7+Piourq62UUBAAA4SpPCztixY/XYY4+poKDAuiw/P1/z58/XuHHjHFYcAABAczUp7Pzud79TeXm5unfvrp49e6pnz57q0aOHysvLlZKS4ugaAQAAmqxJc3YiIiL02WefaceOHTp27JgkqW/fvoqLi3NocQAAAM3VqDM7O3fuVExMjMrLy+Xl5aXbbrtN8+bN07x58zRs2DD169dPH330UUvVCgAA0GiNCjurV6/W7NmzFRAQUKstMDBQP/nJT/Tyyy87rDgAAIDmatRlrC+++EIvvvii3fb4+HitXLmy2UUBQEvKz8/XgP797baXlpY4sRoALa1RYae4uLjOW86tG2vdWqWlpc0uCgBakmFUK2fHdrvtXa7va7cNVy8/v0C9e/W22x4WFq6P9zL1AS2vUWGna9euOnTokHr16lVn+z//+U917tzZIYUBADybxWLR/KSn7bavSl3mxGpwLWvUnJ0JEybomWee0eXLl2u1Xbp0SYsXL9aPf/xjhxUHAADQXI06s7No0SK99dZbuv766zV37lz16dNHknTs2DGlpqbKYrHol7/8ZYsUCgAA0BSNCjthYWHKysrSnDlzlJycLMMwJEleXl5KSEhQamqqwsLCWqRQAACApmj0QwWjoqK0bds2ffvttzpx4oQMw1Dv3r31gx/8oCXqAwAAaJYmPUFZkn7wgx9o2LBhjqwFAADA4Zr0biwAAABPQdgBAACmRtgBAACmRtgBAACmRtgBAACmRtgBAACmRtgBAACmRtgBAACm5tKws3z5cg0bNkwdOnRQaGioJk6cqOPHj9v0uXz5spKSktSpUye1b99ekydPVnFxsU2fvLw8JSYmqm3btgoNDdWTTz6pK1euOHMoAADATbk07OzZs0dJSUnat2+fMjIyVFVVpfj4eF24cMHaZ/78+Xr33Xe1efNm7dmzRwUFBZo0aZK13WKxKDExUZWVlcrKytLrr7+uDRs26Nlnn3XFkAAAgJtp8usiHOH999+3+b5hwwaFhoYqNzdXt9xyi86ePav169crPT1dY8eOlSSlpaWpb9++2rdvn0aOHKkPPvhAR44c0Y4dOxQWFqZBgwbpV7/6lRYuXKglS5bI19fXFUMDAABuwq3m7Jw9e1aS1LFjR0lSbm6uqqqqFBcXZ+0THR2tyMhIZWdnS5Kys7M1YMAAm7etJyQkqLy8XIcPH65zPxUVFSovL7f5AAAAc3KbsFNdXa3HH39co0ePVv/+/SVJRUVF8vX1VVBQkE3fsLAwFRUVWfv8Z9Cpaa9pq8vy5csVGBho/URERDh4NAAAwF24TdhJSkrSoUOH9Oabb7b4vpKTk3X27Fnr59SpUy2+TwAA4BounbNTY+7cudqyZYs+/PBDdevWzbo8PDxclZWVKisrszm7U1xcrPDwcGufTz75xGZ7NXdr1fT5Pj8/P/n5+Tl4FAAAwB259MyOYRiaO3eu3n77be3cuVM9evSwaR8yZIh8fHyUmZlpXXb8+HHl5eUpNjZWkhQbG6uDBw+qpKTE2icjI0MBAQGKiYlxzkAAAIDbcumZnaSkJKWnp+sf//iHOnToYJ1jExgYqDZt2igwMFCzZs3SggUL1LFjRwUEBGjevHmKjY3VyJEjJUnx8fGKiYnR9OnTtWLFChUVFWnRokVKSkri7A0AAHBt2Fm7dq0k6dZbb7VZnpaWpgcffFCStGrVKnl7e2vy5MmqqKhQQkKC1qxZY+3bqlUrbdmyRXPmzFFsbKzatWunGTNmaOnSpc4aBgAAcGMuDTuGYTTYx9/fX6mpqUpNTbXbJyoqStu2bXNkaQAAwCTc5m4sAACAlkDYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAApkbYAQAAptba1QUAAK5N+fkF6t2rt932sLBwfbz3IydWBLMi7AAAXMJisWh+0tN221elLnNiNTAzLmMBAABTI+wAAABTI+wAAABTI+wAAABTI+wAAABTI+wAAABT49ZzANecK1csSklJsd9usTixGgAtjbAD4BpkKHbYzfW02w9CADwPl7EAAICpEXYAAICpEXYAAICpEXYAAICpEXYAAICpEXYAAICpEXYAAICpEXYAAICpEXYAAICp8QRlwI2MHTNGpaWldttDQkK0c9cuJ1YEAJ6PsAO4kdLSUuXs2G63vVvf/hrQv7/d9sKCgpYoCwA8GmEH8CCGUV1vGOoaHePEagDAMxB2AOB7jOpqvfjyErvt3t5ezisGQLMRdgDge7y9vfXfKWvstk+Ydo8TqwHQXNyNBQAATI2wAwAATI2wAwAATI2wAwAATI2wAwAATI2wAwAATI2wAwAATI2wAwAATI2wAwAATI2wAwAATI2wAwAATI2wAwAATI2wAwAATI2wAwAATI2wAwAATI2wAwAATI2wAwAATI2wAwAATI2wAwAATK21qwsAAEe7csWilJQU+x0M59UCwPUIOwBMyFDssJvraa8nCF3N1qur9eLLS+y2e3t7NWv7AByLsAMAjeTt7a3/Tlljt33CtHucWA2AhjBnBwAAmBphBwAAmBphBwAAmBpzdgAAbik/v0C9e/Wut09YWLg+3vuRkyqCp3Jp2Pnwww/10ksvKTc3V4WFhXr77bc1ceJEa7thGFq8eLFeffVVlZWVafTo0Vq7dq169/7///GfOXNG8+bN07vvvitvb29NnjxZv/3tb9W+fXsXjAgA4CgWi0Xzk56ut8+q1GVOqgaezKWXsS5cuKCBAwcqNTW1zvYVK1bolVde0bp165STk6N27dopISFBly9ftvaZNm2aDh8+rIyMDG3ZskUffvihHnnkEWcNAQAAuDmXntkZP368xo8fX2ebYRhavXq1Fi1apDvuuEOS9MYbbygsLEx///vfde+99+ro0aN6//33tX//fg0dOlSSlJKSogkTJmjlypXq0qWL08YCAADck9tOUD558qSKiooUFxdnXRYYGKgRI0YoOztbkpSdna2goCBr0JGkuLg4eXt7Kycnx+62KyoqVF5ebvMBAADm5LZhp6ioSJIUFhZmszwsLMzaVlRUpNDQUJv21q1bq2PHjtY+dVm+fLkCAwOtn4iICAdXDwAA3MU1eTdWcnKyFixYYP1eXl5O4EGLGztmjEpLS+vtU1hQ4KRqAODa4bZhJzw8XJJUXFyszp07W5cXFxdr0KBB1j4lJSU26125ckVnzpyxrl8XPz8/+fn5Ob5ooB6lpaXK2bG93j5do2OcVA0AXDvc9jJWjx49FB4erszMTOuy8vJy5eTkKDY2VpIUGxursrIy5ebmWvvs3LlT1dXVGjFihNNrBgAA7selZ3bOnz+vEydOWL+fPHlSBw4cUMeOHRUZGanHH39cv/71r9W7d2/16NFDzzzzjLp06WJ9Fk/fvn31ox/9SLNnz9a6detUVVWluXPn6t577+VOLMCkrlyxKCWlgbeWG86pBa7X0IMHeeggJBeHnU8//VRjxoyxfq+ZRzNjxgxt2LBBTz31lC5cuKBHHnlEZWVluummm/T+++/L39/fus7GjRs1d+5cjRs3zvpQwVdeecXpYwHgLIZih93cQJ8GwhBMo6EHD/LQQUguDju33nqrDMP+P8G8vLy0dOlSLV261G6fjh07Kj09vSXKAwAAJuC2c3YAAAAcgbADAABMjbADAABMzW2fswN4moYeGsgDAwHANQg7gIM09NBAHhgIAK7BZSwAAGBqhB0AAGBqhB0AAGBqhB0AAGBqhB0AAGBqhB0AAGBqhB0AAGBqhB0AAGBqPFQQABzMqK7Wiy8vqbePt7eXc4oBQNgBAEfz9vbWf6esqbfPhGn3OKkaAFzGAgAApsaZHeAq8aJPAPBMhB3gKvGiTwDwTFzGAgAApkbYAQAApsZlLABwgYZuT+fWdMBxCDu4ZjQ0wTgkJEQ7d+1yYkW4ljV0ezq3pgOOQ9jBNaOhCcYj4hKcWA0AwFkIOwAA08rPL1DvXr3ttoeFhevjvR85sSK4AmEH+D/5+fka0L+/3Xaeo+McV65YlJKSYr+D4bxa4PksFovmJz1tt31V6jInVgNXIewA/8cwqnmOjlswFDvs5nra6wlCAFAHbj0HAACmRtgBAACmRtgBAACmRtgBAACmRtgBAACmRtgBAACmRtgBAACmRtgBAACmRtgBAACmRtgBAACmRtgBAACmxruxADgVL/oE4GyEHQBOxos+ATgXYQcAPJC3t5defHlJve0AvkPYAQAP1KqVt/47ZY3d9gnT7nFiNZ4rP79AvXv1ttseFhauj/d+5MSK0BIIOwCAa5bFYtH8pKfttq9KXebEatBSuBsLAACYGmEHAACYGpexYApjx4xRaWlpvX0KCwqcVA0AwJ0QduARGgozhQUFyjtysN5tdI2OcXRZAAAPQNiBRygtLVXOju122wkyAAB7mLMDAABMjbADAABMjctYAOCGjOrqep+Q3Nz1ecIyriWEHQCN0tCLPK9UXeFFnw7g7V3/E5ITG3hCckPr84RlXEsIOwAaqeEXefKiTwDuhLADt3A1t5YDANAUhB04RXOfk8Ot5QCApiLswCl4Tg4AT8Rb0c2BsAMAgB28Fd0cCDsAcA26mlvbuT0dZkHYAYBrUEO3pkvcng7z4AnKAADA1DizA8CqoQcGSuKhgLDy9va65p/S3NAEZolJzO6AsAOH4Dk5ZtHQAwMlHgqIGq1a8ZTmhiYwS9LPn57LHV0uRtiBQ3BrOQDUjTu6XI+wAwCoU3NfRgq4C9OEndTUVL300ksqKirSwIEDlZKSouHDh7u6LKdo6BJSSEiIdu7a5cSKAJhBc19GypvX4S5MEXY2bdqkBQsWaN26dRoxYoRWr16thIQEHT9+XKGhoa4ur8U1dAlpRFxCs7bfUJiSmJMDoLaGwtL4++4iDMEpTBF2Xn75Zc2ePVszZ86UJK1bt05bt27Va6+9pl/84hcurq75Wnryb3PfWyUxJ8ddNHQ31ZWqK/XfbcWdVnCihsLQtTDBWeKVFM7g8WGnsrJSubm5Sk5Oti7z9vZWXFycsrOzXViZ47T05F8mF1+dBoPEFYsTq7GnobupUhpsBzyJGW5/ZwJzy/P4sHP69GlZLBaFhYXZLA8LC9OxY8fqXKeiokIVFRXW72fPnpUklZeXO7y+Hycm6vTp03bbg4ODtWXr1nq3YbFYVH7unN12wzDqbbdYLPWOLT8/Xy+tXGm3varqSr3br+nTnG00NIbmtl9VjZVV9bYb1dW6od+Qetvd4ed44eLFFmt3xj6o0T3a3aGGaotFy1c+W2+N3t5eWvei/d+ZyQ9Nr3cbXl7SpcuX6m1vzvqO2EZ1dXWL/P30n+JvS1BpaYnd9pCQUH2QYf8fxc1dv6lqfi6G0cBpacPD5efnG5KMrKwsm+VPPvmkMXz48DrXWbx4saHvTtjz4cOHDx8+fDz8c+rUqXqzgsef2QkODlarVq1UXFxss7y4uFjh4eF1rpOcnKwFCxZYv1dXV+vMmTPq1KmTvLwaf8qzvLxcEREROnXqlAICAhq9vidizIzZrBiz+cd8rY1XMu+YDcPQuXPn1KVLl3r7eXzY8fX11ZAhQ5SZmamJEydK+i68ZGZmau7cuXWu4+fnJz8/P5tlQUFBza4lICDAVP8RXQ3GfG1gzNeGa23M19p4JXOOOTAwsME+Hh92JGnBggWaMWOGhg4dquHDh2v16tW6cOGC9e4sAABw7TJF2JkyZYpKS0v17LPPqqioSIMGDdL7779fa9IyAAC49pgi7EjS3Llz7V62aml+fn5avHhxrUtjZsaYrw2M+dpwrY35WhuvdG2O+T95GUZD92sBAAB4Lm9XFwAAANCSCDsAAMDUCDsAAMDUCDsAAMDUCDtX4fnnn9eoUaPUtm1buw8fzMvLU2Jiotq2bavQ0FA9+eSTunLlSr3bPXPmjKZNm6aAgAAFBQVp1qxZOn/+fAuMoPl2794tLy+vOj/79++3u96tt95aq/+jjz7qxMqbp3v37rXqf+GFF+pd5/Lly0pKSlKnTp3Uvn17TZ48udYTvt3V119/rVmzZqlHjx5q06aNevbsqcWLF6uysrLe9TztOKempqp79+7y9/fXiBEj9Mknn9Tbf/PmzYqOjpa/v78GDBigbdu2OanS5lu+fLmGDRumDh06KDQ0VBMnTtTx48frXWfDhg21jqe/v7+TKm6+JUuW1Ko/Ojq63nU8+RhLdf9Z5eXlpaSkpDr7e/oxbizCzlWorKzU3XffrTlz5tTZbrFYlJiYqMrKSmVlZen111/Xhg0b9Oyz9b/Abtq0aTp8+LAyMjK0ZcsWffjhh3rkkUdaYgjNNmrUKBUWFtp8Hn74YfXo0UNDhw6td93Zs2fbrLdixQonVe0YS5cutal/3rx59fafP3++3n33XW3evFl79uxRQUGBJk2a5KRqm+fYsWOqrq7W73//ex0+fFirVq3SunXr9PTT9t/IXMNTjvOmTZu0YMECLV68WJ999pkGDhyohIQElZTU/RLDrKws3XfffZo1a5Y+//xzTZw4URMnTtShQ4ecXHnT7NmzR0lJSdq3b58yMjJUVVWl+Ph4Xbhwod71AgICbI7nv/71LydV7Bj9+vWzqf/jjz+229fTj7Ek7d+/32a8GRkZkqS7777b7jqefowbxTGv47w2pKWlGYGBgbWWb9u2zfD29jaKioqsy9auXWsEBAQYFRUVdW7ryJEjhiRj//791mXvvfee4eXlZeTn5zu8dkerrKw0QkJCjKVLl9bb74c//KHx2GOPOaeoFhAVFWWsWrXqqvuXlZUZPj4+xubNm63Ljh49akgysrOzW6DClrdixQqjR48e9fbxpOM8fPhwIykpyfrdYrEYXbp0MZYvX15n/3vuucdITEy0WTZixAjjJz/5SYvW2VJKSkoMScaePXvs9rH3Z52nWLx4sTFw4MCr7m+2Y2wYhvHYY48ZPXv2NKqrq+ts9/Rj3Fic2XGA7OxsDRgwwOaJzQkJCSovL9fhw4ftrhMUFGRzViQuLk7e3t7Kyclp8Zqb65133tG///3vq3olx8aNGxUcHKz+/fsrOTlZFy9edEKFjvPCCy+oU6dOGjx4sF566aV6L0/m5uaqqqpKcXFx1mXR0dGKjIxUdna2M8p1uLNnz6pjx44N9vOE41xZWanc3Fyb4+Pt7a24uDi7xyc7O9umv/Td77cnH09JDR7T8+fPKyoqShEREbrjjjvs/lnmrr788kt16dJF1113naZNm6a8vDy7fc12jCsrK/WnP/1JDz30UL0vt/b0Y9wYpnmCsisVFRXVejVFzfeioiK764SGhtosa926tTp27Gh3HXeyfv16JSQkqFu3bvX2mzp1qqKiotSlSxf985//1MKFC3X8+HG99dZbTqq0eX72s5/pxhtvVMeOHZWVlaXk5GQVFhbq5ZdfrrN/UVGRfH19a83tCgsL84jj+n0nTpxQSkqKVq5cWW8/TznOp0+flsViqfP39dixY3WuY+/32xOPZ3V1tR5//HGNHj1a/fv3t9uvT58+eu2113TDDTfo7NmzWrlypUaNGqXDhw83+DvvDkaMGKENGzaoT58+Kiws1HPPPaebb75Zhw4dUocOHWr1N9MxlqS///3vKisr04MPPmi3j6cf40Zz9aklV1m4cKEhqd7P0aNHbdaxd9pv9uzZRnx8vM2yCxcuGJKMbdu21bn/559/3rj++utrLQ8JCTHWrFnT9IE1UlN+DqdOnTK8vb2Nv/71r43eX2ZmpiHJOHHihKOG0GhNGXON9evXG61btzYuX75cZ/vGjRsNX1/fWsuHDRtmPPXUUw4dR2M0ZczffPON0bNnT2PWrFmN3p87HOe65OfnG5KMrKwsm+VPPvmkMXz48DrX8fHxMdLT022WpaamGqGhoS1WZ0t59NFHjaioKOPUqVONWq+ystLo2bOnsWjRohaqrGV9++23RkBAgPHHP/6xznYzHWPDMIz4+Hjjxz/+caPW8fRj3JBr9szOE088UW/qlaTrrrvuqrYVHh5e626OmrtvwsPD7a7z/QmRV65c0ZkzZ+yu0xKa8nNIS0tTp06ddPvttzd6fyNGjJD03RmDnj17Nnp9R2jOsR8xYoSuXLmir7/+Wn369KnVHh4ersrKSpWVldmc3SkuLnbqcf2+xo65oKBAY8aM0ahRo/SHP/yh0ftzh+Ncl+DgYLVq1arW3XH1HZ/w8PBG9XdXc+fOtd4I0dh/ufv4+Gjw4ME6ceJEC1XXsoKCgnT99dfbrd8sx1iS/vWvf2nHjh2NPqvq6ce4Idds2AkJCVFISIhDthUbG6vnn39eJSUl1ktTGRkZCggIUExMjN11ysrKlJubqyFDhkiSdu7cqerqautfFM7Q2J+DYRhKS0vTAw88IB8fn0bv78CBA5Kkzp07N3pdR2nOsT9w4IC8vb1rXYKsMWTIEPn4+CgzM1OTJ0+WJB0/flx5eXmKjY1tcs3N1Zgx5+fna8yYMRoyZIjS0tLk7d34qX3ucJzr4uvrqyFDhigzM1MTJ06U9N2lnczMTLsvEo6NjVVmZqYef/xx67KMjAyXHs/GMAxD8+bN09tvv63du3erR48ejd6GxWLRwYMHNWHChBaosOWdP39eX331laZPn15nu6cf4/+Ulpam0NBQJSYmNmo9Tz/GDXL1qSVP8K9//cv4/PPPjeeee85o37698fnnnxuff/65ce7cOcMwDOPKlStG//79jfj4eOPAgQPG+++/b4SEhBjJycnWbeTk5Bh9+vQxvvnmG+uyH/3oR8bgwYONnJwc4+OPPzZ69+5t3HfffU4fX2Ps2LHD7mWeb775xujTp4+Rk5NjGIZhnDhxwli6dKnx6aefGidPnjT+8Y9/GNddd51xyy23OLvsJsnKyjJWrVplHDhwwPjqq6+MP/3pT0ZISIjxwAMPWPt8f8yG8d2lgsjISGPnzp3Gp59+asTGxhqxsbGuGEKjffPNN0avXr2McePGGd98841RWFho/fxnH08+zm+++abh5+dnbNiwwThy5IjxyCOPGEFBQda7KadPn2784he/sPbfu3ev0bp1a2PlypXG0aNHjcWLFxs+Pj7GwYMHXTWERpkzZ44RGBho7N692+Z4Xrx40drn+2N+7rnnjO3btxtfffWVkZuba9x7772Gv7+/cfjwYVcModGeeOIJY/fu3cbJkyeNvXv3GnFxcUZwcLBRUlJiGIb5jnENi8ViREZGGgsXLqzVZrZj3FiEnaswY8aMOuc47Nq1y9rn66+/NsaPH2+0adPGCA4ONp544gmjqqrK2r5r1y5DknHy5Enrsn//+9/GfffdZ7Rv394ICAgwZs6caQ1Q7uq+++4zRo0aVWfbyZMnbX4ueXl5xi233GJ07NjR8PPzM3r16mU8+eSTxtmzZ51YcdPl5uYaI0aMMAIDAw1/f3+jb9++xrJly2zm63x/zIZhGJcuXTJ++tOfGj/4wQ+Mtm3bGnfeeadNWHBnaWlpduf01DDDcU5JSTEiIyMNX19fY/jw4ca+ffusbT/84Q+NGTNm2PT/y1/+Ylx//fWGr6+v0a9fP2Pr1q1Orrjp7B3PtLQ0a5/vj/nxxx+3/nzCwsKMCRMmGJ999pnzi2+iKVOmGJ07dzZ8fX2Nrl27GlOmTLGZP2a2Y1xj+/bthiTj+PHjtdrMdowby8swDMOJJ5IAAACciufsAAAAUyPsAAAAUyPsAAAAUyPsAAAAUyPsAAAAUyPsAAAAUyPsAAAAUyPsAAAAUyPsAAAAUyPsAICkyspKV5cAoIUQdgC4tb/+9a8aMGCA2rRpo06dOikuLk4XLlyQJL322mvq16+f/Pz81LlzZ5s3l+fl5emOO+5Q+/btFRAQoHvuuUfFxcXW9iVLlmjQoEH64x//qB49esjf31+SVFZWpocfflghISEKCAjQ2LFj9cUXXzh30AAcirADwG0VFhbqvvvu00MPPaSjR49q9+7dmjRpkgzD0Nq1a5WUlKRHHnlEBw8e1DvvvKNevXpJkqqrq3XHHXfozJkz2rNnjzIyMvS///u/mjJlis32T5w4ob/97W966623dODAAUnS3XffrZKSEr333nvKzc3VjTfeqHHjxunMmTPOHj4AB+FFoADc1meffaYhQ4bo66+/VlRUlE1b165dNXPmTP3617+utV5GRobGjx+vkydPKiIiQpJ05MgR9evXT5988omGDRumJUuWaNmyZcrPz1dISIgk6eOPP1ZiYqJKSkrk5+dn3V6vXr301FNP6ZFHHmnB0QJoKa1dXQAA2DNw4ECNGzdOAwYMUEJCguLj43XXXXepqqpKBQUFGjduXJ3rHT16VBEREdagI0kxMTEKCgrS0aNHNWzYMElSVFSUNehI0hdffKHz58+rU6dONtu7dOmSvvrqqxYYIQBnIOwAcFutWrVSRkaGsrKy9MEHHyglJUW//OUvlZmZ6ZDtt2vXzub7+fPn1blzZ+3evbtW36CgIIfsE4DzEXYAuDUvLy+NHj1ao0eP1rPPPquoqChlZGSoe/fuyszM1JgxY2qt07dvX506dUqnTp2yuYxVVlammJgYu/u68cYbVVRUpNatW6t79+4tNSQATkbYAeC2cnJylJmZqfj4eIWGhionJ0elpaXq27evlixZokcffVShoaEaP368zp07p71792revHmKi4vTgAEDNG3aNK1evVpXrlzRT3/6U/3whz/U0KFD7e4vLi5OsbGxmjhxolasWKHrr79eBQUF2rp1q+6888561wXgvgg7ANxWQECAPvzwQ61evVrl5eWKiorSb37zG40fP16SdPnyZa1atUo///nPFRwcrLvuukvSd2eD/vGPf2jevHm65ZZb5O3trR/96EdKSUmpd39eXl7atm2bfvnLX2rmzJkqLS1VeHi4brnlFoWFhbX4eAG0DO7GAgAApsZzdgAAgKkRdgAAgKkRdgAAgKkRdgAAgKkRdgAAgKkRdgAAgKkRdgAAgKkRdgAAgKkRdgAAgKkRdgAAgKkRdgAAgKkRdgAAgKn9P4kW/zOkgH9fAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjsAAAHHCAYAAABZbpmkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAOulJREFUeJzt3Xl4FeX9///XScjClhyTkA0JmwoECSAIHDcQIhHRQkEsmGKwiC0FFFOtoshmFcEFFEGsrVD7NbjUrQVBIRqxEhAjm2GpUDSQkITFrJAAyfz+8Mf5eEpIwsnZMnk+rutcF2fmnpn3nVzIy5l77ttiGIYhAAAAk/LzdgEAAADuRNgBAACmRtgBAACmRtgBAACmRtgBAACmRtgBAACmRtgBAACmRtgBAACmRtgBAACmRtgB0ChkZGTIYrEoIyPD26UAaGQIOwDcbuXKlbJYLDV+HnnkEbdcs7q6Wq+//rr69++vsLAwtW7dWldccYXuuusubd68WZJ03333yWKxaP/+/Rc8z2OPPSaLxaKdO3dKkjp06CCLxaLExMQa27/66qv2vn399deu7xiAi9bM2wUAaDrmzZunjh07Omy78sor63XsDTfcoFOnTikwMLBe7e+77z4tXbpUI0aMUHJyspo1a6Z9+/Zp7dq16tSpkwYMGKDk5GQtWbJEaWlpmjVrVo3nWbVqlXr06KGEhAT7tuDgYH322WfKz89XdHS0Q/s33nhDwcHBqqioqFedANyPsAPAY4YNG6a+ffs6dayfn5+Cg4PrbHfy5EmVlpZq2bJlmjRpkv785z877F+8eLGOHj0qSerfv78uu+wyrVq1qsawk5mZqYMHD+rpp5922H7ttddq69ateuutt3T//ffbtx8+fFhffPGFfvnLX+rdd991ppsA3IDHWAC86ocfftDvf/97denSRc2bN1d4eLjGjBmj77//3qFdTWN2Bg0apCuvvFJZWVm64YYb1KJFCz366KM6ePCgDMPQtddee971LBaLIiMj7d+Tk5O1d+9effPNN+e1TUtLk8Vi0bhx4xy2BwcHa9SoUUpLS3PYvmrVKl1yySVKSkpy4icBwF0IOwA8pri4WMeOHXP4bN26VZs2bdLYsWP14osv6ne/+53S09M1aNAgnTx5ss5zHj9+XMOGDVOvXr20ePFi3XjjjWrfvr0k6Z133qnzHMnJyZJ0XnCpqqrS22+/reuvv15xcXHnHXfnnXfqq6++0oEDB+zb0tLSdPvttysgIKDOugF4Do+xAHhMTYN6T548qdtvv91h22233SabzaZ3331X48ePr/Wc+fn5Wr58uX772986bL/rrrv0+uuv69JLL9WgQYN07bXXavjw4eratatDu8svv1xXX3213nrrLS1cuFB+fj/9P+CGDRtUWFioJ554osbrDh48WNHR0Vq1apVmzpypPXv2aPv27XrhhRf03//+t86fBQDP4c4OAI9ZunSp1q9f7/Bp3ry5ff+ZM2d0/PhxXXbZZbJarTU+WvpfQUFBuvvuu8/bvmLFCr300kvq2LGj3n//fT344IPq1q2bhgwZotzcXIe2v/71r3X48GFt3LjRvi0tLU2BgYEaM2ZMjdf19/fXHXfcoVWrVkn6aWByu3btdP3119frZwHAcwg7ADymX79+SkxMdPicOnVKs2bNUrt27RQUFKSIiAi1adNGRUVFKi4urvOcbdu2rfENLT8/P02ZMkVZWVk6duyYPvzwQw0bNkyffvqpxo4d69B27Nix8vf3tz/Kqqio0Pvvv69hw4bpkksuueC177zzTu3evVs7duxQWlqaxo4dK4vFcpE/FQDuRtgB4FXTpk3Tk08+qTvuuENvv/22PvnkE61fv17h4eGqrq6u8/if3xm6kPDwcP3iF7/QRx99pIEDB+rf//63fvjhB/v+yMhI3XTTTXr33Xd15swZ/etf/1Jpaal9PM+F9O/fX507d9b06dN18OBB3XnnnXV3GIDHEXYAeNU//vEPpaSk6LnnntPtt9+um266Sdddd52Kiorccr1zr74fOXLEYXtycrJOnDihtWvXKi0tTSEhIbrtttvqPN+4ceOUkZGhbt26qVevXu4oGUADMUAZgFf5+/vLMAyHbUuWLFFVVZXT58zPz9eJEycUHx/vsP306dNKT0+Xn5+fLrvsMod9I0eOVIsWLbRs2TJlZGRo3Lhx9ZrX55577pG/v7/69+/vdL0A3IuwA8Crbr31Vv39739XaGio4uPjlZmZqQ0bNig8PNzpcx4+fFj9+vXT4MGDNWTIEEVHR6uwsFCrVq3Sjh07NH36dEVERDgc06pVK40cOdI+bqeuR1jntG/fXnPmzHG6VgDuR9gB4FUvvPCC/P399cYbb6iiokLXXnutNmzY0KCJ+bp06aLF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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import warnings\n", "\n", "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "import seaborn as sns\n", "\n", "warnings.filterwarnings(\"ignore\", \"is_categorical_dtype\")\n", "warnings.filterwarnings(\"ignore\", \"use_inf_as_na\")\n", "\n", "df = pd.DataFrame({\"score\": score, \"fscore\": fscore, \"y\": y})\n", "\n", "sns.histplot(df, x=\"score\", hue=\"y\").set_title(\"SVM\")\n", "plt.show()\n", "sns.histplot(df, x=\"fscore\", hue=\"y\").set_title(\"FairSVM\")\n", "plt.show()" ] } ], "metadata": { "colab": { "provenance": [] }, "kernelspec": { "display_name": "Python 3", "name": "python3" }, "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 0 }