Skip to content
Snippets Groups Projects
Bachelors_thesis_analyses.ipynb 497 KiB
Newer Older
  • Learn to ignore specific revisions
  •        "    <tr>\n",
           "      <th>Male</th>\n",
           "      <td>2626</td>\n",
           "      <td>29</td>\n",
           "      <td>1621</td>\n",
           "      <td>427</td>\n",
           "      <td>9</td>\n",
           "      <td>285</td>\n",
           "    </tr>\n",
           "  </tbody>\n",
           "</table>\n",
           "</div>"
          ],
          "text/plain": [
           "race    African-American  Asian  Caucasian  Hispanic  Native American  Other\n",
           "sex                                                                         \n",
           "Female               549      2        482        82                2     58\n",
           "Male                2626     29       1621       427                9    285"
          ]
         },
    
         "execution_count": 13,
    
         "metadata": {},
         "output_type": "execute_result"
        }
       ],
       "source": [
        "tab = compas.groupby(['sex', 'race']).size()\n",
        "tab.unstack()"
       ]
      },
      {
       "cell_type": "code",
    
       "execution_count": 14,
    
       "metadata": {
        "scrolled": false
       },
       "outputs": [
        {
         "data": {
          "image/png": "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\n",
          "text/plain": [
           "<Figure size 432x288 with 1 Axes>"
          ]
         },
         "metadata": {
          "needs_background": "light"
         },
         "output_type": "display_data"
        },
        {
         "data": {
          "image/png": "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\n",
          "text/plain": [
           "<Figure size 1008x504 with 2 Axes>"
          ]
         },
         "metadata": {
          "needs_background": "light"
         },
         "output_type": "display_data"
        }
       ],
       "source": [
        "plt.bar(range(1, 11), compas.decile_score.value_counts(), ec='black')\n",
        "plt.title(\"Decile scores of all defendants\")\n",
        "plt.ylabel(\"Frequency\")\n",
        "plt.xlabel(\"Decile score\")\n",
        "plt.xticks(range(1, 11))\n",
        "plt.show()\n",
        "\n",
        "fig, ax = compas.query(\"race in ['Caucasian', 'African-American']\").hist(\n",
        "    \"decile_score\",\n",
        "    by=\"race\",\n",
        "    figsize=(14, 7),\n",
        "    sharey=True,\n",
        "    xrot='horizontal',\n",
        "    ec='black',\n",
        "    bins=np.arange(0.5, 11.5, 1.0),\n",
        "    rwidth=0.8)\n",
        "\n",
        "fig.text(-1.5, 350, \"Frequency\", rotation='vertical')\n",
        "fig.text(11.5, -60, \"Decile score\", horizontalalignment='center')\n",
        "plt.tight_layout(w_pad=-2)\n",
        "plt.show()"
       ]
      },
      {
       "cell_type": "code",
    
       "execution_count": 15,
    
       "metadata": {
        "scrolled": false
       },
       "outputs": [
        {
         "name": "stderr",
         "output_type": "stream",
         "text": [
          "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\scipy\\stats\\stats.py:1713: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.\n",
          "  return np.add.reduce(sorted[indexer] * weights, axis=axis) / sumval\n"
         ]
        },
        {
         "data": {
          "image/png": "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\n",
          "text/plain": [
           "<Figure size 432x288 with 1 Axes>"
          ]
         },
         "metadata": {
          "needs_background": "light"
         },
         "output_type": "display_data"
        }
       ],
       "source": [
        "sns.distplot(compas.age)\n",
        "plt.title(\"Histogram of defendants' ages\")\n",
        "plt.xlabel(\"Age of defendant\")\n",
        "plt.show()"
       ]
      },
      {
       "cell_type": "code",
    
       "execution_count": 16,
    
       "metadata": {
        "scrolled": false
       },
    
       "outputs": [
        {
         "data": {
          "text/html": [
           "<div>\n",
           "<style scoped>\n",
           "    .dataframe tbody tr th:only-of-type {\n",
           "        vertical-align: middle;\n",
           "    }\n",
           "\n",
           "    .dataframe tbody tr th {\n",
           "        vertical-align: top;\n",
           "    }\n",
           "\n",
           "    .dataframe thead th {\n",
           "        text-align: right;\n",
           "    }\n",
           "</style>\n",
           "<table border=\"1\" class=\"dataframe\">\n",
           "  <thead>\n",
           "    <tr style=\"text-align: right;\">\n",
           "      <th>is_recid</th>\n",
           "      <th>0</th>\n",
           "      <th>1</th>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>age_cat</th>\n",
           "      <th></th>\n",
           "      <th></th>\n",
           "    </tr>\n",
           "  </thead>\n",
           "  <tbody>\n",
           "    <tr>\n",
           "      <th>25 - 45</th>\n",
           "      <td>1784</td>\n",
           "      <td>1748</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>Greater than 45</th>\n",
           "      <td>847</td>\n",
           "      <td>446</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>Less than 25</th>\n",
           "      <td>551</td>\n",
           "      <td>796</td>\n",
           "    </tr>\n",
           "  </tbody>\n",
           "</table>\n",
           "</div>"
          ],
          "text/plain": [
           "is_recid            0     1\n",
           "age_cat                    \n",
           "25 - 45          1784  1748\n",
           "Greater than 45   847   446\n",
           "Less than 25      551   796"
          ]
         },
         "metadata": {},
         "output_type": "display_data"
        },
        {
         "data": {
          "text/html": [
           "<div>\n",
           "<style scoped>\n",
           "    .dataframe tbody tr th:only-of-type {\n",
           "        vertical-align: middle;\n",
           "    }\n",
           "\n",
           "    .dataframe tbody tr th {\n",
           "        vertical-align: top;\n",
           "    }\n",
           "\n",
           "    .dataframe thead th {\n",
           "        text-align: right;\n",
           "    }\n",
           "</style>\n",
           "<table border=\"1\" class=\"dataframe\">\n",
           "  <thead>\n",
           "    <tr style=\"text-align: right;\">\n",
           "      <th>is_recid</th>\n",
           "      <th>0</th>\n",
           "      <th>1</th>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>sex</th>\n",
           "      <th></th>\n",
           "      <th></th>\n",
           "    </tr>\n",
           "  </thead>\n",
           "  <tbody>\n",
           "    <tr>\n",
           "      <th>Female</th>\n",
           "      <td>740</td>\n",
           "      <td>435</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>Male</th>\n",
           "      <td>2442</td>\n",
           "      <td>2555</td>\n",
           "    </tr>\n",
           "  </tbody>\n",
           "</table>\n",
           "</div>"
          ],
          "text/plain": [
           "is_recid     0     1\n",
           "sex                 \n",
           "Female     740   435\n",
           "Male      2442  2555"
          ]
         },
         "metadata": {},
         "output_type": "display_data"
        },
        {
         "data": {
          "text/html": [
           "<div>\n",
           "<style scoped>\n",
           "    .dataframe tbody tr th:only-of-type {\n",
           "        vertical-align: middle;\n",
           "    }\n",
           "\n",
           "    .dataframe tbody tr th {\n",
           "        vertical-align: top;\n",
           "    }\n",
           "\n",
           "    .dataframe thead th {\n",
           "        text-align: right;\n",
           "    }\n",
           "</style>\n",
           "<table border=\"1\" class=\"dataframe\">\n",
           "  <thead>\n",
           "    <tr style=\"text-align: right;\">\n",
    
           "      <th>is_recid</th>\n",
           "      <th>0</th>\n",
           "      <th>1</th>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>race</th>\n",
    
           "      <th>age_cat</th>\n",
    
           "      <th></th>\n",
           "      <th></th>\n",
           "    </tr>\n",
           "  </thead>\n",
           "  <tbody>\n",
           "    <tr>\n",
    
           "      <th rowspan=\"3\" valign=\"top\">African-American</th>\n",
           "      <th>25 - 45</th>\n",
           "      <td>847.0</td>\n",
           "      <td>1051.0</td>\n",
    
           "    </tr>\n",
           "    <tr>\n",
    
           "      <th>Greater than 45</th>\n",
           "      <td>261.0</td>\n",
           "      <td>207.0</td>\n",
    
           "    </tr>\n",
           "    <tr>\n",
    
           "      <th>Less than 25</th>\n",
           "      <td>294.0</td>\n",
           "      <td>515.0</td>\n",
    
           "    </tr>\n",
           "    <tr>\n",
    
           "      <th rowspan=\"3\" valign=\"top\">Asian</th>\n",
           "      <th>25 - 45</th>\n",
           "      <td>10.0</td>\n",
           "      <td>4.0</td>\n",
    
           "    </tr>\n",
           "    <tr>\n",
    
           "      <th>Greater than 45</th>\n",
           "      <td>7.0</td>\n",
           "      <td>4.0</td>\n",
    
           "    </tr>\n",
           "    <tr>\n",
    
           "      <th>Less than 25</th>\n",
           "      <td>4.0</td>\n",
           "      <td>2.0</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th rowspan=\"3\" valign=\"top\">Caucasian</th>\n",
           "      <th>25 - 45</th>\n",
           "      <td>620.0</td>\n",
           "      <td>508.0</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>Greater than 45</th>\n",
           "      <td>442.0</td>\n",
           "      <td>186.0</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>Less than 25</th>\n",
           "      <td>167.0</td>\n",
           "      <td>180.0</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th rowspan=\"3\" valign=\"top\">Hispanic</th>\n",
           "      <th>25 - 45</th>\n",
           "      <td>180.0</td>\n",
           "      <td>111.0</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>Greater than 45</th>\n",
           "      <td>81.0</td>\n",
           "      <td>28.0</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>Less than 25</th>\n",
           "      <td>51.0</td>\n",
           "      <td>58.0</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th rowspan=\"3\" valign=\"top\">Native American</th>\n",
           "      <th>25 - 45</th>\n",
           "      <td>5.0</td>\n",
           "      <td>2.0</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>Greater than 45</th>\n",
           "      <td>NaN</td>\n",
           "      <td>2.0</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>Less than 25</th>\n",
           "      <td>NaN</td>\n",
           "      <td>2.0</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th rowspan=\"3\" valign=\"top\">Other</th>\n",
           "      <th>25 - 45</th>\n",
           "      <td>122.0</td>\n",
           "      <td>72.0</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>Greater than 45</th>\n",
           "      <td>56.0</td>\n",
           "      <td>19.0</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>Less than 25</th>\n",
           "      <td>35.0</td>\n",
           "      <td>39.0</td>\n",
    
           "    </tr>\n",
           "  </tbody>\n",
           "</table>\n",
           "</div>"
          ],
          "text/plain": [
    
           "is_recid                              0       1\n",
           "race             age_cat                       \n",
           "African-American 25 - 45          847.0  1051.0\n",
           "                 Greater than 45  261.0   207.0\n",
           "                 Less than 25     294.0   515.0\n",
           "Asian            25 - 45           10.0     4.0\n",
           "                 Greater than 45    7.0     4.0\n",
           "                 Less than 25       4.0     2.0\n",
           "Caucasian        25 - 45          620.0   508.0\n",
           "                 Greater than 45  442.0   186.0\n",
           "                 Less than 25     167.0   180.0\n",
           "Hispanic         25 - 45          180.0   111.0\n",
           "                 Greater than 45   81.0    28.0\n",
           "                 Less than 25      51.0    58.0\n",
           "Native American  25 - 45            5.0     2.0\n",
           "                 Greater than 45    NaN     2.0\n",
           "                 Less than 25       NaN     2.0\n",
           "Other            25 - 45          122.0    72.0\n",
           "                 Greater than 45   56.0    19.0\n",
           "                 Less than 25      35.0    39.0"
    
          ]
         },
         "metadata": {},
         "output_type": "display_data"
        }
       ],
       "source": [
        "tab = compas.groupby(['age_cat', 'is_recid']).size()\n",
        "display(tab.unstack())\n",
        "\n",
        "tab = compas.groupby(['sex', 'is_recid']).size()\n",
        "display(tab.unstack())\n",
        "\n",
    
        "tab = compas.groupby(['race', 'age_cat', 'is_recid']).size()\n",
    
        "display(tab.unstack())"
       ]
      },
    
      {
       "cell_type": "markdown",
       "metadata": {},
       "source": [
    
        "From above it is clear that there are no Native American recidivists of age over 45 or under 25. There are some other value combinations that might be problematic. Therefore the procedure of estimating $P(X=x)$ has to be considered carefully."
    
       ]
      },
      {
       "cell_type": "markdown",
       "metadata": {},
       "source": [
        "### Synthetic data\n",
    
        "In the chunk below, we generate the synthetic data as described by Lakkaraju et al. The default values and definitions of $Y$ and $T$ values follow their description.\n",
    
        "**Parameters**\n",
    
        "* M = `nJudges_M`, number of judges\n",
        "* N = `nSubjects_N`, number of subjects assigned to each judge\n",
    
        "* betas $\\beta_i$ = `beta_i`, where $i \\in \\{X, Z, W\\}$ are coefficients for the respected variables\n",
    
        "* R = `acceptanceRate_R`, acceptance rates\n",
        "* X = `X`, invidual's features observable to all (models and judges)\n",
        "* Z = `Z`, information observable for judges only\n",
        "* W = `W`, unobservable / inaccessible information\n",
    
        "* T = `decision_T`, bail-or-jail decisions where $T=0$ represents jail decision and $T=1$ bail decision.\n",
    
        "* Y = `result_Y`, result variable, if $Y=0$ person will or would recidivate and if $Y=1$ person will or would not commit a crime."
    
       "execution_count": 17,
    
       "metadata": {
        "scrolled": false
       },
    
        {
         "data": {
          "text/html": [
           "<div>\n",
           "<style scoped>\n",
           "    .dataframe tbody tr th:only-of-type {\n",
           "        vertical-align: middle;\n",
           "    }\n",
           "\n",
           "    .dataframe tbody tr th {\n",
           "        vertical-align: top;\n",
           "    }\n",
           "\n",
           "    .dataframe thead th {\n",
           "        text-align: right;\n",
           "    }\n",
           "</style>\n",
           "<table border=\"1\" class=\"dataframe\">\n",
           "  <thead>\n",
           "    <tr style=\"text-align: right;\">\n",
           "      <th></th>\n",
           "      <th>count</th>\n",
           "      <th>mean</th>\n",
           "      <th>std</th>\n",
           "      <th>min</th>\n",
           "      <th>25%</th>\n",
           "      <th>50%</th>\n",
           "      <th>75%</th>\n",
           "      <th>max</th>\n",
           "    </tr>\n",
           "  </thead>\n",
           "  <tbody>\n",
           "    <tr>\n",
           "      <th>judgeID_J</th>\n",
           "      <td>50000.0</td>\n",
           "      <td>49.500000</td>\n",
           "      <td>28.866359</td>\n",
           "      <td>0.000000</td>\n",
           "      <td>24.750000</td>\n",
           "      <td>49.500000</td>\n",
           "      <td>74.250000</td>\n",
           "      <td>99.000000</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>acceptanceRate_R</th>\n",
           "      <td>50000.0</td>\n",
           "      <td>0.478235</td>\n",
           "      <td>0.230644</td>\n",
           "      <td>0.103756</td>\n",
           "      <td>0.264643</td>\n",
           "      <td>0.473985</td>\n",
           "      <td>0.647587</td>\n",
           "      <td>0.890699</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>X</th>\n",
           "      <td>50000.0</td>\n",
           "      <td>-0.003875</td>\n",
           "      <td>0.996715</td>\n",
           "      <td>-4.659953</td>\n",
           "      <td>-0.671782</td>\n",
           "      <td>-0.001726</td>\n",
           "      <td>0.668077</td>\n",
           "      <td>3.831790</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>Z</th>\n",
           "      <td>50000.0</td>\n",
           "      <td>0.006964</td>\n",
           "      <td>0.998001</td>\n",
           "      <td>-4.852118</td>\n",
           "      <td>-0.666258</td>\n",
           "      <td>0.004730</td>\n",
           "      <td>0.679477</td>\n",
           "      <td>4.241772</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>W</th>\n",
           "      <td>50000.0</td>\n",
           "      <td>0.010863</td>\n",
           "      <td>0.996944</td>\n",
           "      <td>-4.029138</td>\n",
           "      <td>-0.666574</td>\n",
           "      <td>0.012306</td>\n",
           "      <td>0.679578</td>\n",
           "      <td>4.285856</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>result_Y</th>\n",
           "      <td>50000.0</td>\n",
           "      <td>0.496500</td>\n",
           "      <td>0.499993</td>\n",
           "      <td>0.000000</td>\n",
           "      <td>0.000000</td>\n",
           "      <td>0.000000</td>\n",
           "      <td>1.000000</td>\n",
           "      <td>1.000000</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>probabilities_T</th>\n",
           "      <td>50000.0</td>\n",
           "      <td>0.500794</td>\n",
           "      <td>0.279762</td>\n",
           "      <td>-0.335627</td>\n",
           "      <td>0.276723</td>\n",
           "      <td>0.501317</td>\n",
           "      <td>0.723352</td>\n",
           "      <td>1.295719</td>\n",
           "    </tr>\n",
           "    <tr>\n",
           "      <th>decision_T</th>\n",
           "      <td>50000.0</td>\n",
           "      <td>0.477260</td>\n",
           "      <td>0.499488</td>\n",
           "      <td>0.000000</td>\n",
           "      <td>0.000000</td>\n",
           "      <td>0.000000</td>\n",
           "      <td>1.000000</td>\n",
           "      <td>1.000000</td>\n",
           "    </tr>\n",
           "  </tbody>\n",
           "</table>\n",
           "</div>"
          ],
          "text/plain": [
           "                    count       mean        std       min        25%  \\\n",
           "judgeID_J         50000.0  49.500000  28.866359  0.000000  24.750000   \n",
           "acceptanceRate_R  50000.0   0.478235   0.230644  0.103756   0.264643   \n",
           "X                 50000.0  -0.003875   0.996715 -4.659953  -0.671782   \n",
           "Z                 50000.0   0.006964   0.998001 -4.852118  -0.666258   \n",
           "W                 50000.0   0.010863   0.996944 -4.029138  -0.666574   \n",
           "result_Y          50000.0   0.496500   0.499993  0.000000   0.000000   \n",
           "probabilities_T   50000.0   0.500794   0.279762 -0.335627   0.276723   \n",
           "decision_T        50000.0   0.477260   0.499488  0.000000   0.000000   \n",
           "\n",
           "                        50%        75%        max  \n",
           "judgeID_J         49.500000  74.250000  99.000000  \n",
           "acceptanceRate_R   0.473985   0.647587   0.890699  \n",
           "X                 -0.001726   0.668077   3.831790  \n",
           "Z                  0.004730   0.679477   4.241772  \n",
           "W                  0.012306   0.679578   4.285856  \n",
           "result_Y           0.000000   1.000000   1.000000  \n",
           "probabilities_T    0.501317   0.723352   1.295719  \n",
           "decision_T         0.000000   1.000000   1.000000  "
          ]
         },
         "metadata": {},
         "output_type": "display_data"
        },
    
        {
         "name": "stdout",
         "output_type": "stream",
         "text": [
    
          "Name: decision_T, dtype: int64\n"
         ]
        },
        {
         "data": {
          "text/html": [
           "<div>\n",
           "<style scoped>\n",
           "    .dataframe tbody tr th:only-of-type {\n",
           "        vertical-align: middle;\n",
           "    }\n",
           "\n",
           "    .dataframe tbody tr th {\n",
           "        vertical-align: top;\n",
           "    }\n",
           "\n",
           "    .dataframe thead th {\n",
           "        text-align: right;\n",
           "    }\n",
           "</style>\n",
           "<table border=\"1\" class=\"dataframe\">\n",
           "  <thead>\n",
           "    <tr style=\"text-align: right;\">\n",
           "      <th>decision_T</th>\n",
    
           "      <th>0</th>\n",
           "      <th>1</th>\n",
    
           "    </tr>\n",
           "    <tr>\n",
           "      <th>result_Y</th>\n",
           "      <th></th>\n",
           "      <th></th>\n",
           "    </tr>\n",
           "  </thead>\n",
           "  <tbody>\n",
           "    <tr>\n",
           "      <th>0.0</th>\n",
    
           "      <td>20083</td>\n",
           "      <td>5092</td>\n",
    
           "    </tr>\n",
           "    <tr>\n",
           "      <th>1.0</th>\n",
    
           "      <td>6054</td>\n",
           "      <td>18771</td>\n",
    
           "    </tr>\n",
           "  </tbody>\n",
           "</table>\n",
           "</div>"
          ],
          "text/plain": [
    
           "result_Y                \n",
    
           "0.0         20083   5092\n",
           "1.0          6054  18771"
    
         "output_type": "display_data"
    
        "# Set seed for reproducibility\n",
        "npr.seed(0)\n",
        "\n",
        "def generateData(nJudges_M=100,\n",
        "                 nSubjects_N=500,\n",
        "                 beta_X=1.0,\n",
        "                 beta_Z=1.0,\n",
        "                 beta_W=0.2):\n",
        "\n",
        "    # Assign judge IDs as running numbering from 0 to nJudges_M - 1\n",
        "    judgeID_J = np.repeat(np.arange(0, nJudges_M, dtype=np.int32), nSubjects_N)\n",
        "\n",
        "    # Sample acceptance rates uniformly from a closed interval\n",
        "    # from 0.1 to 0.9 and round to tenth decimal place.\n",
        "    acceptance_rates = np.round(npr.uniform(.1, .9, nJudges_M), 10)\n",
        "\n",
    
        "    # Replicate the rates so they can be attached to the corresponding judge ID.\n",
    
        "    acceptanceRate_R = np.repeat(acceptance_rates, nSubjects_N)\n",
        "\n",
        "    # Sample the variables from standard Gaussian distributions.\n",
        "    X = npr.normal(size=nJudges_M * nSubjects_N)\n",
        "    Z = npr.normal(size=nJudges_M * nSubjects_N)\n",
        "    W = npr.normal(size=nJudges_M * nSubjects_N)\n",
        "\n",
        "    probabilities_Y = 1 / (1 + np.exp(-(beta_X * X + beta_Z * Z + beta_W * W)))\n",
        "\n",
        "    # 0 if P(Y = 0| X = x; Z = z; W = w) >= 0.5 , 1 otherwise\n",
        "    result_Y = 1 - probabilities_Y.round()\n",
        "\n",
        "    probabilities_T = 1 / (1 + np.exp(-(beta_X * X + beta_Z * Z)))\n",
        "    probabilities_T += npr.normal(0, .1, nJudges_M * nSubjects_N)\n",
        "\n",
    
        "    # Initialize decision values as 1\n",
        "    decision_T = np.ones(nJudges_M * nSubjects_N)\n",
    
        "\n",
        "    # Initialize the dataframe\n",
        "    df_init = pd.DataFrame(\n",
        "        np.column_stack((judgeID_J, acceptanceRate_R, X, Z, W, result_Y,\n",
        "                         probabilities_T, decision_T)),\n",
        "        columns=[\n",
        "            \"judgeID_J\", \"acceptanceRate_R\", \"X\", \"Z\", \"W\", \"result_Y\",\n",
        "            \"probabilities_T\", \"decision_T\"\n",
        "        ])\n",
        "\n",
        "    # Sort by judges then probabilities\n",
        "    data = df_init.sort_values(\n",
        "        by=[\"judgeID_J\", \"probabilities_T\"], ascending=False)\n",
        "\n",
        "    # Iterate over the data. Subject is in the top (1-r)*100% if\n",
        "    # his within-judge-index is over acceptance threshold times\n",
        "    # the number of subjects assigned to each judge. If subject\n",
        "    # is over the limit they are assigned a zero, else one.\n",
    
        "    data.reset_index(drop=True, inplace=True)\n",
        "\n",
        "    data['decision_T'] = np.where(\n",
        "        (data.index.values % nSubjects_N) <\n",
        "        ((1 - data['acceptanceRate_R']) * nSubjects_N), 0, 1)\n",
    
        "\n",
        "    return data\n",
        "\n",
        "\n",
    
        "df = generateData()\n",
        "\n",
        "# Basic stats of the created data set.\n",
    
        "display(df.describe().T)\n",
    
        "print(df.decision_T.value_counts())\n",
        "\n",
        "tab = df.groupby(['result_Y', 'decision_T']).size()\n",
    
        "display(tab.unstack())"
    
       "execution_count": 18,
    
       "metadata": {},
       "outputs": [
        {
         "name": "stdout",
         "output_type": "stream",
         "text": [
          "(25000, 8)\n",
          "(25000, 8)\n",
    
          "(11866, 8)\n",
          "(11997, 8)\n"
    
         ]
        },
        {
         "data": {
          "text/html": [
           "<div>\n",
           "<style scoped>\n",
           "    .dataframe tbody tr th:only-of-type {\n",
           "        vertical-align: middle;\n",
           "    }\n",
           "\n",
           "    .dataframe tbody tr th {\n",
           "        vertical-align: top;\n",
           "    }\n",
           "\n",
           "    .dataframe thead th {\n",
           "        text-align: right;\n",
           "    }\n",
           "</style>\n",
           "<table border=\"1\" class=\"dataframe\">\n",
           "  <thead>\n",
           "    <tr style=\"text-align: right;\">\n",
           "      <th>decision_T</th>\n",
    
           "    </tr>\n",
           "    <tr>\n",
           "      <th>result_Y</th>\n",
           "      <th></th>\n",
           "    </tr>\n",
           "  </thead>\n",
           "  <tbody>\n",
           "    <tr>\n",
           "      <th>0.0</th>\n",
    
           "    </tr>\n",
           "    <tr>\n",
           "      <th>1.0</th>\n",
    
           "    </tr>\n",
           "  </tbody>\n",
           "</table>\n",
           "</div>"
          ],
          "text/plain": [
    
           "result_Y        \n",
    
         "execution_count": 18,
    
         "metadata": {},
         "output_type": "execute_result"
        }
       ],
       "source": [
    
        "# Split the data set to test and train\n",
    
        "from sklearn.model_selection import train_test_split\n",
    
        "train, test = train_test_split(df, test_size=0.5, random_state=0)\n",
    
        "\n",
        "print(train.shape)\n",
        "print(test.shape)\n",
        "\n",
        "train_labeled = train[train.decision_T == 1]\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "test_labeled = test[test.decision_T == 1]\n",
    
        "\n",
        "print(train_labeled.shape)\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "print(test_labeled.shape)\n",
    
        "\n",
        "tab = train_labeled.groupby(['result_Y', 'decision_T']).size()\n",
        "tab.unstack()"
       ]
      },
      {
       "cell_type": "markdown",
       "metadata": {},
       "source": [
    
        "## Algorithms\n",
    
        "### Contraction algorithm\n",
    
        "Below is an implementation of Lakkaraju's team's algorithm presented in [their paper](https://helka.finna.fi/PrimoRecord/pci.acm3098066). Relevant parameters to be passed to the function are presented in the description."
    
       "execution_count": 19,
    
    Riku-Laine's avatar
    Riku-Laine committed
       "metadata": {},
       "outputs": [],
    
    Riku-Laine's avatar
    Riku-Laine committed
        "def contraction(df,\n",
        "                judgeIDJ_col,\n",
        "                decisionT_col,\n",
        "                resultY_col,\n",
        "                modelProbS_col,\n",
        "                accRateR_col,\n",
        "                r,\n",
        "                binning=False):\n",
    
        "    '''\n",
        "    This is an implementation of the algorithm presented by Lakkaraju\n",
        "    et al. in their paper \"The Selective Labels Problem: Evaluating \n",
        "    Algorithmic Predictions in the Presence of Unobservables\" (2017).\n",
        "    \n",
        "    Parameters:\n",
        "    df = The (Pandas) data frame containing the data, judge decisions,\n",
        "    judge IDs, results and probability scores.\n",
        "    judgeIDJ_col = String, the name of the column containing the judges' IDs\n",
        "    in df.\n",
        "    decisionT_col = String, the name of the column containing the judges' decisions\n",
        "    resultY_col = String, the name of the column containing the realization\n",
        "    modelProbS_col = String, the name of the column containing the probability\n",
        "    scores from the black-box model B.\n",
        "    accRateR_col = String, the name of the column containing the judges' \n",
        "    acceptance rates\n",
        "    r = Float between 0 and 1, the given acceptance rate.\n",
        "    binning = Boolean, should judges with same acceptance rate be binned\n",
        "    \n",
        "    Returns:\n",
        "    u = The estimated failure rate at acceptance rate r.\n",
        "    '''\n",
        "    # Sort first by acceptance rate and judge ID.\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "    sorted_df = df.sort_values(\n",
        "        by=[accRateR_col, judgeIDJ_col], ascending=False)\n",
    
        "\n",
        "    if binning:\n",
        "        # Get maximum leniency\n",
        "        max_leniency = sorted_df[accRateR_col].values[0].round(1)\n",
        "\n",
        "        # Get list of judges that are the most lenient\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "        most_lenient_list = sorted_df.loc[sorted_df[accRateR_col].round(1) ==\n",
        "                                          max_leniency, judgeIDJ_col]\n",
    
        "\n",
        "        # Subset to obtain D_q\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "        D_q = sorted_df[sorted_df[judgeIDJ_col].isin(\n",
        "            most_lenient_list.unique())]\n",
    
        "    else:\n",
        "        # Get most lenient judge\n",
        "        most_lenient_ID = sorted_df[judgeIDJ_col].values[0]\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "\n",
    
        "        # Subset\n",
        "        D_q = sorted_df[sorted_df[judgeIDJ_col] == most_lenient_ID]\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "\n",
    
        "    R_q = D_q[D_q[decisionT_col] == 1]\n",
        "\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "    R_sort_q = R_q.sort_values(by=modelProbS_col, ascending=False)\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "    number_to_remove = int(\n",
        "        np.round((1 - r) * D_q.shape[0] - (D_q.shape[0] - R_q.shape[0])))\n",
    
        "\n",
        "    R_B = R_sort_q[number_to_remove:R_sort_q.shape[0]]\n",
        "\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "    return np.sum(R_B[resultY_col] == 0) / D_q.shape[0]"
       ]
      },
      {
       "cell_type": "markdown",
       "metadata": {},
       "source": [
    
        "### Causal model\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "\n",
    
        "Our model is defined by the probabilistic expression \n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "\n",
    
        "\\begin{equation}\\label{model}\n",
    
        "P(Y=0 | \\text{do}(R=r)) = \\sum_x \\underbrace{P(Y=0|X=x, T=1)}_\\text{1} \n",
        "\\overbrace{P(T=1|R=r, X=x)}^\\text{2} \n",
        "\\underbrace{P(X=x)}_\\text{3}\n",
    
        "\\end{equation}\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "\n",
    
        "As a picture (Z not in model):\n",
        "\n",
        "![Model as picture](../figures/intervention_model.png \"Intervention model\")\n",
        "\n",
    
        "**Algorithm -- UPDATE!!**\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "\n",
    
        "Our model will be constructed sequentially.\n",
    
        "Input: Training and test data sets $(\\mathbf{x}, t, y) \\in \\mathcal{D}$ and acceptance rate $r$.  \n",
    
        "Returns: $P(Y=0 | \\text{do}(R=r))$\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "\n",
    
        "Procedure:\n",
    
        "1. Model $P(X=x)$ in a suitable way and assign to $\\mathcal{M}_0$\n",
        "*  Build model $\\mathcal{M}_1$ predicting response $Y$ with predictors $X$ from the labeled observations (where $T=1$) in training data.\n",
        "*  Predict $P(Y=0|X=x)$ for every observation in the test data using model $\\mathcal{M}_1$.\n",
    
        "*  Initialize `sum = 0`\n",
        "*  For every point in the parameter space (for every $x$ in $X$)\n",
    
        "    1. $p_x \\leftarrow P(X=x)$ from $\\mathcal{M}_0$\n",
    
        "    *  $\\mathcal{D_x} \\leftarrow \\{\\mathcal{D} | X = x\\}$\n",
        "    *  Assign first $r\\cdot 100\\%$ observations from $\\mathcal{D_x}$ to $\\mathcal{D}_{rx}$\n",
    
        "    *  $p_t \\leftarrow \\dfrac{|\\{\\mathcal{D}_{rx}|T=1\\}|}{|\\mathcal{D}_{rx}|}$ (part 2 of eq. $\\ref{model}$) Pitääkö tähänkin treenaa joku oma luokittelija?\n",
    
        "    *  $p_y$ will be predicted from the model $\\mathcal{M}_1$\n",
    
        "    *  `sum +=` $p_y \\cdot p_t \\cdot p_x$\n",
        "* Return `sum`\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "\n",
    
        "**Constructing $\\mathcal{M}_0$, preliminary ideas:**\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "\n",
    
        "* Approximate $P(X=x)$ with frequencies (makes independence assumption, make variables factors first)\n",
        "* Construct Bayesian network.\n",
        "\n",
        "Functions:\n",
        "\n",
        "* $f(x)$ gives probability of recidivism given personal properties and predictive model.\n",
        "* `ep` counts performance of the predictive model given a data, model and leniency rate like Michael's pdf."
    
       "execution_count": 33,
    
    Riku-Laine's avatar
    Riku-Laine committed
       "metadata": {
        "scrolled": false
       },
    
       "outputs": [],
    
        "def causal(x_list, df_test, df_train, result_col, feature_cols, x_model, y_model,\n",
    
        "           leniency_r):\n",
    
        "    ''' OUT??\n",
    
        "    Gives probability of negative event given a leniency r.\n",
        "    \n",
        "    Parameters:\n",
    
        "    x_list = list of all possible x values\n",
        "    df_test = pandas dataframe, test data\n",
        "    df_train = pandas dataframe, training data\n",
        "    feature_cols = String (list), name of columns containing individual features.\n",
        "    y_cols = String, name of column containgn the result variable\n",
        "    x_model = model predicting probability of given combination of private features\n",
        "    y_model = model predicting probability of recidivism given private features\n",
        "    leniency_r = float, leniency level between .0.0 and 1.0\n",
    
        "    '''\n",
        "    probability = 0\n",
    
    Riku-Laine's avatar
    Riku-Laine committed
        "\n",
    
        "    for x in x_list:\n",
        "\n",
    
        "        p_x = x_model(x)\n",
    
        "        D_tx = df_test[(y_model(df_test[feature_cols]) < leniency_r)\n",
        "                       & (df_test[feature_cols] == x)]\n",
    
        "        if D_tx.shape[0] == 0:\n",
        "            continue\n",
    
        "        p_t = np.sum(D_tx.decision_T == 1) / D_tx.shape[0]\n",
    
        "        p_y = y_model(x)\n",
    
        "        probability += p_y[0, 0] * p_t * p_x\n",
    
        "    return probability\n",
        "\n",
        "\n",
        "def f(x, model):\n",