├── Demo_mirror_generator.ipynb ├── Demo_mirror_generator_pareto.ipynb ├── README.md ├── dag_hiring.png ├── dag_pareto.png ├── mirror ├── edges.py ├── erasers.py ├── generator.py └── nodes.py ├── out ├── hiring │ ├── R1.csv │ ├── R1_mar.csv │ ├── R1_mcar.csv │ └── R1_nmar.csv └── pareto │ └── R1.csv └── requirements.txt /Demo_mirror_generator.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Mirror Data Generator\n", 8 | "- mirrorGen is an open source tool to generate synthetic data based on a correlation DAG, which describes the relation among the columns in the data. It can be used to produce \"dirty\" data, mirroring various bias in real life, which can be used in applications, such as classification and ranking tasks [[1]](https://arxiv.org/abs/2006.08688).\n", 9 | "\n", 10 | "## Demo the usage of mirrorGen to generate data that is described by the DAG below.\n", 11 | "- It simulate a dataset with 6 columns: \n", 12 | " - G with values of 'M' and 'F'.\n", 13 | " - age with values in [20, 70].\n", 14 | " - job with values of 'E' and 'F'.\n", 15 | " - X1 with values in [-2, 2].\n", 16 | " - X2 with values from a Gaussian distribution G(0,1).\n", 17 | " - D with values of 'Y' and 'N'.\n", 18 | "- The correlation among above columns are:\n", 19 | " - G affects age, job, and X1.\n", 20 | " - D is equally determined by age, job, X1, and X2 through the same weights for all the edges." 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "![DAG](dag_hiring.png \"DAG\") " 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 5, 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "from mirror.nodes import *\n", 37 | "from mirror.edges import *\n", 38 | "from mirror.generator import Mirror\n", 39 | "from mirror import erasers\n", 40 | "import pandas as pd" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "### 1. Define the DAG and generate data" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 2, 53 | "metadata": {}, 54 | "outputs": [ 55 | { 56 | "name": "stdout", 57 | "output_type": "stream", 58 | "text": [ 59 | "G independet ['G']\n", 60 | "----------------------------------------\n", 61 | "\n", 62 | "age with parents\n", 63 | "One parent ['G', 'age']\n", 64 | "----------------------------------------\n", 65 | "\n", 66 | "job with parents\n", 67 | "One parent ['G', 'age', 'job']\n", 68 | "----------------------------------------\n", 69 | "\n", 70 | "X1 with parents\n", 71 | "One parent ['G', 'age', 'job', 'X1']\n", 72 | "----------------------------------------\n", 73 | "\n", 74 | "X2 independet ['G', 'age', 'job', 'X1', 'X2']\n", 75 | "----------------------------------------\n", 76 | "\n", 77 | "D with parents\n", 78 | "New CPT {'1E00': {'N': 0.3, 'Y': 0.7}, '1F00': {'N': 0.35, 'Y': 0.65}, '1E01': {'N': 0.45, 'Y': 0.55}, '0F01': {'N': 0.55, 'Y': 0.45}, '1F01': {'N': 0.5, 'Y': 0.5}, '0F00': {'N': 0.39999999999999997, 'Y': 0.6000000000000001}, '0E00': {'N': 0.35, 'Y': 0.65}, '0E01': {'N': 0.5, 'Y': 0.5}, '1F10': {'N': 0.5, 'Y': 0.5}, '0F10': {'N': 0.55, 'Y': 0.45}, '0E11': {'N': 0.65, 'Y': 0.35}, '0E10': {'N': 0.5, 'Y': 0.5}, '0F11': {'N': 0.7, 'Y': 0.3}, '1E11': {'N': 0.6000000000000001, 'Y': 0.39999999999999997}, '1E10': {'N': 0.45, 'Y': 0.55}, '1F11': {'N': 0.65, 'Y': 0.35}} \n", 79 | "\n", 80 | "Child node is CAT ['G', 'age', 'job', 'X1', 'X2', 'group', 'C_X1', 'C_age', 'C_X2', 'D']\n", 81 | "----------------------------------------\n", 82 | "\n", 83 | "--> Generated data is saved to out/hiring/R1.csv \n", 84 | "\n", 85 | "\n" 86 | ] 87 | } 88 | ], 89 | "source": [ 90 | "# name of folder to save the synthetic data\n", 91 | "data_flag = \"hiring\"\n", 92 | "\n", 93 | "# size of the data\n", 94 | "total_n = 30000 \n", 95 | "\n", 96 | "# initialize nodes\n", 97 | "node_g = CategoricalNode(\"G\", {\"M\": 0.5, \"F\": 0.5}, sample_n=total_n)\n", 98 | "node_a = OrdinalGlobalNode(\"age\", min=20, max=70)\n", 99 | "node_r = CategoricalNode(\"job\", {\"E\", \"F\"})\n", 100 | "\n", 101 | "node_x1 = GaussianNode(\"X1\")\n", 102 | "node_x2 = GaussianNode(\"X2\", miu=0, var=1, sample_n=total_n)\n", 103 | "node_d = CategoricalNode(\"D\", {\"Y\", \"N\"}) # the value does not have meaning. Only the keys matter for the domain\n", 104 | "\n", 105 | "# initialize edges\n", 106 | "edge_g_a = CtoN(\"G\", \"age\", {\"M\": [\"Gaussian\", 30, 10], \"F\": [\"Gaussian\", 45, 10]})\n", 107 | "edge_g_r = CtoC(\"G\", \"job\", {\"M\": {\"E\": 0.6, \"F\": 0.4}, \"F\": {\"E\": 0.4, \"F\": 0.6}})\n", 108 | "edge_g_x1 = CtoN(\"G\", \"X1\", {\"M\": [\"Gaussian\", 1, 0.5], \"F\": [\"Gaussian\", 0, 1]})\n", 109 | "\n", 110 | "\n", 111 | "edge_a_d = NtoC(\"age\", \"D\", [50], [{\"Y\": 0.8, \"N\": 0.2}, {\"Y\": 0.2, \"N\": 0.8}])\n", 112 | "edge_r_d = CtoC(\"job\", \"D\", {\"E\": {\"Y\": 0.6, \"N\": 0.4}, \"F\": {\"Y\": 0.4, \"N\": 0.6}})\n", 113 | "\n", 114 | "edge_x1_d = NtoC(\"X1\", \"D\", [0.5], [{\"Y\": 0.4, \"N\": 0.6}, {\"Y\": 0.6, \"N\": 0.4}])\n", 115 | "edge_x2_d = NtoC(\"X2\", \"D\", [0.5], [{\"Y\": 0.8, \"N\": 0.2}, {\"Y\": 0.2, \"N\": 0.8}])\n", 116 | "\n", 117 | "# define DAG\n", 118 | "nodes = [node_g, node_a, node_r, node_x1, node_x2, node_d]\n", 119 | "edge_relation = {\"X1\": edge_g_x1,\n", 120 | " \"age\": edge_g_a,\n", 121 | " \"job\": edge_g_r,\n", 122 | " \"D\": ([edge_x1_d, edge_r_d, edge_a_d, edge_x2_d],[0.25, 0.25, 0.25, 0.25])}\n", 123 | "\n", 124 | "\n", 125 | "\n", 126 | "# generate data\n", 127 | "mirror = Mirror(seed=0)\n", 128 | "mirror.generate_csv(nodes, edge_relation)\n", 129 | "mirror.save_to_disc(\"out/\"+data_flag+\"/R1.csv\", excluded_cols=['C_X1', 'C_age', 'C_X2', 'group'])\n", 130 | "\n", 131 | "print()" 132 | ] 133 | }, 134 | { 135 | "cell_type": "markdown", 136 | "metadata": {}, 137 | "source": [ 138 | "### 2. Simulate missing values in above generated data" 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "metadata": {}, 144 | "source": [ 145 | "### 2.1 Missing completely random" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": 7, 151 | "metadata": {}, 152 | "outputs": [], 153 | "source": [ 154 | "# define the missing patterns \n", 155 | "missing ='mcar'\n", 156 | "# columns to inject missing values\n", 157 | "applied_cols = ['job', 'X1']\n", 158 | "# fraction of inject missing values\n", 159 | "fraction = 0.2 \n", 160 | "# encoding of the missing values\n", 161 | "missing_values = {x:'?' for x in applied_cols}\n", 162 | "# random seed to use\n", 163 | "seed = 0\n", 164 | "\n", 165 | "# initialize the eraser\n", 166 | "perturbation = erasers.MCAR_eraser(applied_cols, fraction, missing_values, seed)\n", 167 | "# read the data to inject the missings\n", 168 | "data = pd.read_csv('out/hiring/R1.csv')\n", 169 | "missing_data = perturbation.transform(data)\n", 170 | "missing_data.to_csv('out/hiring/R1_'+missing+'.csv')" 171 | ] 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "metadata": {}, 176 | "source": [ 177 | "### 2.2 Missing not at random but depend on some other columns" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 10, 183 | "metadata": {}, 184 | "outputs": [], 185 | "source": [ 186 | "missing = 'mar'\n", 187 | "applied_cols = ['job', 'X1']\n", 188 | "fraction = 0.2 \n", 189 | "missing_values = {x:'?' for x in applied_cols}\n", 190 | "seed = 0\n", 191 | "# specify the columns on which the missing values are depend, e.g., both job and X1 depend on G\n", 192 | "depends_on_cols = ['G', 'G']\n", 193 | "# specify the order of the dependent column\n", 194 | "# if categorical column the order is specified by the value of each category, e.g., {'G': {'M': 1, 'F': 0}} means sorting based on G and the order of 'M' and 'F'.\n", 195 | "# if numerical column, then the order is specified by a weight of the column, e.g., {'X1': -1} means sorting in the reversed order of X1.\n", 196 | "depends_on_cols_orders = {'G': {'M': 1, 'F': 0}}\n", 197 | "\n", 198 | "perturbation = erasers.MAR_eraser(applied_cols, fraction, missing_values, depends_on_cols, depends_on_cols_orders, seed)\n", 199 | "\n", 200 | "data = pd.read_csv('out/hiring/R1.csv')\n", 201 | "missing_data = perturbation.transform(data)\n", 202 | "missing_data.to_csv('out/hiring/R1_'+missing+'.csv')" 203 | ] 204 | }, 205 | { 206 | "cell_type": "markdown", 207 | "metadata": {}, 208 | "source": [ 209 | "### 2.3 Missing not at random but depend on the columns themself" 210 | ] 211 | }, 212 | { 213 | "cell_type": "code", 214 | "execution_count": 11, 215 | "metadata": {}, 216 | "outputs": [], 217 | "source": [ 218 | "missing = 'nmar'\n", 219 | "applied_cols = ['job', 'X1']\n", 220 | "fraction = 0.2 \n", 221 | "missing_values = {x:'?' for x in applied_cols}\n", 222 | "seed = 0\n", 223 | "# specify the order of the columns to be injected with missing values \n", 224 | "# if categorical column the order is specified by the value of each category, e.g., {'job': {'F': 1, 'E': 0}} means sorting based on G and the order of 'M' and 'F'.\n", 225 | "# if numerical column, then the order is specified by a weight of the column, e.g., {'X1': -1} means sorting in the reversed order of X1.\n", 226 | "missings_cols_orders = {'job': {'F': 1, 'E': 0}, 'X1': -1} # order first by F and E and then by the reversed order of X1\n", 227 | "perturbation = erasers.NMAR_eraser(applied_cols, fraction, missing_values, missings_cols_orders, seed)\n", 228 | "\n", 229 | "data = pd.read_csv('out/hiring/R1.csv')\n", 230 | "missing_data = perturbation.transform(data)\n", 231 | "missing_data.to_csv('out/hiring/R1_'+missing+'.csv')" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": null, 237 | "metadata": {}, 238 | "outputs": [], 239 | "source": [] 240 | } 241 | ], 242 | "metadata": { 243 | "kernelspec": { 244 | "display_name": "Python 3", 245 | "language": "python", 246 | "name": "python3" 247 | }, 248 | "language_info": { 249 | "codemirror_mode": { 250 | "name": "ipython", 251 | "version": 3 252 | }, 253 | "file_extension": ".py", 254 | "mimetype": "text/x-python", 255 | "name": "python", 256 | "nbconvert_exporter": "python", 257 | "pygments_lexer": "ipython3", 258 | "version": "3.8.2" 259 | } 260 | }, 261 | "nbformat": 4, 262 | "nbformat_minor": 4 263 | } 264 | -------------------------------------------------------------------------------- /Demo_mirror_generator_pareto.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Mirror Data Generator\n", 8 | "- mirrorGen is an open source tool to generate synthetic data based on a correlation DAG, which describes the relation among the columns in the data. It can be used to produce \"dirty\" data, mirroring various bias in real life, which can be used in applications, such as classification and ranking tasks [[1]](https://arxiv.org/abs/2006.08688).\n", 9 | "\n", 10 | "## Demo the usage of mirrorGen to generate data that is described by the DAG below.\n", 11 | "- It simulate a dataset with 6 columns: \n", 12 | " - G with values of 'M' and 'F' and each value has a probability of 0.5 to appear, i.e., 50% is M and 50% is F. \n", 13 | " - U with values from a Pareto distribution with P(2.0, 1.0) for shape and scale respectively.\n", 14 | "- The correlation among above columns are:\n", 15 | " - X is determined by G and U with weights of 0.2 and 0.8 respectively.\n", 16 | " - Y is determined by G and X with weights of 0.4 and 0.6 respectively." 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": {}, 23 | "outputs": [ 24 | { 25 | "data": { 26 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAUQAAAFKCAYAAABl4Ca2AAAgAElEQVR4Xu1dCbhNVRv+jPde8zxmJmNdDZKQUpT+UlQqGpChkGY0KUpKA5Lq5xdKJZRolFJmRUKkIrNkninh/s+7tI5zzz3nnj2ds/c5+/2e5z5X3bXX8K593vOt9U05MjIyMoRCBIgAESACkoOEyLeACBABInAKARIi3wQiQASIwL8IkBD5KhABIkAESIh8B4gAESACmRGghsg3gggQASJADZHvABEgAkSAGiLfASJABIhAWAR4ZOaLQQSIABHgkZnvABEgAkSAR2a+A0SACBABHpn5DhABIkAEskOAd4h8P4gAESACvEPkO0AEiAAR4B0i3wEiQASIAO8Q+Q4QASJABHiHyHeACBABImAAARpVDIDEJkSACPgDARKiP/aZqyQCRMAAAiREAyCxCREgAv5AgIToj33mKokAETCAAAnRAEhsQgSIgD8QICH6Y5+5SiJABAwgQEI0ABKbEAEi4A8ESIj+2GeukggQAQMIkBANgMQmRIAI+AMBEqI/9pmrJAJEwAACJEQDILEJESAC/kCAhOiPfeYqiQARMIAACdEASGxCBIiAPxAgIfpjn7lKIkAEDCBAQjQAEpsQASLgDwRIiP7YZ66SCBABAwiQEA2AxCZEgAj4AwESoj/2maskAkTAAAIkRAMgsQkRIAL+QICE6I995iqJABEwgAAJ0QBIbEIEiIA/ECAh+mOfuUqTCMyePVu+/fZbWbZsmdxxxx1y3XXXmeyBzRMRARJiIu4a5+w4Ahs2bJDhw4cHSDB4gCeffFKeeuopx8dkh95DgITovT3hjOKIAIhwwIABMm7cuEyjpqenyyWXXKJ+6tevL5UrVzY8q44dO0qOHDlk6NChUqRIEcPPsaH7CJAQ3d8DzsAFBMIRIY7GIDOQoB0pWrSo7Nu3T5HhfffdJ9AwKYmBAAkxMfaJs3QQAZAVSEsLiBBHYjNaYHbTAdmCCKdNm6aaoV/0j3Eo3kaAhOjt/eHsYoQACArE5SQRhk4VRhkQ4/Lly9WfoH2OHTs2Ritit04gQEJ0AkX2QQSyQQD3kyDG/fv3kxQ9/qaQED2+QZxeciAA9x3cTZIUvb2fJERv7w9nl0QIBJMiyHHq1Km0Qntsf0mIHtsQTie5EdCkiFXiKE2Hb2/tNwnRW/vB2fgAAZAiBP6NFG8hQEL01n5wNkSACLiIAAnRRfA5NBEgAt5CgITorf3gbBxA4KOPPlIWXYbNOQCmz7ogIfpsw5N9uYhCqVKliiLD9evXG17uJ598ItOnT1fte/XqJWeffXbUZx977DHZuXOnpKSkyIgRI6K2ZwPvI0BC9P4ecYYmEIDltlOnTtKsWTOVucaoDBw4MBBzjJC71q1bR320QoUKsmXLFtUuIyMjans28D4CJETv7xFnaAKBc845R+UwRIgcQuWMCgnRKFLJ3Y6EmNz766vVITYZx+XChQurbDNmhIRoBq3kbUtCTN699d3KEC+MJK/IKhOa3zAaGCTEaAj54+8kRH/ssy9WCe0QWuKPP/5o2umZhOiLVyTqIkmIUSFig0RBAFmqrRo4vECIuo4LE8q698aREN3DniM7iIC+P6xUqZLSEs2KFwjRDqGbXS/bh0eAhMg3IykQgIvNpZdeatrdRi/eC4QIZ3Joid98843tMgZJsakuLIKE6ALoHNJ5BLT/oRWDCmZDQnR+TxKxRxJiIu4a55wFAZQCQPU8qyVDSYh8qYAACZHvQVIg4CQhIhb62muvjYpL6dKlZceOHZYNOaEDaLchlC/FvynxR4CEGH/MOWIMELBLiC+++KI8/PDDamYTJkyQDh06ZDtLhOrlzJlTtSlYsKAcOHDA9qp4h2gbQtsdkBBtQ8gOvIDAsGHD5P7775d7771X8G+zMmbMGOnSpYt6bOTIkdKjR49su9i9e7eUKFFCtalatar8/vvvZofM0p6EaBtC2x2QEG1DyA68gIBdKzMy3ehjcteuXWXUqFHZLmvp0qVy3nnnqTZNmzaVOXPm2IaBhGgbQtsdkBBtQ8gOvICAXULctm2blCtXLnAEXrlypVSsWDHi0qBNQquEPProozJo0CDbMGg/xL179zKXo200rXVAQrSGG5/yGALaMRt5EEEoVgQaHzQ/SJ06dWT+/PlhiQm5E6+55prAEHPnzpUmTZpYGTLwDDL0IFNPenq6ytZDcQcBEqI7uHPUGCCAok3Lly9X5T2tVLODQ3Tz5s0DMytVqpT6b5Bd8eLFVQQMNNEZM2YE2lx//fUyZcoU26vRd6BW/ShtT4AdKARIiHwRkgYBbWm2algBEJqYjIDSokULef/996Vo0aJGmmfbBlohxgaRWyFz2xNgByREvgPJhYA+dlauXNlU+YBQFBYsWKDIafLkyWEBQnkBlBlAAto8efIkF4g+Xw01RJ+/AMm2fJAhBEdb/W+razx8+LBs3rxZ/vjjDzl27JjAEbts2bJSpkwZq13yOY8jQEL0+AZxeuYQgJbIAvDmMGPr0wiQEPk2EAEiQAT+RYCEyFeBCBABIkBC5DtABIgAEciMADVEvhFEgAgQAWqIfAeIABEgAtQQ+Q4QASJABMIiwCMzXwwiECcE4BKEFGVIAEvXoDiBbnIYEqJJwNg88RHYt29f3LPJIAt3p06dBGM3a9ZMOY5TvIcACdF7e8IZxRABpOYfP368Cs1DIoV4CGq9IM4agjExNrLyULyHAAnRe3vCGcUQAZ2EFUPg32PHjrUd4hdpusiOA61Qa4OslRLDjXWoaxKiQ0Cym8RBAMdXJGbYv3+/0tSgNSJDjlNaGwgQWihKo0IKFy4sGBMETPE2AiREb+8PZxcjBHCXp4/PegidegulBKyQoybB4PtBHpFjtIEx6paEGCNg2W1iIADywv3e7NmzM00Y5Igaz0atwSBYnRcRGiHIFj9WiDUxkEvOWZIQk3NfuSqTCIDQcKzFz7Rp09TTyKCtj7koOwrRdU/CdQ8CBIHiOE5JTARIiIm5b5x1DBHQ5BhMbMiJWL58efWzZcuWGI7Ort1EgIToJvocO2EQQKJYVOGrUKGCbNq0KWHmzYmaQ4CEaA4vtvYpAhs3blTuOXbLE/gUvoRZNgkxYbaKE3UTgXXr1km1atWkatWq8vvvv7s5FY4dQwRIiDEEl10nDwJr166VGjVqSPXq1WXNmjXJszCuJBMCJES+EETAAAK//fab1KxZU/388ssvBp5gk0REgISYiLvGOccdgdWrV0udOnWkdu3a8vPPP8d9fA4YHwRIiPHBmaMkOAKrVq2SevXqqZ+ffvrJ0dUcOnRIZsyYIcWLF5cLL7xQUlNTDfeP8MPFixcrV6By5cpJw4YNVaggxRoCJERruPEpnyGwYsUKSU9PFxSpX758uWOrf/HFF+Xhhx+WNm3ayI4dO2Tbtm3y1VdfSZUqVaKO8cUXX0i7du2kVq1a0qpVK/n888/VcX7SpEly5ZVXRn2eDbIiQELkW0EEDCCA5K7nnHOOikT58ccfDTwRvQmSPyAbzsiRI6VHjx5y5MgRdUcJgREnJSUlYicgTmiEINIPP/ww0O7SSy9V2XVAriVLlow+CbbIhAAJkS8EETCAwA8//CDnn3++nHfeebJkyRIDT2Tf5PDhw1K2bFnVaPfu3ZInTx717//973/StWtXeeONN6R79+4RO5k4caLccsstKn1ZcETNiBEjpHfv3kpbpJZofptIiOYx4xM+RAD3dBdccIE0aNBAvv/+e9sIzJkzR2XO/s9//iOffPJJoL9FixZJo0aNpFSpUrJ9+/aI40yfPl2QleeKK66Qzz77THLmzKnaPvTQQ/LSSy/J1q1blQZJMYcACdEcXmztUwS+++47ZfDAz8KFC22jAA3w7rvvVtrc8OHDA/2ByM444wz139kde4Oz6/Tq1UvVaYHDOO4ToTFCc6SYR4CEaB4zPuFDBBYsWCCNGzeWiy66SObPn28bgZ49e8prr70mKC/Qv3//QH/Hjx8PHJ9xNMcRPZLoYzP+jqw8cAfq0KGDDBkyRHLnzm17jn7sgITox13nmk0jMG/ePGnatKk0adJE5s6da/r50AfQD4j11VdfFZBjsJQuXVpph1OnThXkZcxORo8eLd26dVNNChYsqFxwtGHG9iR92AEJ0YebziWbRwAJZKGFOVUxD/eRIK///ve/AULTsypUqJAcPHhQWYsxXiSBYQYZueE0jmw8eAakCPKGexDFPAIkRPOY8QkfIoBksc2bNxe4tcyaNcs2AtD8kIgWBpAHHnggU386Ce2ff/4p0BbDCRLWXnPNNconEm5AO3fulJYtWyoHbRhkQJB58+a1PU+/dUBC9NuOc72WEICzdIsWLeTyyy+XmTNnWuoj+CGQIAwhjz76qAwaNCjwJ20sgaZ34MCBiONoq/fzzz8vffr0Ue2QogyaJ47bsFzDgk0xhwAJ0RxebO1TBL788kvl4gItDGF2dkVrnCBZ9K0FLj0Iv4M2+vXXX0ccBnVgYJCByw2iVLTASfv6669XFmwYbSjmECAhmsOLrX2KAMLkQDxwdobTs105efKkVKpUSR1xcReYL18+1eXTTz+trM5jxoyRzp07B4aBSw3aa+sxXHVQwwWFsECOWhC6hwQUgwcPln79+tmdpu+eJyH6bsu5YCsIfPrpp3L11VdncaS20pd+RrvyDBw4UJ544gnRdVvg3gODiiY/hPbB1zA4TA/HYuRmRCIH+EjCCRv3ioiLHjVqlCAZBcodUMwhQEI0hxdb+xSBjz/+WFq3bq0MGYgScUomT56sjCoI48MdII67zz77bKbypS+//LI8+OCDWcgYfoe33XabLF26VEWtILwQBhWE/yHummIeARKiecz4hA8RQHlSaGiwDsM/0EmBZgdyQ3mCtLS0LF3j77Ak4ygc7u+7du1Sha9QETCSVdrJ+SZzXyTEZN5drs0UAriny5Url4oLxo/+N37DeAGfP2iJ7733XpY22dVrNjUJNnYVARKiq/BzcC8hcNdddylHaSuiSRR3e0WLFrXSBZ/xAAIkRA9sAqfgDQRWrlwpZ511luXJhPoUWu6ID7qGAAnRNeg5sBcRQI5BJE0wK4gKQaaaEiVKmH2U7T2EAAnRQ5vBqbiPgHaFMTuTvn37ynPPPWf2Mbb3GAIkRI9tCKfjPgIIeYMRxajg/hDaYZkyZYw+wnYeRYCE6NGN4bTcQwCRKFdddZXhCcBHEMWiKImPAAkx8feQK4gBAjpfoZGuEX4HH0BK4iNAQkz8PeQKYoDA+++/LzfffHPUnu+9914ZNmxY1HZskBgIkBATY584SxcQQJLVaEXpN2zYoJIuUJIDARJicuwjVxEDBJAkIbtSoEi4gLKflORBgISYPHvJlcQAAWh/iBMOJwj1Q/wxJXkQICEmz15yJTFAANZjpNQKFYT5vf766zEYkV26iQAJ0U30ObbnEfjrr79Uai6k9g+WX3/9Vc4880zPz58TNIcACdEcXr5qjYSlSHVfr149FeMLB2SjgnRVSFKKCnKoLZzIbilI3vrMM88Elt61a1eVhJWSfAiQEF3aU+SwA+EUKFBAZTtOTU11aSZZh/37779V+vp3331X/UbND5Aa/lunuo802SNHjsitt96aJWdgcDEkzyzU4ES2b9+utETkJYSA6OvUqWPwaTZLJARIiDHeLRAEKqAhBf3atWsVCeLn2LFjmUYuXry4IkZ88OAUjHT1bmU97tSpk4wbN06WLVsm6enpyvUELiggurfffjtbxBC1gQzPyOR87rnnypQpU1RBdsikSZPkxhtvjDHisem+d+/eyqIMbN58883YDMJeXUeAhBiDLUDBcGhTIEH8oKBQqBQrVkwR4KFDh8ISJNrjjgrEiB/UA46HLFmyRBo0aJAlVX6HDh3UmkCOOEKHE2iWJUuWFBR112R+/PhxlVQV4XCoWodiTYkm0AxB6k2bNhWUI0VFPCaETbRdNDZfEqIxnAy3QuFx1MTYs2dP4JlmzZopUrvwwguVBggiDE0Fj0Lj0BxRVwMkCq0S/60FpPLII4+oPmIpuCvDnVloAfUhQ4YIMrp07NhRxo4dG3YK69atU8drWGCDBWQCrRcED2OEl2X9+vUKf5Qa3bZtm9oD/A4VvY/4DaJHQogqVap4eWmcmwEESIgGQDLSBEdMEOGaNWtUc5SsRMEgfFCsZkGZO3euIka4d0DrhODIhkSkqLgWC7npppvU0faDDz6Qtm3bBobQoWy4O8MdmhlBvZC6detmS6Zm+nO6LQxAwBk/qIscTkB8+AE5hiNIPIMi8Vqjd+u6w2ls/NYfCdHmjsM4cvvttwdq9eJDAU0OxYicEmibIFtobVqQ6r5bt25ODRHop1q1agJND9blSy65JPD/Fy1aJI0aNVL/jSsAM0dGVJZr166dun/EPaRXBNogcEWVOi0wGuFLDMSGok5aEwy2sGP9WnNcvXp14I4Y98VaunTpor64qDV6ZbeNzYOEaAynsK1QDxdk+Ntvv6l4Vhw177zzThs9Zv8otE98gKGNQpxOSooPdP78+VXfy5cvV4YULTAI1ahRQ/0n6obgrtCooLj75s2bVZ+61rDRZ2PR7sCBAwpHWL614MtF1102416knwdJ6quOYJcc7BGIEe5HFO8jQEK0uEeovAYyhNEAl+xvvfVW3HztdOFyTB1WW4zthNsOiAKFzyGhriXQhLSrCZyVU1JSDCGHO0XcsS1cuDDm959GJoT6yrgH1Xe8sIZDo4c26JQAq8GDBwcs8jCg4UsMNZ0p3kaAhGhhf8aMGSM4EkHwe/To0RZ6sfcIrLYgZBzZYWiB4cKKZhM6C30Uxl0arM1aUAT9/PPPN2UYwV1b/fr1lTYWS83ZKJJI03X//fer5kgAC82tcePGRh833Q57grXr7NsYH+nCKN5FgIRocm9wtwaNEAItoF+/fiZ7cK45juq4m8NRFG4xEyZMsN05jB8wgsDK2rJly0B/OA7iSIkcgdCOowmO37iDvOyyyxRObov2I8Q8HnvssUyRJ7Ge2+OPPy6DBg1Sw9xzzz3yyiuvxHpI9m8RARKiCeDgEgP3EWRI9kpiUPgFQsuBFRp3mAMHDjSxoqxN8fyTTz6pNBscJbXAoPPQQw+pDzY0q+zkn3/+UQQNZ/PXXnvNlAHG1uQjPAxr/4cffqj+Cu0e0TfxFjhzay0Z1ntY8SneQ4CEaGJP4E84Z84cpSnhLsor8tFHH0mbNm3UdHBXdccdd1ieGizMsDRDu4M2rAWO4d9++63gfqxWrVrqf+P+FF8SaK8Fztko5Qk/y/Hjx2cyosCpGY7Z8aw/gkw1GK9UqVLKnQh76JYAP2jYCAXEl8sLL7zg1lQ4bgQESIgGX40BAwbIU089pQwLuBsqUqSIwSfj00xrcJgXsjhr44iV0XVf+ACDQPRxOdSqDU1n6tSp8uqrr0rPnj3l6NGjAj9GfFng/hG1iiEIU9y9e7dy54GvH9xa4iFvvPGG3H333Wqo0CuAeIwfbgxtZMLfoD3r+bk1H46bGQESooE34s8//5TKlSsLtJ+ZM2fK5ZdfbuCp+DeB5gry6tOnTyaXEiszwT0bYndxp4grAtzBQasJ9j/U4+molgceeECGDh0acbiCBQsqYsyTJ4+VKZl6xsvEA0f7Hj16eIqoTYGbxI1JiAY2V1/I33DDDQInY69KcJF1J7I54wsAvo/QisNZsKER4giNqAwzjtrxwA9hgpi7V4+m+igP304YxyjeQICEGGUf4I+nkxksXbrUdgYaGD+mTZumjpWIlMAdHIjloosuUi4qGAtHyqJFi1p6Q3B/CL9EXOAHR2BY6ixBH9JHfkQNwXneq9KwYUMVKog7TmQJoriPAAkxyh6gyJAuNoQ7KauCSAYkSAi23EbqCwYAaKIXX3yx6eGQPEEbPfxYEQ5fOLjegOM17jedDKE0vRlRHtDGMDhuY69wpUBxFwESYhT8zzjjDNm6davAMRn5/awIPqSwvOJ+L1hwFEXiVUSZoH9ooMFi1c8R0SvIQ6iNHVbmnKjPwCUIuCG5hnaINrIWaOn33XdfIAks3IaiWaTxJQdDG+6YIXDSh1ZqRuAgDid7fFHC1YniLgIkxGzwR7YZaGl273lgSQzWLmH0gK9faPbp/fv3C0pbBjtY41gNjceMwN0F4WlmScHMGF5si7on+qoB7lHIX2hGQErPPfecegRa+sqVK7ON2YbbDPYSAqs63hejIY16Xvodw3/v3bvXc94LZvBLhrYkxGx2EVEoSACAcC9kgbYiwdZOPB+aRSZcn9rFB3+zMjbC+XTyBZCEHRccK2s2+8y2foMkT4VyUqJnJ7OPZmr/zjvvqGw6LVq0UHkZzQrcg5DRR2vq8O3UDt2hfc2bNy9AuDjqIoVYsD+mmbEREQTvBXwRQjOluIcACTEb7GHggFHl66+/DoTrmd0qhK7NmjVLPQai69+/f9QucMRGUSadAxH3YWaNLHANwrxBEu3bt486ppsNtvZ+QnaNHCsptapLqT49pNgd7SxNB9cSEydOFDsxw8F3sJgEDFOhcdjI9oOiW/gNwfUEomGsyvDhw9Vx3WhYpNVx+Fx0BEiIETBCan988+NYe/jw4ehIhmmBnHm62hz6wgfIaFYafBDh/wdiQ/IGs2mzdIZrr7qdBMO1uevDsufN0/HR+RqkS6k+PaVw26tM4Q6MsW9IVWZVW9MkiMp6WuAWo1OfnThxQl1FQKOD4IoD/pp2BC5SSPiLgmP6S9BOf3zWOgIkxAjY4UNQs2ZN9cHCB8yKBMevWj3GWRkXzyAZK7LhOJX0weo8jDy3sUMv2TfxoyxNC1zaWEr17SEFW0QPt4MBBe5KyMizePFiI8NGbIMaKtD4YKWG4H4QPp74UkIsN5I1QJAvEolzQ8tBWBkcY6CeDQxvMLRQ3EGAhBgBdxRKQjwvLuZxQW9FYDjRyRacTuYabT44LkO7RAyyPrJHe8atv69vc6ccmD4j4vCFW1+hjtL5Gp0XsQ0ia2ClBeaw/NoV3MMiSkcfi+ErCANbsBU5WHO0Ox7mjCsVWMl1Zhy7ffJ58wiQECNghhRXuHtDei3UE7EiupwnnkV/uCMKFWgjODJBdN3f0Cp9OHbjOGVGdB0T+CQimsTLsu7KDnJw5uyoUyzavo2U7NNT0s46lVwiWDTW4e78onYcoQGSUUCz1wLLsybISPtpdSydYzO7Il5W++ZzxhEgIUbAClZlRA/gsju7+NzsoAaZ6lC/SIYZWDajuWpYMRJoF5TZucpJyQpnSI60VMmZL0395Eg9/W/130F/U23SUgJtA39PO/VsaHs8myNnTuNvXJiWa5u1lcPzwhd3Ctdx8e63KY0xb+UKgT+jTAESODh95IRbTWhWGpQbQE0bJ0Uf+RO1VKuTWLjZFwkxAvraxwykaDVdFXIm6mSgkTSKWBEiLueLFSokS3KWj/n7lSM1RXKFI8soxKuJeMfgEXJsw2bT8yz10N2KGHMVLyrp6emyYsUK5f6CEEinBOUSYFCBgUsLjGyhPqR2x1u2bJkKC8W9JBL+UtxBgIQYAXf4hKHeBlw5UKDdigQ77uIuEQlcQwXHY8Qehx6TEYOrixVZ0RDhPlK/Vm2pW7WaLPjmWzl55KhkHP1L/T559Gjm/8b/C/z9VBvd9oT+21//Phvcz79/k4wMK/A48gw01pJ9esi5rwyWbbt2qqiR0qVLO9I3OkGsMWKOgwXGMhzRnRQcxTHvEiVKCGp0U9xBgIQYAXcYIuBDGJoo1cw2acMGnjFbpD046asVQkQuQxhUYAiAgSiWkvHX36eINpRIjwaRcMjfg9vvfe8jOXn4dAlPs3PNXaqE/HfnRhlxYp+YKYAVbRxEjkBjC9YO9TNOGlTQJzILwSULqdFwaqC4gwAJMQLuusqcWSIL7g4ZpWEQ0RfxuKQHyRoRu4QIrRYuN4ng7LuqTLoc37nbCCyZ2qSdf7YU73qrFO/SXpWB3bRpk0pC60QtZBi4kOxW3wHjPhjXEIg7hiCuHZUEdRJc05MPeQAhmlWrVpWKFSuqDEgUdxAgIUbAHXHFyD4NZ1+U57QqukYJnoeVEvdcRo50wZX9rGiIOgWWldA/q2u1+tzKwjXlxCHjzu9w2C7erUMm/0SE3MEnENnMkUrNrgQnccU7gNyKqBWDhBzaeRqhnU4V0NK5LOGED6KluIMACTEb3BE9AJcYvKz4wFkRHOFwBwUi1KSIcLpIWbdRuhO+dMGlTa0QImoAI12/k24oVtZv5JkVeSpKxsmT2TbNWSC/FO/aQYp1aS+ptapnaavLGUCjQyJfOwLDTHBmI2iFsGJD0D+0RS24WsHVhF1B+B+yFGUXP213DD4fHQESYjYYaSuxXWfZX375RTn0BodlQdPAcRaki3AwWBlxgY/sJ8GCdjj+wopqVGAF1X6LThsZjM7BaDvcP67If7pIVehzqXXPlGJdOigyzJmWGrFbhNCNHDlSWfVR6tOqYI9gpcbRG4KyCNC2gyXYvxRaP3w+UWHQjiD8D5nZUZsGadso7iBAQswGd8SrIhOJE64QICY43cJXzojgmIbjGHzezNYggSM5yNaOQcjIHJ1oc3zPPllVsl6Wrgpeeak6Fhe+9pRmFk2QlQhHWJAVrMBWBeGOCHuEYN9h7Q+NP8d1ChJ/aGOLE1odSqOOHTtWpR9DVBPFHQRIiFFwxzc/ss1AC6hdu7atXYJrDQwr+MCFKyoPEkTCWNR+hnYKFwwroj/UiZCa/p+tf8rPFc8/tcycOZUmiJ+0c7KSZHZYIHchMtBAY0OZTysCQgqu2RxccjW0v+D6NfgbrjiQINaq4F4ZxjfU2dYlK6z2xeesI0BCjIKdrlGCokDIIOOUwM0C94XIiIMMLUgkAQuj3WJN6A8JZWEAyO4D7dQ67Pbz95r1sq5Ve2Utxv1g7uLWaslgHnbStQXXzjFKcDr+WGNgFW/kyGzevLmKnQaxU9xDgIQYBa4QFRIAAB9GSURBVHtYLrVBBZZG3Pl5WfRdmp0Y7Hiu78SefZKrmDM1rnHUxJdWuHu/aGvSkS5oh0w3MHJEE3zpNG7cOJBdx6qFGNFQCBV1onxstDnz79kjQEI08IboS3Qcp+AO41XBcQv3XhAYacwYYry6JjPz0un4oW3DkJUoggQciCyyUvYgUdaYKPMkIRrYKWiGcNCGQGMMDeUy0EVcmuiM0ajh8tprr8VlTK8NgnhgfBnYtTbHa13augzLNtx9KO4iQEI0iD8yT8P9Akck1NPwmuhktLly5VIlLVEt0I8yadIkFWFSpkwZhUO0TEJuYoR7ZNz3wgMBngHB/o1uzsvPY5MQDe4+/NNAhjiWIukDEjJ4RXQyW8wHqcqQsszPouvJOJUsNlZYaqMMwjnhfUBxHwESook9wFEMLjFwfPbKh23z5s1qTojjhUOyTjdmYllJ11Qn1YD/JlJp2XWXigVAsEjjjheGGTMx7rGYC/s8jQAJ0eTbgLKUusKaXd8zk0NnaQ7/SMwFmW1QTwShepRTCOj7VPh1Ir7ZS0dnHJVx2vjhhx8SIvmGn94pEqKF3YbDM/wSIU4G+JuZCgopwQEb1lRYKfGhL1asmJkukrotUmhBcwZOXnNBwh0n7jpRWAr30U5lzEnqDY3T4kiIFoHW1kE8jg8c7hTjpYXgAh5kiA89wvMwdoUKp9PpW1xS0j2GLwtoYtCk3friCgX1kUceUeF5+PLClxi+zCjeQYCEaGMvUL8DxIQPHI5muCS/+uqrbfSY/aOIoUVlOR0xgwLqyGZDiYyArlWCFm6nQoPDuK7P43TtF74DziBAQrSJI7QQkKKuBQxCRHYcq+nCIk0H5QhAhigeBUGpSoxDiY4ASjF0795dNbz22muVRl2oUKHoDzrUAvk08Y5MmzZN9YgCVUjaQfEeAiREh/YE2VaQnQZaHAQx0MjLZ0djhEM4DCVIa6VLlcJ4AiJ0IgmqQ0tPiG5geQYpIdYbMc8gRThxx1rgbI1xEaNcrlw5Na7RrOmxnhv7z4oACdHBtwLaG7S44LKVyEsIUgSRQWvEhyItLS3sqMh2AmdiHKdAhEuXLg20Q5ws7p9at27t4Iz91RXS9IOctGN9jx49FKaxcGJHajB8QeqIIRh4QIZOlDfw167Fd7UkxBjgDW0O6b1AakuWLMkyAi7Uy5Ytq8gRmW6gtSDzTWhxIRzrNJm2b98+BjP1Z5dIwqqJKnfu3IoUoXWH5j20gg4ypONLEWSImjoQEC+0fIr3ESAhxniPQI5a48MRGMQHP7RwgtyLIMmmTZsqImzVqlWMZ+ff7lHSAcQFiz0ETtzQ4vUXEEL/jApC7/Qe4zecrSFwrwHR6oQbRvtjO/cQICG6gP2uXbtk048r5Lsr2kmhMqWl0byPFRE6oaG4sJyEHhK5CEGMoaFzzZo1UwXqtSaP/cG/dQ5L/RtfcqFlXhE6CCJ0otZKQoObgJMnIbq1aRkZsjxPRcmRO5ec/dcGt2bBcf9FAHd+WsuzEvEDzVJrl7G4k+RGxQcBEmJ8cA47yqqy9eX4jl1Sd/sKyV2CUSYubkWmoRGrDqs0tECtCUILRHF6pIGD9qg1RmiN0Ajz5cvnlelzHjYQICHaAM/uo7+dd4UcXbZKai77SlLPYsSCXTxj+bzOTOOVpB6xXKuf+yYhurj766++XQ58Pkuqfv6OFGzZzMWZcOhoCJAQoyGUHH8nIbq4j5u7PSx7xrwnFd58WYrdcbr4uYtT4tARECAh+uPVICG6uM87XnhNtvV7Vkr16yVlB/VzcSYcOhoCJMRoCCXH30mILu7jwa/nyrqWt0jBFs2k6hfvuDgTDh0NARJiNISS4+8kRBf38cS+A7KyeB3JVaSQ1Nv9s4sz4dDRECAhRkMoOf5OQnR5H1dXvVCObdwitdctkryV/FkYyuUtMDQ8CdEQTAnfiITo8hZuaNtF9k/7QipPGS2F2zBUz+XtiDg8CdGrO+PsvEiIzuJpurftzwyTP598UUo/2lvKPN3H9PN8ID4IkBDjg7Pbo5AQXd6Bw3O+k7WXXi/5GzeQ6nOmujwbDh8JgXgSIjIgzZgxQ5DsA2nfrMa4nzx5UtatW6dK5yKrzzXXXMMNjoIACdHlVyTjxAlZVbKenDhwSOr+uZwhfC7vh9uEqAuYtWnTRpAfE6GDSDxhJo9iRkaGvPnmmyrBRKVKlVRlRoQXoswFJXsESIgeeEM2tu8p+96fJhXGDpVit9/ogRn5cwo623m41aMwFH5QrAo/kaRw4cKWwRs3bpx06tRJ5U5EDsUjR45IzZo1VX9r1641VMTs6NGj0rFjR1XVD2Um+vbtK7ly5bI8J789SEL0wI7vfXeqbLrtHinc9iqpPHmUB2bkzykgo/miRYssLx7H24ULF1p6HgklkCgCsnv3bpWfEYIiYl27dpU33ngjUBcmuwF69+4tqAj50ksvCYpaUcwhQEI0h1dMWp/Yf1D5I+ZMS1X+iDnynvowUOKLwMSJE1WBe6vy3nvvqcLzVmTOnDkqiw6S1AanHwNBg6hLlSol27dvz7ZrpC/TKcg+/vhjyZEjh5Wp+PoZEqJHtn/txW3k8PzFUnnSf6Xw9f/xyKz8N4369evL8uXLTS88PT1dli1bZvo5/QA0wLvvvlug4Q0fPjzQz9atWwM1X3CnWLJkybBj7Ny5U6pVqyYHDx5UWm7Dhg0FRpWcOXNanpMfHyQhemTXd7/xlmzp+agUaN5Eqs2c6JFZ+W8aY8eOlc6dO5teOIwYuP+zKrrOy4ABA6R///6BblCXRR+fUZ8nkmEkWLu97777ZMqUKYKktw0aNBAYai6++GKrU/PVcyREj2z3ySNHZVXpswW/a/06T1KqV/bIzPw3DRgykAzWqCBp7K+//mq0edh2qMo3f/58efXVVwXkGCylS5dWFuepU6fKddddF/b5Bx98UF5++WUpWLCgvPLKKwKNFSQ5ZMgQ1V5rjbYm6YOHSYge2uSt9zwuu14bJyUf6C7lXnjCQzPz11RQkS+UlLJDQFuF7aB0wQUXyOLFi8MWsUf1RRyFv/32W3XPGE60QQjW5RtvPO2pgLK1uE9s3ry5ygJOyR4BEqKH3pC/126QX2o2kVyFCiqfxBwpeT00O39NpWLFirJ58+aoi65QoYJs2rQpartoDaD5TZs2Lax1WBtHUN0P2mI40aQ5a9asTMWtgskdd4o0tJAQo72Lnvr7781vkEOzF0nF8cOl6K3Xe2pufpoM3FYeeuihqEvG/RyOq3YFLjJDhw5VztTwH9Syb98+KVq0qDoKHzhwIOIw+sj92WefZSpfu3Tp0sC9I2pGp6Sk2J1qUj9PDdFj23to1jz5vcXN6g6x5s+zJQedal3ZIdRWRiEplIyNJCVKlJA//vgjYPSwM1GUQ8WxtkWLFvLll18Guvr++++VxTjakfeee+5R94+h/ocwrECLrVq1qqBGOIUaYsK9A+uu7CAHZ86W8iOekRI9Oibc/JNlwk8//XQmi2/ougYOHChPPOHMXS+OswizA4HBSVtX8dNzGDNmTCbrN8gN7RGjDJk7d66yJMOqDAOKdreZMGGC3HbbbRJqvU6WPXJ6HdQQnUbUgf7++ukX+fXclpKrcEGVJxF3ipT4I4AjKrREEFSo5M+fX2mHuLtzShYsWCCNGzcWTbTov3z58ur/waCiyQ9GnF69egninT/88MPA8H369JEXXnhB4DqE8D247MCoAvKEpmknrNCpNXq9HxKiR3do0x33yt4JH0jJ+7pKuZee9Ogsk39auNMbPHhwloU+8sgj8uyzzzoOwOTJk1XIHcL4Nm7cqBIzYJwiRYoExoJ7De4tQ6NacEcIx+7Ro0fLFVdcIXv27BEc699++22VOYcSHQESYnSMXGnxz5Ztsrp6I5EMkRoLP5a0c89yZR5+HxThctAScaTVguMotLdIFl+7mCFbzc8//6zu/dLS0rJ0h7//+OOPUrt27bB/BxGCTGvUqCEFChSwOx1fPU9C9PB273jxddnWd5DkrVpRFbPPmT+fh2ebvFO7//77ZdiwYYEFIhIEFmFK8iFAQvTynmZkyO+X3ajccIp1vkUqjH7By7NN2rlt2LAhUz7C9evXS+XKjCRKxg0nIXp8V//ZtkN+rdNMThw4KFWmjZVCV7fw+IyTc3p33XWXiiLp3r27SsVFSU4ESIgJsK/7pnwiG2+6S3IVLSw1f/pG8pQtlQCzTp4p4s5u9uzZKgIE/oIIn2PER/Lsb/BKSIgJsq+bOz8ge8ZPkrT0OlJ93jTJmS/rZXuCLMXT08RxGHkFUdME6fthPMHvUIEVGMYW/IZFFxZfM2n+PQ2CjydHQkyQzc/4629Ze0lbObJ4uRRo1kiqfvEuE8k6tHew2CIpK37grxdOQHz4ATmGI0g8gwQNSNCKn3POOceh2bGbeCJAQown2jbHOrHvgKy9+Dr5a9VvUug/l0vlqWMY2mcDU2iD8PFDmn4tiBCBtgdSg1uL1gSDE63CBUdrjqtXr1ZECq0SNVC0dOnSRcUlU2u0sUEuPEpCdAF0O0Me37FLfrvgKvln8x9S5ObrpNKEESJMFW8KUkSggAiff/75wHPdunULpN+3kmUaJAlSBDmOGnW6Lg6KPIEYnYxoMbVYNjaFAAnRFFzeaHxs3SZZ07i1gBwLt2klld59jcdng1uD3IAIa4PzMgRxvog6gTbolEBrRHQLIkQgxYoVE1TUY11kpxCOXT8kxNhhG9Oej/2+UX5v1V7wO1/Dc6TK9PGs6RwFcThXw8kactVVVynNDXHCsRJkwIYmipRcEIx/7733xmo49usAAiREB0B0q4sTe/bJulbt5ciSFZK3YnmpOuM9STmzqlvT8fS4ujwnJvnYY4/JM888E7f5Pv7444Ech0jThRT/FG8iQEL05r4YnhWszxtv6SH7p89QWXEqvv0KnbdD0EOCBJ0VJjSNlmGgbTZEEao777xT9dK2bVv54IMPbPbIx2OBAAkxFqjGu8+MDNnS6zFB5T5IsdtvlPKvPC05CzKw/+GHH1ZV51DXGPVGItUkiceWIYUX6jYjYQSycSNVF8VbCJAQvbUftmaz/4NPZfNdfQVH6TzlSkuFccOk4GVNbfWZyA/rWsdYAxytW7Zs6fpykA0bjtwQ1DtBLWaKdxAgIXpnLxyZyfGdu2VTx/vk4BffqP6Kd7tVyr3Y33eZcrxMPK+//rr06NFD7Y9XiNqRly8JOiEhJsEmhlvC3nenytbej8uJvftV7HPpx++TYl3aS45/U84n6bIDy0Kt5DVr1nj2aKqP8shZaKYGdLLvm9vrIyG6vQMxHP/47r2y/amXZPeoCZJx/LjkrVZJygx4WIrefG1SO3PrinkIpfvuu+9iiLC9rlE8CqGCTlXuszcbPg0ESIg+eA/gq/hH32dk/9TP1WpTz64tZZ/pq8L/kk1Q0B25CuF4PXXqVEG9Y6/KRx99pOqiwHEbORdRapTiLgIkRHfxj+voR777Ubb2fkz5LWpiLHH3HVK0Q9ukuWPUNVBatWoVcIiOBjLC7uAfiNKjEBg94KpjRODO88UXX6imZcqUUQWizAgcxD///HMVLROLGi1m5sK21BB9+Q4c+ma+7Bz2Pznw6VciGRnKf7HobTdIiZ4dJaVmtYTFRBd1xwLmzJkjTZsat7CHlhxFTZKKFStmi8WmTZtUKVAt7733nnKrMSO6fCie2bt3b6ZiUmb6YVtnEKCG6AyOpntZsWKFrFq1Sho1amQrHT0SCiCBKbKzmJW/126QXSPGyJ5xk+TkoVOlNvM1SJci7VqrxBFw3YmHbHtiiOTKn09K9e1p627znXfekVtvvTVLsXcja4B2eP755wv2BQINE9hGSgQLzJEVB9odBEQIQrQicAeaOXOmoIZyhw4drHTBZxxCgIToEJBGu9m8ebMirz///FMF+yNyYtCgQSqu1qzoOr7QhKARWRWUJ9jzv3dl18hxcmzD5lPd5Mgh+S48V4qCHNu1ltxlSlrtPupzfzw4QHYOGy15K5STkn16SIkeHaM+E67BLbfcIhMnTrQcMwwyTE9PD3T91ltvqeQP4QTJGjp16qT+BKdvJHTAXaAVGT58uKBwlR1StTIun8mKAAkxjm8F6ubWrVtXjh07Jr/88oug2DnqdKBeB3Ly6dAuI1NCCiu4bOzYsUMdDe0QYmC8jAw5NOc72T/5Y9n3wacqm44mx/xNLpAi7a45RY4lrH3wI61ry939lCVcS2rdM6VU317qbtOMwChx6NAhWbt2rVSrZu3ojy8nxB5D0N+vv/6qciIGC3Ih1qpVS2DAgdj1JUQh+erVq6uSobpPM+tmW+cQICE6h2XUnnS2FRQa11lXjh8/LuXLl1fP4t4qNTU1aj9oAPJEKNi6deucI8TgkU+elENzFsm+96fL/g8/k+O7TqXLguaYWq+m5G98gRRoeoH6nadCOUNzjtRo0+29Ze87H2b5c75G50npvj2l0DXRI0yQUQZHWBx7Fy9ebHk+ODpfeOGFsnTpUtUHjCtTpkzJ1B8s19OmTVP/r1evXjJixAjL4+kHGzRoIEuWLFHHdBhaKO4gQEKMI+4oUgQSg+8ZPgBarrzySqVljB8/Xm6//faoM4I7CbRKfChxB+mYhpjNyChdcGj2Ajk0a74cnr84cOeIR/KcUVbyN2ko+RueI6npdSXfufVMxVFvuKFrwCUo3BQKtmwmpfr1UqUTIgky2MBK++STT8pTTz0VFcPsGoQenYPddyZPnizt2rVTj6OQPNpC07crmPOAAQPU1Qm0VIo7CJAQ44g7sibjSIT7w9KlTxssEMaFcC5ojdAesxN9XIO7B/ztcGyOByEGzynjxAk5umSFHPp2gRz6ZoEcnv+9nDxyNNO081auIGnpdSU1vY6k1a+j/o3/F07WteogB7+cHXUnitx4jZTq00PSzj0rS1vc5+Fez+zVQ6RBQa4gWcgZZ5yhjs7QHhEBg2sKCJy+4fzthOAuGWUHkLx27NixTnTJPiwgQEK0AJqVR0Bk+mj8999/S968eQPdDBkyRJBqHkaW6dOnR+xeWzZxfwXixF2ZG4QYboKHF/6giPHo4uVyZPEyObZxS5ZmOVJTJLXOmYoY4d6TUq2SpFSvIn/0HSRHvjt1RDUixe+8Rd0xIvJGi9aynTpyhh6d+/fvL7i3xbUHBBodtFGnRB/54QOp/Rqd6pv9GEeAhGgcK1stZ82aJZdddpnqA8QWLNpiWadOHeWKE0mQHWXkyJHqriktLc1ThBg6Z4QNguSOLPxBjny/TI4s/lFO7D9lhAiVHMDEArol7++mXHVylyyurMM4vqKCXv369S30lvWRn376Sc4+++wsfzj33HNl0aJFkidPHkfGQSfLli1Tlfow3vLlyx3rlx2ZQ4CEaA4vy63hr4bLclguoWkEy+jRowVFji655BJVCD2cwK0Dsa9IS3/WWaeOjF7SEI0AA8MMimP9s+UPOYbf//7smzZDMkKO3Eb6Q5ucaanKVeesVwbLrt27slxHGO0nUrvnnntORZEEC/YCWrqTgmM4rlFKlCghO3fudLJr9mUCARKiCbDsNIXmAs0CEqohausz0tzDJy1UEFoGIwwu7xFipmXLli3ywAMPqMt9fHBxpxhsrLEz33g+u7pKQzm2aavlIfOULin1t/8k/5w8IXBtSklJsdxX6IPwAjjvvPMCDtuxqouCaxR4GEDrhFsWxR0ESIhxwh3f+nDghcCwAp8zLf369VMlMeGTCE0xVFDv14glE644wTWG47Q028OsLHWWnNi913Q/KK5VvEsHKdb5ZhVCh1A6uCE5XQsZSVyRbBaCozI0dacFNaLxxYZwQbhfUdxBgIQYR9wvvvhiQezqvHnzMlV7Q+QKjAH4W5MmTcJqiDhyh2qW0BDxYYXlEymv8GEKd+cVxyVaGuqnAtXl5NG/DD8L5/DiXdtLgeansYL7EcgKVwoXXXSR4b6MNIwHIeqoI/hALly40Mi02CYGCJAQYwBqpC4Rq4pQMCQS0NEQCOiHdlO4cGF1J6iPe7hnhGaIDCqRJNHuEMOtI+PkSVmRJ/skCnguV7EiUrxLeynWpYOyTocKCjfBXxB+gjfccIOjuxoPQoTz94033qjSgemCWI4ugp0ZQoCEaAgmZxqdOHFCRT7A4oyjHS7Q4W4Dt5tPPvlERVpAcA+G4zWO1oiYgPUxnCQDISKpxE+Fa0YEGD6Hp4iwveTIlStiO0SMwAKPEp/B96xO7Fw8CBHRLrhD7tmzp7z66qtOTJt9WECAhGgBNDuPINYWGVlwLAIh4m7wiSeeUD6IWo4ePaosjiDE0KiW4LFBqojZzc46bWeu8Xj2n+075edyWQm/SNurpFjXDoIoFSOCO1jcxcJBGyU/nZR4EGLnzp2VQzaMY/iSpLiDAAnRHdxV7rvdu3eroP5wAjcMtKlZM7L25NLUHR322PpNsrr6qTs/5GWEJgiN0GxexpUrVyp3JGjWKPPppMSDEPEFiD2H72O9evWcnD77MoEACdEEWGzqPAJ/rfpNNt3a818i7CA5Uk5H8JgdDUQCx/avv/5amjdvbvbxiO1jTYjwPcV8kQkJxE5xDwESonvYc2QRVUMaBhMnRN/HwjcTVnenBHeS+l4PmXSQUcdJefDBB1UoZp8+fZT7FcU9BEiI7mHPkR1GQKfjxzUD8k0miiDqBckjzJY9SJT1JdI8SYiJtFuca1QEYJFHXHAsrM1RB7fQQFuXEX+NaCaKuwiQEN3Fn6M7jMCkSZPkpptuUv6bKO3pZBifw1MVhOsh3BLp4N5///1AnkWnx2F/xhEgIRrHii0TBIHLL79cGVacSBYbyyXrpLDIgvTVV1/Fcij2bRABEqJBoNgscRAAGYIUkSgBqbRq167tuckjYw5SliHvIshQp4bz3ER9NiESos823C/L1RX4kKkG8c1eOjrjqNy4cWP54YcfWGnPYy8kCdFjG8LpOIMAUmghUQbcZFADBXd0XhHcceKuE6nakOgjOHu6V+bo13mQEP268z5YN1xvoInt2bNHhfUNHjzY9VUj2SzC81DDGZqr04lmXV9ggk+AhJjgG8jpZ4+ArlWCVkaKeMUSTziMDx06VA3hVO2XWM7Xj32TEP246z5b86hRo6R79+5q1ddee6289dZbggqI8RKkckN5WV3LOVIi4HjNh+NERoCEyLfDFwjA8gxSQvVDxDyDFCOlVXMSEDhbY1zEKJcrV06NS4uykwg72xcJ0Vk82ZuHEUCafpATDBkQ1MPGnR7qLjstyGaOO0tUSoTAwAMydLq8gdPz9nt/JES/vwE+XD+SsGqiyp07tyLFRx99VBV5sitI7osi9yBDFKjSxIvktRTvI0BC9P4ecYYxQAA1nEFc2h0HTtzIWI76NvidXemG0Okg9A5GEmQ9x284W0PgXgOiTcQ6NzGAPCG6JCEmxDZxkrFCALkIQYyhoXPNmjWTGjVqSNmyZdXdH37w723btql7SP17zZo1Mnv27EzTQ5QMiPDSSy+N1bTZb4wQICHGCFh2m1gI4M5Pa3nQ9MwKNEutXcbiTtLsfNjeGgIkRGu48akkRuDw4cMqOQS0wGCNEEdjHKW11ojf+IFGmC9fviRGxD9LIyH6Z6+5UiJABKIgQELkK0IEiAAR+BcBEiJfBSJABIgACZHvABEgAkQgMwLUEPlGEAEiQASoIfIdIAJEgAhQQ+Q7QASIABEIiwCPzHwxiAARIAI8MvMdIAJEgAjwyMx3gAgQASLAIzPfASJABIhAdgjwDpHvBxEgAkSAd4h8B4gAESACvEPkO0AEiAAR4B0i3wEiQASIAO8Q+Q4QASJABAwgQKOKAZDYhAgQAX8gQEL0xz5zlUSACBhAgIRoACQ2IQJEwB8IkBD9sc9cJREgAgYQICEaAIlNiAAR8AcCJER/7DNXSQSIgAEESIgGQGITIkAE/IEACdEf+8xVEgEiYAABEqIBkNiECBABfyBAQvTHPnOVRIAIGECAhGgAJDYhAkTAHwiQEP2xz1wlESACBhAgIRoAiU2IABHwBwIkRH/sM1dJBIiAAQRIiAZAYhMiQAT8gQAJ0R/7zFUSASJgAAESogGQ2IQIEAF/IEBC9Mc+c5VEgAgYQICEaAAkNiECRMAfCJAQ/bHPXCURIAIGECAhGgCJTYgAEfAHAiREf+wzV0kEiIABBEiIBkBiEyJABPyBAAnRH/vMVRIBImAAARKiAZDYhAgQAX8gQEL0xz5zlUSACBhAgIRoACQ2IQJEwB8IkBD9sc9cJREgAgYQICEaAIlNiAAR8AcCJER/7DNXSQSIgAEESIgGQGITIkAE/IEACdEf+8xVEgEiYAABEqIBkNiECBABfyBAQvTHPnOVRIAIGECAhGgAJDYhAkTAHwiQEP2xz1wlESACBhAgIRoAiU2IABHwBwIkRH/sM1dJBIiAAQRIiAZAYhMiQAT8gQAJ0R/7zFUSASJgAAESogGQ2IQIEAF/IEBC9Mc+c5VEgAgYQICEaAAkNiECRMAfCJAQ/bHPXCURIAIGECAhGgCJTYgAEfAHAiREf+wzV0kEiIABBEiIBkBiEyJABPyBAAnRH/vMVRIBImAAARKiAZDYhAgQAX8gQEL0xz5zlUSACBhAgIRoACQ2IQJEwB8IkBD9sc9cJREgAgYQICEaAIlNiAAR8AcCJER/7DNXSQSIgAEE/g987dHWxlVmYgAAAABJRU5ErkJggg==\n", 27 | "text/plain": [ 28 | "" 29 | ] 30 | }, 31 | "execution_count": 1, 32 | "metadata": { 33 | "image/png": { 34 | "height": 150, 35 | "width": 200 36 | } 37 | }, 38 | "output_type": "execute_result" 39 | } 40 | ], 41 | "source": [ 42 | "from IPython import display\n", 43 | "display.Image('dag_pareto.png', width = 200, height = 150)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 2, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | "from mirror.nodes import *\n", 53 | "from mirror.edges import *\n", 54 | "from mirror.generator import Mirror\n", 55 | "import pandas as pd" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "### 1. Define the DAG and generate data" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 4, 68 | "metadata": {}, 69 | "outputs": [ 70 | { 71 | "name": "stdout", 72 | "output_type": "stream", 73 | "text": [ 74 | "G independet ['G']\n", 75 | "----------------------------------------\n", 76 | "\n", 77 | "U independet ['G', 'U']\n", 78 | "----------------------------------------\n", 79 | "\n", 80 | "X with parents\n", 81 | "----------------------------------------\n", 82 | "\n", 83 | "Y with parents\n", 84 | "----------------------------------------\n", 85 | "\n", 86 | "--> Generated data is saved to out/pareto/R1.csv \n", 87 | "\n", 88 | "\n" 89 | ] 90 | } 91 | ], 92 | "source": [ 93 | "# name of folder to save the synthetic data\n", 94 | "data_flag = \"pareto\"\n", 95 | "\n", 96 | "# size of the data\n", 97 | "total_n = 2000 \n", 98 | "\n", 99 | "# initialize nodes\n", 100 | "node_g = CategoricalNode(\"G\", {\"M\": 0.5, \"F\": 0.5}, sample_n=total_n)\n", 101 | "\n", 102 | "node_u = ParetoNode(\"U\", sample_n=total_n, shape=2.0, scale=1.0) # an unobserved pareto node\n", 103 | "node_x = ParetoNode(\"X\")\n", 104 | "node_y = ParetoNode(\"Y\")\n", 105 | "\n", 106 | "edge_g_x = CtoN(\"G\", \"X\", {\"M\": [\"Pareto\", 3.0, 1.0], \"F\": [\"Pareto\", 1.0, 1.0]})\n", 107 | "edge_g_y = CtoN(\"G\", \"Y\", {\"M\": [\"Pareto\", 3.0, 1.0], \"F\": [\"Pareto\", 2.0, 1.0]})\n", 108 | "\n", 109 | "edge_u_x = NtoNLinear(\"U\", \"X\")\n", 110 | "edge_x_y = NtoNLinear(\"X\", \"Y\")\n", 111 | "\n", 112 | "# define DAG\n", 113 | "nodes = [node_g, node_u, node_x, node_y]\n", 114 | "edge_relations = {\"X\": ([edge_g_x, edge_u_x], [0.2, 0.8]),\n", 115 | " \"Y\": ([edge_g_y, edge_x_y], [0.4, 0.6])}\n", 116 | "\n", 117 | "\n", 118 | "# generate data\n", 119 | "mirror = Mirror(seed=0)\n", 120 | "mirror.generate_csv(nodes, edge_relations)\n", 121 | "mirror.save_to_disc(\"out/\"+data_flag+\"/R1.csv\")\n", 122 | "\n", 123 | "print()" 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": null, 129 | "metadata": {}, 130 | "outputs": [], 131 | "source": [] 132 | } 133 | ], 134 | "metadata": { 135 | "kernelspec": { 136 | "display_name": "Python 3", 137 | "language": "python", 138 | "name": "python3" 139 | }, 140 | "language_info": { 141 | "codemirror_mode": { 142 | "name": "ipython", 143 | "version": 3 144 | }, 145 | "file_extension": ".py", 146 | "mimetype": "text/x-python", 147 | "name": "python", 148 | "nbconvert_exporter": "python", 149 | "pygments_lexer": "ipython3", 150 | "version": "3.7.9" 151 | } 152 | }, 153 | "nbformat": 4, 154 | "nbformat_minor": 4 155 | } 156 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MirrorDataGenerator 2 | 3 | mirrorGen is an open source tool to generate synthetic data based on a correlation DAG, which describes the relation among the columns in the data. It can be used to produce "dirty" data, mirroring various bias in real life, for different applications, such as classifications and rankings [1](https://arxiv.org/abs/2006.08688). 4 | 5 | ### Prerequisite for language 6 | 7 | Python 3: [Install Tutorial](https://installpython3.com/) 8 | 9 | 10 | ### Install MirrorDataGenerator 11 | 12 | Step 1 Download MirrorDataGenerator. 13 | 14 | Step 2 Unzip the downloaded source file and initiate the python environment. 15 | 16 | ```bash 17 | cd MirrorDataGenerator # go to the MirrorDataGenerator repository that is just downloaded 18 | python -m venv venv 19 | source venv/bin/activate # activate the environment for MirrorDataGenerator 20 | pip install -r requirements.txt 21 | ``` 22 | 23 | 24 | ### Usage of MirrorDataGenerator 25 | 26 | We prepared a [demo notebook](Demo_mirror_generator.ipynb) to showcase Mirror Data Generator. 27 | 28 | 29 | ### Methodology 30 | 31 | TBD. 32 | 33 | 34 | ### License 35 | 36 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 37 | 38 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 39 | 40 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 41 | -------------------------------------------------------------------------------- /dag_hiring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataResponsibly/MirrorDataGenerator/8d8d80d94442042cbded733e4b934d9fc688ddca/dag_hiring.png -------------------------------------------------------------------------------- /dag_pareto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataResponsibly/MirrorDataGenerator/8d8d80d94442042cbded733e4b934d9fc688ddca/dag_pareto.png -------------------------------------------------------------------------------- /mirror/edges.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | from bisect import bisect 4 | from mirror.nodes import CategoricalNode 5 | from mirror.nodes import GaussianNode, ParetoNode 6 | 7 | 8 | # Abstract base class for all nodes 9 | class Edge(): 10 | def __init__(self, parent_name, child_name): 11 | 12 | self.parent_name = parent_name 13 | self.child_name = child_name 14 | # self.weight = weight 15 | self.type = None 16 | self.relation = None 17 | 18 | def instantiate_values(self, input_df): 19 | raise NotImplementedError 20 | 21 | def get_type(self): 22 | return "Edge" 23 | 24 | class NtoNLinear(Edge): 25 | def __init__(self, parent_name, child_name): 26 | Edge.__init__(self, parent_name, child_name) 27 | self.type = "NtoN" 28 | self.relation = "linear" 29 | 30 | def instantiate_values(self, input_df): 31 | if input_df.shape[0] > 0: # use the values of its parent nodes to generate the values 32 | return np.array(input_df[self.parent_name]) 33 | else: # no parent data exits 34 | print("No parent data exits!") 35 | raise ValueError 36 | 37 | class NtoNNonLinear(Edge): 38 | def __init__(self, parent_name, child_name, threshold): 39 | Edge.__init__(self, parent_name, child_name) 40 | self.type = "NtoN" 41 | self.relation = "nonlinear" 42 | self.threshold = threshold 43 | 44 | def instantiate_values(self, input_df): # TODO: update 45 | raise NotImplementedError 46 | 47 | 48 | class NtoC(Edge): 49 | def __init__(self, parent_name, child_name, bounds, probabilities): 50 | """ 51 | :param parent_name: 52 | :param child_name: 53 | :param bounds: sorted list of numbers, the values specify the boundary of each range. 54 | E.g. [20, 45, 65] defines 4 ranges: [-, 20), [20, 45), [45, 65), [65, -) 55 | :param probabilities: list of dict, the order of the dict maps to the orders in the bounds. 56 | The dict stores the probabilities of each category for the child node when the value of the parent node is within the range. 57 | E.g. [{"Y": 0.2, "N": 0.8}, {"Y": 0.7, "N": 0.3}, {"Y": 0.6, "N": 0.4}, {"Y": 0.3, "N": 0.7}] 58 | """ 59 | Edge.__init__(self, parent_name, child_name) 60 | self.type = "NtoC" 61 | self.relation = "sample" 62 | self.bounds = bounds 63 | self.probabilities = probabilities 64 | self.probability_table = {str(x): probabilities[x] for x in np.arange(len(probabilities))} 65 | 66 | def instantiate_values(self, input_df): 67 | if input_df.shape[0] > 0: 68 | input_df[self.child_name] = input_df[self.parent_name].apply(lambda x: np.random.choice(list(self.probabilities[bisect(self.bounds, x)].keys()), p=list(self.probabilities[bisect(self.bounds, x)].values()))) 69 | return np.array(input_df[self.child_name]) 70 | else: # no parent data exits 71 | print("No parent data exits!") 72 | raise ValueError 73 | 74 | 75 | class CtoC(Edge): 76 | def __init__(self, parent_name, child_name, probability_table): 77 | """ 78 | :param parent_name: 79 | :param child_name: 80 | :param probability_table: dict, key is the categories from the child node, value is the set of the probability of its parent. 81 | E.g. {"M": {"Y": 0.7, "N": 0.3}, "F": {"Y": 0.3, "N": 0.7}} 82 | """ 83 | Edge.__init__(self, parent_name, child_name) 84 | self.type = "CtoC" 85 | self.relation = "sample" 86 | self.probability_table = probability_table 87 | 88 | def instantiate_values(self, input_df): 89 | if input_df.shape[0] > 0: 90 | input_df[self.child_name] = input_df[self.parent_name].apply(lambda x: np.random.choice(list(self.probability_table[x].keys()), p=list(self.probability_table[x].values()))) 91 | return np.array(input_df[self.child_name]) 92 | else: # no parent data exits 93 | print("No parent data exits!") 94 | raise ValueError 95 | 96 | 97 | class CtoN(Edge): 98 | def __init__(self, parent_name, child_name, category_distribution): 99 | """ 100 | :param parent_name: str, the name of the parent node 101 | :param child_name: str, the name of the node to be generated 102 | :param category_distribution: dict, {"M": ["Gaussian", 0, 1], "F": ["Gaussian", -1, 1]} 103 | """ 104 | 105 | Edge.__init__(self, parent_name, child_name) 106 | self.type = "CtoN" 107 | self.relation = "sample" 108 | self.category_distribution = category_distribution 109 | 110 | def sample_x(self, x): 111 | if self.category_distribution[x][0] == "Gaussian": # NUM 112 | return np.random.normal(self.category_distribution[x][1], np.sqrt(self.category_distribution[x][2])) 113 | elif self.category_distribution[x][0] == "Uniform": # NUM 114 | return np.random.uniform(self.category_distribution[x][1], self.category_distribution[x][2]) 115 | elif self.category_distribution[x][0] == "Pareto": # NUM 116 | return (np.random.pareto(self.category_distribution[x][1]) + 1) * self.category_distribution[x][2] 117 | else: # ORD 118 | return np.random.randint(self.category_distribution[x][1], self.category_distribution[x][2]) 119 | 120 | def instantiate_values(self, input_df): 121 | """ 122 | :param input_df: dataframe, the column with name self.parent_name stores the values of the parent code to be used in the generation 123 | :return: dataframe, the edge is instantiated by adding the column with name self.child_name 124 | """ 125 | if input_df.shape[0] > 0: # use the values of its parent nodes to generate the values 126 | input_df[self.child_name] = input_df[self.parent_name].apply(lambda x: self.sample_x(x)) 127 | return np.array(input_df[self.child_name]) 128 | else: # no parent data exits 129 | print("No parent data exits!") 130 | raise ValueError 131 | 132 | if __name__ == '__main__': 133 | node_g = CategoricalNode("G", {"M": 0.5, "F": 0.5}, sample_n=100) 134 | 135 | # node_g_m = GaussianNode("M_X", miu=0, var=1) 136 | # node_g_f = GaussianNode("F_X", miu=0, var=1) 137 | 138 | df = pd.DataFrame() 139 | df["G"] = node_g.instantiate_values() 140 | 141 | # df["tmp"] = [1 for _ in range(df.shape[0])] 142 | # df["A"] = np.random.randint(1, 80, size=1000) 143 | 144 | edge_g_x = CtoN("G", "X", {"M": ["Gaussian", 3.0, 1.0], "F": ["Gaussian", 2.0, 1.0]}) 145 | df["X"] = edge_g_x.instantiate_values(df) 146 | 147 | print(df.groupby(by=['G'])['X'].mean()) 148 | print(df.groupby(by=['G'])['X'].var()) 149 | 150 | print(len(df), np.mean(df["X"]), np.var(df["X"])) 151 | 152 | 153 | # print(df[df["G"]=="M"].shape[0], df[df["G"]=="F"].shape[0]) 154 | # edge_g_x = CtoN("G", "X", {"M": ["Gaussian", 0, 1], "F": ["Gaussian", -1, 1]}) 155 | # df["X"] = edge_g_x.instantiate_values(df) 156 | # print(len(df), np.mean(df["X"]), np.var(df["X"])) 157 | 158 | # m_df = df[df["G"] == "M"] 159 | # f_df = df[df["G"] == "F"] 160 | # print("M", len(m_df), np.mean(m_df["X"]), np.var(m_df["X"])) 161 | # print("F", len(f_df), np.mean(f_df["X"]), np.var(f_df["X"])) 162 | 163 | # edge_g_d = CtoC("G", "D", {"M": {"Y": 0.7, "N": 0.3}, "F": {"Y": 0.3, "N": 0.7}}) 164 | # df["D"] = edge_g_d.instantiate_values(df) 165 | # print(df.groupby(by=["G","D"]).count()/500) 166 | 167 | # edge_g_d = NtoC("A", "D", [25, 45, 65], [{"Y": 0.2, "N": 0.8}, {"Y": 0.7, "N": 0.3}, {"Y": 0.6, "N": 0.4}, {"Y": 0.3, "N": 0.7}]) 168 | # print(edge_g_d.probability_table) 169 | # df["D"] = edge_g_d.instantiate_values(df) 170 | # 171 | # for range_i in [[1, 25], [25, 45], [45, 65], [65, 100]]: 172 | # cur_df = df[(df["A"] < range_i[1]) & (df["A"] >= range_i[0])] 173 | # print(range_i) 174 | # print(cur_df[["D", "tmp"]].groupby(by=["D"]).count()/cur_df.shape[0]) 175 | # print("\n\n") 176 | 177 | # print(edge_g_d.get_type()) 178 | 179 | -------------------------------------------------------------------------------- /mirror/erasers.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | class Eraser: 4 | def __init__(self, columns, fraction, replace_values): 5 | """ 6 | :param columns: list of str, names of the columns to be considered 7 | :param fraction: float, ratio of the data to be erased 8 | :param replace_values: dict, key is str, representing the name of a column, same as in columns. value is str, representing the value to be put in for the column. 9 | """ 10 | if not columns: 11 | print('columns need to be non-empty.') 12 | raise ValueError 13 | if not fraction or type(fraction) != float: 14 | print('fraction need to be non-empty and float.') 15 | raise ValueError 16 | elif fraction > 1 or fraction <= 0: 17 | print('fraction need in the range (0, 1].') 18 | raise ValueError 19 | if not replace_values: 20 | print('replace_values need to be non-empty.') 21 | raise ValueError 22 | elif len(set(columns).difference(replace_values.keys())) > 0: 23 | print('replace_values need to have the key set as columns.') 24 | raise ValueError 25 | self.columns = columns 26 | self.fraction = fraction 27 | self.replace_values = replace_values 28 | 29 | def transform(self, data): 30 | raise NotImplementedError 31 | 32 | 33 | class MCAR_eraser(Eraser): 34 | 35 | def __init__(self, columns, fraction, replace_values, seed=0): 36 | Eraser.__init__(self, columns, fraction, replace_values) 37 | self.pattern = 'MCAR' 38 | self.seed = seed 39 | def transform(self, data): 40 | np.random.seed(self.seed) 41 | corrupted_data = data.copy(deep=True) 42 | missing_indices = np.random.rand(len(data)) < self.fraction 43 | 44 | for coli in self.columns: # record the original value 45 | corrupted_data['orig_' + coli] = corrupted_data[coli] 46 | corrupted_data.loc[missing_indices, [coli]] = self.replace_values[coli] 47 | 48 | corrupted_data['perturb_index'] = missing_indices 49 | 50 | return corrupted_data 51 | 52 | 53 | class MAR_eraser(): 54 | def __init__(self, columns, fraction, replace_values, depends_on_cols, depends_on_orders=None, seed=0): 55 | Eraser.__init__(self, columns, fraction, replace_values) 56 | if len(columns) != len(depends_on_cols): 57 | print('depends_on_cols need to have the same length as columns.') 58 | raise ValueError 59 | if depends_on_orders: 60 | if set(depends_on_orders.keys()).difference(depends_on_cols): 61 | print('depends_on_orders need to have the key set same as depends_on_cols.') 62 | raise ValueError 63 | self.depends_on_cols = depends_on_cols 64 | self.depends_on_orders = depends_on_orders 65 | self.pattern = 'MAR' 66 | self.seed = seed 67 | 68 | def transform(self, data): 69 | np.random.seed(self.seed) 70 | corrupted_data = data.copy(deep=True) 71 | n_values_to_discard = int(len(data) * min(self.fraction, 1.0)) 72 | if n_values_to_discard == len(data): 73 | perc_lower_start = 0 74 | else: 75 | perc_lower_start = np.random.randint(0, len(data) - n_values_to_discard) 76 | perc_idx = range(perc_lower_start, perc_lower_start + n_values_to_discard) 77 | 78 | if self.depends_on_orders: # auto-fill zero for the non-specified categories 79 | for coli, value_dicti in self.depends_on_orders.items(): 80 | if type(value_dicti) == dict: 81 | for vi in set(corrupted_data[coli].unique()).difference(value_dicti.keys()): 82 | self.depends_on_orders[coli].update({vi: 0}) 83 | corrupted_data[coli + '_ordered'] = corrupted_data[coli].apply(lambda x: self.depends_on_orders[coli][x]) 84 | else: 85 | corrupted_data[coli + '_ordered'] = corrupted_data[coli].apply(lambda x: x * self.depends_on_orders[coli]) 86 | 87 | missing_indices = corrupted_data.sort_values(by=[x+'_ordered' if x in self.depends_on_orders else x for x in self.depends_on_cols], ascending=False).iloc[perc_idx].index 88 | corrupted_data.drop(columns=[x+'_ordered' for x in self.depends_on_orders], inplace=True) 89 | 90 | for coli in self.columns: # record the original value 91 | corrupted_data["orig_" + coli] = corrupted_data[coli] 92 | corrupted_data.loc[missing_indices, [coli]] = self.replace_values[coli] 93 | 94 | corrupted_data["perturb_index"] = False 95 | corrupted_data.loc[missing_indices, ["perturb_index"]] = True 96 | 97 | return corrupted_data 98 | 99 | 100 | 101 | class NMAR_eraser(): 102 | def __init__(self, columns, fraction, replace_values, depends_on_orders=None, seed=0): 103 | Eraser.__init__(self, columns, fraction, replace_values) 104 | if depends_on_orders: 105 | if len(depends_on_orders) > len(columns): 106 | if sum([x not in depends_on_orders for x in columns]) > 0: 107 | print('depends_on_orders need to have the key set same as columns.') 108 | raise ValueError 109 | self.depends_on_orders = depends_on_orders 110 | self.pattern = 'NMAR' 111 | self.seed = seed 112 | 113 | def transform(self, data): 114 | np.random.seed(self.seed) 115 | corrupted_data = data.copy(deep=True) 116 | n_values_to_discard = int(len(data) * min(self.fraction, 1.0)) 117 | if n_values_to_discard == len(data): 118 | perc_lower_start = 0 119 | else: 120 | perc_lower_start = np.random.randint(0, len(data) - n_values_to_discard) 121 | perc_idx = range(perc_lower_start, perc_lower_start + n_values_to_discard) 122 | 123 | if self.depends_on_orders: # auto-fill zero for the non-specified categories 124 | for coli, value_dicti in self.depends_on_orders.items(): 125 | if type(value_dicti) == dict: 126 | for vi in set(corrupted_data[coli].unique()).difference(value_dicti.keys()): 127 | self.depends_on_orders[coli].update({vi: 0}) 128 | corrupted_data[coli + '_ordered'] = corrupted_data[coli].apply(lambda x: self.depends_on_orders[coli][x]) 129 | else: 130 | corrupted_data[coli + '_ordered'] = corrupted_data[coli].apply(lambda x: x*self.depends_on_orders[coli]) 131 | 132 | missing_indices = corrupted_data.sort_values(by=[x+'_ordered' if x in self.depends_on_orders else x for x in self.columns], ascending=False).iloc[perc_idx].index 133 | corrupted_data.drop(columns=[x+'_ordered' for x in self.depends_on_orders], inplace=True) 134 | 135 | for coli in self.columns: # record the original value 136 | corrupted_data["orig_" + coli] = corrupted_data[coli] 137 | corrupted_data.loc[missing_indices, [coli]] = self.replace_values[coli] 138 | 139 | corrupted_data["perturb_index"] = False 140 | corrupted_data.loc[missing_indices, ["perturb_index"]] = True 141 | 142 | return corrupted_data -------------------------------------------------------------------------------- /mirror/generator.py: -------------------------------------------------------------------------------- 1 | import os, pathlib 2 | from mirror.nodes import * 3 | from mirror.edges import * 4 | from bisect import bisect 5 | 6 | class Mirror(): 7 | def __init__(self, seed=0): 8 | self.seed = seed 9 | np.random.seed(seed) 10 | self.df = None 11 | self.cat_cols = [] 12 | self.num_cols = [] 13 | 14 | def generate_csv(self, nodes, edges): 15 | """ 16 | :param nodes: list of Node object. The order represents the order to generate the nodes. 17 | E.g. [CategoricalNode("G", [], [], {"M": 0.5, "F": 0.5}, sample_n=100), 18 | CategoricalNode("R", [], [], {"W": 0.5, "B": 0.5}, sample_n=100), 19 | OrdinalLocalNode("X", [], [], {"bound": [1, 5, 50], "probability": [0.5, 0.5]}, sample_n=100)] 20 | :param edges: dict, key is the name of the Node object, value is Edge object that represents the incoming edges and its weight for this node. 21 | E.g. {"X": ([CtoN("G", "X"), CtoN("R", "X")], [0.5, 0.5])} for NUM and ORD, 22 | {"D": [CtoC("G", "D"), NtoC("A", "D")]} for CAT with multiple parents, 23 | {"D": CtoC("G", "D")} for CAT with single parent 24 | :return: 25 | """ 26 | df = pd.DataFrame() 27 | for node_i in nodes: 28 | if node_i.type == "NUM": 29 | self.num_cols.append(node_i.name) 30 | else: 31 | self.cat_cols.append(node_i.name) 32 | if node_i.name in edges.keys(): # have parents 33 | print(node_i.name, "with parents") 34 | # iterate the incoming edges from its parents 35 | if type(edges[node_i.name]) not in [tuple, list]: # only have one parent node 36 | if edges[node_i.name].parent_name not in df.columns: 37 | print("The parent is not exited!") 38 | raise ValueError 39 | df[node_i.name] = edges[node_i.name].instantiate_values(df) 40 | print("One parent", edges[node_i.name], list(df.columns)) 41 | else: # have more than one parent node, update the inputs probability table based on its parents 42 | if type(edges[node_i.name]) == tuple: 43 | parents_i = [x.parent_name for x in edges[node_i.name][0]] 44 | else: 45 | parents_i = [x.parent_name for x in edges[node_i.name]] 46 | if len(set(parents_i).intersection(df.columns)) != len(parents_i): 47 | print("Some parents are not exited!") 48 | raise ValueError 49 | if node_i.type == "CAT": # current node is CAT 50 | df["group"] = "" # get all the possible subgroups from all the parents' categories 51 | for incoming_edge_i, weight_i in zip(edges[node_i.name][0], edges[node_i.name][1]): 52 | # print("---", node_i.name, incoming_edge_i.parent_name, incoming_edge_i.child_name) 53 | if incoming_edge_i.type[0] == "N": # get the categories of the numerical node 54 | # print("**", incoming_edge_i.bounds, bisect(incoming_edge_i.bounds, 23)) 55 | df["C_"+incoming_edge_i.parent_name] = df[incoming_edge_i.parent_name].apply(lambda x: str(bisect(incoming_edge_i.bounds,x))) 56 | df["group"] += df["C_"+incoming_edge_i.parent_name] 57 | else: 58 | df["group"] += df[incoming_edge_i.parent_name] 59 | # compute the new probability table for the child node considering all possible subgroups 60 | all_cpt = {} 61 | for gi in df["group"].unique(): 62 | gi_probability = {} 63 | for node_value_i in node_i.domain: 64 | prob_i = 0 65 | for incoming_edge_i, weight_i in zip(edges[node_i.name][0], edges[node_i.name][1]): 66 | gi_idx = edges[node_i.name][0].index(incoming_edge_i) 67 | prob_i += weight_i * incoming_edge_i.probability_table["".join(gi)[gi_idx]][node_value_i] 68 | # for gi_idx, parent_i in enumerate(edges[node_i.name][0]): 69 | # prob_i *= parent_i.probability_table["".join(gi)[gi_idx]][node_value_i] 70 | gi_probability[node_value_i] = prob_i 71 | # all_cpt["".join(gi)] = {x: gi_probability[x]/sum(gi_probability.values()) for x in gi_probability} 72 | all_cpt["".join(gi)] = {x: gi_probability[x] for x in gi_probability} 73 | # print("New CPT", all_cpt, "\n") 74 | # sample the value of the child node using above new cpt table 75 | df[node_i.name] = df["group"].apply(lambda x: np.random.choice(list(all_cpt[x].keys()), p=list(all_cpt[x].values()))) 76 | # print("Child node is CAT", list(df.columns)) 77 | else: # the child node is NUM or ORD 78 | df[node_i.name] = 0 79 | for incoming_edge_i, weight_i in zip(edges[node_i.name][0], edges[node_i.name][1]): 80 | values_i = incoming_edge_i.instantiate_values(df) 81 | df[node_i.name] = df[node_i.name] + weight_i * values_i 82 | # print("Child node is numerical", list(df.columns)) 83 | 84 | else: # no parents 85 | # instantiate using its parameters 86 | df[node_i.name] = node_i.instantiate_values() 87 | print(node_i.name, "independet", list(df.columns)) 88 | print("----"*10+"\n") 89 | self.df = df 90 | # return self.df 91 | 92 | 93 | def save_to_disc(self, file_name_with_path, excluded_cols=[], shorten_num_cols=True): 94 | if not os.path.exists(file_name_with_path): 95 | directory = os.path.dirname(file_name_with_path) 96 | pathlib.Path(directory).mkdir(parents=True, exist_ok=True) 97 | if shorten_num_cols: 98 | self.df[self.num_cols] = self.df[self.num_cols].round(3) 99 | if excluded_cols: 100 | self.df.drop(columns=excluded_cols).to_csv(file_name_with_path, index=False) 101 | else: 102 | self.df.to_csv(file_name_with_path, index=False) 103 | print('--> Generated data is saved to ', file_name_with_path, '\n') 104 | 105 | 106 | if __name__ == '__main__': 107 | # initialize nodes 108 | total_n = 100 109 | node_g = CategoricalNode("G", {"M": 0.5, "F": 0.5}, sample_n=total_n) 110 | 111 | node_u = ParetoNode("U", sample_n=total_n, shape=2.0, scale=1.0) # an unobserved pareto node 112 | node_x = ParetoNode("X") 113 | node_y = ParetoNode("Y") 114 | 115 | edge_g_x = CtoN("G", "X", {"M": ["Pareto", 3.0, 1.0], "F": ["Pareto", 1.0, 1.0]}) 116 | edge_g_y = CtoN("G", "Y", {"M": ["Pareto", 3.0, 1.0], "F": ["Pareto", 2.0, 1.0]}) 117 | 118 | edge_u_x = NtoNLinear("U", "X") 119 | edge_x_y = NtoNLinear("X", "Y") 120 | 121 | # define DAG 122 | nodes = [node_g, node_u, node_x, node_y] 123 | edge_relations = {"X": ([edge_g_x, edge_u_x], [0.5, 0.5]), 124 | "Y": ([edge_g_y, edge_x_y], [0.4, 0.6])} 125 | 126 | mirror = Mirror(seed=0) 127 | mirror.generate_csv(nodes, edge_relations) 128 | mirror.save_to_disc("../out/synthetic_data/test/R_pareto.csv") 129 | 130 | 131 | 132 | # node_g = CategoricalNode("G", {"M": 0.5, "F": 0.5}, sample_n=total_n) 133 | # node_r = CategoricalNode("R", {"W", "B"}) 134 | # 135 | # node_a = OrdinalGlobalNode("A", min=20, max=70) 136 | 137 | # node_x = GaussianNode("X") 138 | # node_y = GaussianNode("Y") 139 | 140 | # initialize edges 141 | # edge_g_r = CtoC("G", "R", {"M": {"W": 0.635, "B": 0.365}, "F": {"W": 0.622, "B": 0.378}}) 142 | # 143 | # edge_r_a = CtoN("R", "A", {"W": ["Gaussian", 30, 10], "B": ["Gaussian", 45, 10]}) 144 | # 145 | # edge_g_x = CtoN("G", "X", {"M": ["Gaussian", 0, 0.5], "F": ["Gaussian", -1, 1]}) 146 | # 147 | # 148 | # edge_r_x = CtoN("R", "X", {"W": ["Gaussian", 0, 0.5], "B": ["Gaussian", -1, 1]}) 149 | # 150 | # edge_a_x = CtoN("G", "X", {"M": ["Gaussian", 0, 1], "F": ["Gaussian", -1, 1]}) 151 | # 152 | # 153 | # 154 | # 155 | # edge_g_y = CtoN("G", "Y", {"M": ["Gaussian", 0, 0.5], "F": ["Gaussian", -1, 1]}) 156 | # edge_r_y = CtoN("R", "Y", {"W": ["Gaussian", 0, 0.5], "B": ["Gaussian", -1, 1]}) 157 | # 158 | # edge_x_y = NtoNLinear("X", "Y") 159 | 160 | # define DAG 161 | # nodes = [node_g, node_r, node_x, node_y] 162 | # edge_relations = {"X": ([edge_g_x, edge_r_x], [0.5, 0.5]), 163 | # "Y": ([edge_g_y, edge_r_y, edge_x_y], [0.2, 0.2, 0.6])} 164 | 165 | # mirror = Mirror(seed=0) 166 | # mirror.generate_csv(nodes, edge_relations) 167 | # mirror.save_to_disc("../out/synthetic_data/test/R_pareto.csv") 168 | 169 | 170 | 171 | 172 | # total_n = 100000 173 | # 174 | # # initialize nodes 175 | # node_g = CategoricalNode("G", {"M": 0.5, "F": 0.5}, sample_n=total_n) 176 | # node_r = CategoricalNode("R", {"W": 0.5, "B": 0.5}, sample_n=total_n) 177 | # node_a = OrdinalGlobalNode("A", sample_n=total_n, min=15, max=80) 178 | # 179 | # node_d = CategoricalNode("D", {"Y": 0.5, "N": 0.5}) 180 | # 181 | # # initialize edges 182 | # # edge_g_x = CtoN("G", "X", {"M": ["Gaussian", 0, 1], "F": ["Gaussian", -1, 1]}) 183 | # # edge_r_x = CtoN("R", "X", {"W": ["Gaussian", 0, 1], "B": ["Gaussian", -1, 1]}) 184 | # 185 | # edge_g_d = CtoC("G", "D", {"M": {"Y": 0.7, "N": 0.3}, "F": {"Y": 0.3, "N": 0.7}}) 186 | # edge_r_d = CtoC("R", "D", {"W": {"Y": 0.7, "N": 0.3}, "B": {"Y": 0.3, "N": 0.7}}) 187 | # 188 | # # edge_a_d = NtoC("A", "D", [25, 45, 65], [{"Y": 0.2, "N": 0.8}, {"Y": 0.7, "N": 0.3}, {"Y": 0.6, "N": 0.4}, {"Y": 0.3, "N": 0.7}]) 189 | # edge_a_d = NtoC("A", "D", [45], [{"Y": 0.7, "N": 0.3}, {"Y": 0.3, "N": 0.7}]) 190 | # # define DAG 191 | # nodes = [node_g, node_r, node_a, node_d] 192 | # edge_relations = {"D": [edge_g_d, edge_r_d, edge_a_d]} 193 | # 194 | # # nodes = [node_g, node_r, node_d] 195 | # # edge_relations = {"D": [edge_g_d, edge_r_d]} 196 | # 197 | # mirror = Mirror(seed=0) 198 | # mirror.generate_csv(nodes, edge_relations) 199 | # 200 | # # mirror.save_to_disc("../out/test/R1.csv") 201 | # print(mirror.df.columns) 202 | # test_df = mirror.df.copy() 203 | # test_df["GRA"] = test_df["G"] + test_df["R"] + test_df["C_A"] 204 | # test_df["All"] = test_df["G"] + test_df["R"] + + test_df["C_A"] + test_df["D"] 205 | # # test_df["All"] = test_df["G"] + test_df["D"] 206 | # 207 | # print (test_df["GRA"].value_counts(normalize=True)) 208 | # print (test_df["All"].value_counts(normalize=True)) 209 | # # print(mirror.df[["group", "D", "A"]].groupby(by=["group", "D"]).count()) -------------------------------------------------------------------------------- /mirror/nodes.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | # Abstract base class for all nodes 3 | 4 | # Support data type and node type mapping 5 | DATA_TYPE_MAP = {"NUM": float, "ORD": int, "CAT": str} 6 | class Node(): 7 | def __init__(self, name, type, sample_n): 8 | """ 9 | :param name: str, the name of the column that is instantiated from the node 10 | :param type: str, the type of the node 11 | :param sample_n: int, size of the instantiated samples 12 | """ 13 | self.name = name 14 | self.type = type 15 | self.sample_n = sample_n 16 | self.value_type = DATA_TYPE_MAP[type] # the type of values for the node 17 | 18 | # parameters updated by each children node 19 | self.domain = None # set that stores the range of the possible values for the node. ONLY for CAT and ORD nodea 20 | self.distribution = None # str, the name of the distribution that the node is sampled from 21 | self.parameters = None # dict that stores all the necessary parameters for the node distribution. E.g. for GaussianNode, {"miu": 0, "var": 1} and for UniformNode, {"min": 0, "max": 1} 22 | 23 | def instantiate_values(self): 24 | raise NotImplementedError 25 | 26 | def get_type(self): 27 | return "Node" 28 | 29 | class ParetoNode(Node): 30 | # TODO: update edges for ParetoNode 31 | def __init__(self, name, sample_n=2000, shape=1.0, scale=1.0): 32 | """ 33 | :param name: str, the name of the column that is instantiated from this node 34 | :param sample_n: int, size of the instantiated samples 35 | :param shape: float, shape of the Pareto distribution. Must be positive. The parameter a in numpy.random.pareto. 36 | :param scale: float, scale of the Pareto distribution. Must be positive. The parameter m in numpy.random.pareto. 37 | """ 38 | Node.__init__(self, name, "NUM", sample_n) 39 | self.distribution = "Pareto" 40 | self.parameters = {"shape": shape, "scale": scale} 41 | 42 | def instantiate_values(self): 43 | return (np.random.pareto(self.parameters["shape"], self.sample_n) + 1) * self.parameters["scale"] 44 | 45 | 46 | 47 | # Classes of different types of Nodes 48 | class GaussianNode(Node): 49 | 50 | def __init__(self, name, sample_n=2000, miu=0, var=1): 51 | """ 52 | :param name: str, the name of the column that is instantiated from this node 53 | :param sample_n: int, size of the instantiated samples 54 | :param miu: float, the mean value of the node's distribution 55 | :param var: float, the variance value of the node's distribution 56 | """ 57 | Node.__init__(self, name, "NUM", sample_n) 58 | self.distribution = "Gaussian" 59 | self.parameters = {"miu": miu, "var": var} 60 | 61 | def instantiate_values(self): 62 | return np.random.normal(self.parameters["miu"], np.sqrt(self.parameters["var"]), self.sample_n) 63 | 64 | 65 | 66 | class UniformNode(Node): 67 | def __init__(self, name, sample_n=2000, min=0, max=1): 68 | """ 69 | :param name: str, the name of the column that is instantiated from this node 70 | :param sample_n: int, size of the instantiated samples 71 | :param min: int, the minimal value of the node 72 | :param max: int, the maximal value of the node 73 | """ 74 | Node.__init__(self, name, "NUM", sample_n) 75 | self.distribution = "Uniform" 76 | self.parameters = {"min": min, "max": max} 77 | 78 | def instantiate_values(self): 79 | return np.random.uniform(self.parameters["min"], self.parameters["max"], self.sample_n) 80 | 81 | class OrdinalGlobalNode(Node): 82 | def __init__(self, name, sample_n=2000, min=1, max=100): 83 | """ 84 | :param name: str, the name of the column that is instantiated from this node 85 | :param sample_n: int, size of the instantiated samples 86 | :param min: int, the minimal value of the node 87 | :param max: int, the maximal value of the node 88 | """ 89 | Node.__init__(self, name, "ORD", sample_n) 90 | self.domain = [min, max] 91 | self.distribution = "OrdinalGlobal" 92 | self.parameters = {"min": min, "max": max} 93 | 94 | def instantiate_values(self): 95 | return np.random.randint(self.parameters["min"], self.parameters["max"], size=self.sample_n) 96 | 97 | 98 | class OrdinalLocalNode(Node): 99 | def __init__(self, name, parameters, sample_n=2000): 100 | """ 101 | :param name: str, the name of the column that is instantiated from this node 102 | :param parameters: dict, {"bound": [1, 45, 100], "probability": [0.5, 0.5]}} 103 | :param sample_n: int, size of the instantiated samples 104 | """ 105 | Node.__init__(self, name, "ORD", sample_n) 106 | self.domain = [min(parameters["bound"]), max(parameters["bound"])] 107 | self.distribution = "OrdinalLocal" 108 | self.parameters = parameters 109 | 110 | def instantiate_values(self): 111 | res = np.random.choice(len(self.parameters["probability"]), self.sample_n, p=self.parameters["probability"]) 112 | res = [(self.parameters['bound'][i], self.parameters['bound'][i+1]) for i in res] 113 | return np.array([np.random.randint(*i) for i in res]) 114 | 115 | 116 | class CategoricalNode(Node): 117 | def __init__(self, name, parameters, sample_n=2000): 118 | """ 119 | :param name: str, the name of the column that is instantiated from this node 120 | :param parameters: dict, values of the node and its population {"M": 0.5, "F": 0.5}} 121 | :param sample_n: int, size of the instantiated samples 122 | """ 123 | Node.__init__(self, name, "CAT", sample_n) 124 | self.domain = sorted(parameters) 125 | self.distribution = "Multinomial" 126 | self.parameters = parameters 127 | 128 | 129 | def instantiate_values(self): 130 | domain_prob = [self.parameters[x] for x in self.domain] 131 | return np.random.choice(self.domain, self.sample_n, p=domain_prob) 132 | 133 | if __name__ == '__main__': 134 | # node_g = CategoricalNode("G", {"M": 0.5, "F": 0.5}, sample_n=100) 135 | # res = node_g.instantiate_values() 136 | # print(len(res), len([x for x in res if x == "M"]), len([x for x in res if x == "F"])) 137 | 138 | 139 | 140 | # node_x_non_linear = OrdinalLocalNode("X", {"bound": [1, 5, 50], "probability": [0.5, 0.5]}, sample_n=100) 141 | # res = node_x_non_linear.instantiate_values() 142 | # print(len(res), len([x for x in res if x < 5]), len([x for x in res if x < 50 and x >=5])) 143 | 144 | # node_x_linear = OrdinalGlobalNode("X", sample_n=100, min=1, max=100) 145 | # res = node_x_linear.instantiate_values() 146 | # print(len(res), len([x for x in res if x < 50]), len([x for x in res if x >= 50])) 147 | 148 | # node_y = UniformNode("Y", sample_n=100) 149 | # res = node_y.instantiate_values() 150 | # print(len(res), len([x for x in res if x < 0.5]), len([x for x in res if x >= 0.5])) 151 | 152 | # node_z = GaussianNode("Z", sample_n=100, miu=0, var=1) 153 | # res = node_z.instantiate_values() 154 | # print(len(res), len([x for x in res if x < 0]), len([x for x in res if x >= 0])) 155 | 156 | node_z = ParetoNode("X", sample_n=100, shape=2.0, scale=1.0) 157 | res = node_z.instantiate_values() 158 | # print(res) 159 | print(len(res), len([x for x in res if x < 1.0]), len([x for x in res if x >= 1.0])) 160 | -------------------------------------------------------------------------------- /out/pareto/R1.csv: -------------------------------------------------------------------------------- 1 | G,U,X,Y 2 | M,2.303,3.189,3.551 3 | M,1.382,2.691,3.302 4 | M,1.448,2.419,3.505 5 | M,1.155,2.309,3.287 6 | F,1.591,2.54,2.976 7 | M,1.198,2.365,2.901 8 | F,1.538,2.585,3.003 9 | M,1.097,2.458,2.891 10 | M,1.091,2.562,3.842 11 | F,1.31,94.01,60.032 12 | M,1.321,2.347,3.083 13 | M,1.169,2.232,5.788 14 | M,1.073,4.062,5.157 15 | M,1.02,3.153,4.591 16 | F,1.013,3.936,4.121 17 | F,1.172,8.504,11.655 18 | F,1.363,2.609,4.359 19 | M,1.911,3.923,3.973 20 | M,1.38,3.457,4.986 21 | M,3.228,3.902,3.743 22 | M,1.018,2.335,3.258 23 | M,1.105,3.792,4.064 24 | F,1.23,4.724,4.295 25 | M,1.538,2.951,4.482 26 | F,2.606,4.811,4.538 27 | M,1.241,2.324,3.033 28 | F,1.169,56.53,35.851 29 | M,1.032,2.288,3.839 30 | M,2.366,3.251,3.843 31 | F,1.27,5.437,5.382 32 | F,1.528,4.281,4.322 33 | M,7.798,7.618,6.133 34 | F,1.001,2.524,3.453 35 | M,1.082,2.166,2.844 36 | F,2.128,3.004,3.525 37 | M,2.265,3.477,3.785 38 | M,2.082,3.183,4.508 39 | M,1.47,2.488,4.898 40 | M,6.877,6.725,6.561 41 | M,1.287,2.237,3.137 42 | F,1.585,5.857,6.121 43 | F,1.033,2.305,3.1 44 | M,1.302,2.372,3.142 45 | F,1.898,2.736,7.38 46 | M,1.146,2.184,2.931 47 | M,4.219,5.772,4.955 48 | F,1.787,3.013,3.734 49 | F,1.185,27.011,18.582 50 | F,2.081,3.1,3.358 51 | F,1.044,2.442,2.96 52 | M,6.296,7.392,6.015 53 | F,1.026,2.913,6.355 54 | M,3.877,4.433,4.695 55 | F,1.157,4.832,4.486 56 | F,2.032,2.89,3.958 57 | F,1.0,11.769,9.464 58 | M,1.158,3.144,3.678 59 | F,1.996,2.91,4.6 60 | F,1.462,7.129,5.695 61 | F,1.063,31.755,20.609 62 | F,1.284,3.39,9.668 63 | F,1.265,3.791,4.25 64 | M,1.522,2.971,3.221 65 | F,1.735,3.025,3.498 66 | F,2.507,5.43,4.66 67 | F,1.41,3.413,4.207 68 | M,1.282,2.453,18.862 69 | F,1.081,13.211,10.113 70 | M,2.264,3.856,4.23 71 | F,1.868,19.845,13.614 72 | M,1.3,3.236,3.473 73 | F,1.441,2.405,3.439 74 | M,1.728,3.02,4.826 75 | M,1.094,2.663,3.003 76 | M,1.014,2.539,3.378 77 | F,1.21,2.617,3.422 78 | F,1.572,3.347,4.283 79 | F,1.396,2.365,4.919 80 | F,1.803,2.767,3.547 81 | F,2.355,4.614,4.352 82 | F,1.398,3.992,4.168 83 | F,1.075,2.362,2.936 84 | F,2.587,4.245,4.01 85 | M,1.534,2.712,3.265 86 | M,1.961,2.773,3.607 87 | F,1.84,2.872,3.354 88 | M,5.609,6.15,6.883 89 | F,1.191,168.086,103.362 90 | M,1.842,3.177,3.967 91 | M,1.256,2.257,3.426 92 | F,1.286,7.749,6.051 93 | M,1.14,2.361,3.865 94 | F,1.235,2.297,6.256 95 | M,4.398,5.147,4.497 96 | F,1.189,2.506,3.712 97 | F,1.152,2.979,4.249 98 | M,1.549,2.603,3.067 99 | F,1.161,4.289,6.054 100 | M,1.378,2.551,3.473 101 | F,2.456,3.304,3.573 102 | M,1.14,2.213,5.701 103 | F,1.321,3.459,3.656 104 | M,1.602,3.298,4.023 105 | M,1.484,2.391,3.169 106 | F,6.29,8.128,7.538 107 | M,1.769,2.665,3.048 108 | M,1.961,3.203,5.789 109 | M,5.501,6.597,5.469 110 | F,1.307,2.601,3.146 111 | M,1.246,2.504,3.335 112 | F,1.023,6.129,5.414 113 | M,1.107,2.165,3.0 114 | M,1.145,2.184,2.728 115 | F,1.107,13.523,9.714 116 | M,2.019,3.398,4.335 117 | F,1.468,5.73,7.915 118 | M,1.735,3.617,3.7 119 | M,2.36,3.442,4.361 120 | M,1.14,2.413,2.861 121 | M,1.218,2.548,2.95 122 | M,1.852,3.309,3.639 123 | M,1.283,2.442,2.942 124 | M,1.015,2.053,2.719 125 | M,1.33,2.324,3.34 126 | F,3.302,48.624,32.892 127 | M,1.301,2.262,3.673 128 | F,1.224,5.14,4.803 129 | F,9.771,29.124,21.438 130 | M,1.677,2.598,4.145 131 | F,1.256,5.325,5.225 132 | M,1.055,2.197,3.055 133 | F,2.171,3.31,3.429 134 | F,1.851,9.623,7.293 135 | F,3.579,16.101,11.125 136 | M,1.13,2.287,3.169 137 | M,1.063,2.526,3.555 138 | M,1.904,2.803,3.613 139 | M,1.12,2.914,4.533 140 | M,1.102,3.323,3.997 141 | F,1.213,2.731,5.031 142 | M,2.337,3.577,3.619 143 | F,1.474,10.889,8.072 144 | F,1.024,2.038,6.124 145 | M,1.366,3.381,3.648 146 | M,1.779,3.016,3.328 147 | M,1.472,2.611,4.715 148 | F,1.529,3.737,10.339 149 | M,1.136,3.05,3.794 150 | M,2.563,3.889,3.983 151 | M,1.51,2.721,3.698 152 | F,1.867,3.836,3.713 153 | M,7.426,8.519,6.587 154 | F,1.322,2.621,3.335 155 | M,2.9,3.561,4.675 156 | F,1.004,4.537,4.401 157 | M,1.017,2.611,2.995 158 | M,1.562,2.838,3.343 159 | M,1.205,2.292,2.91 160 | F,1.153,2.627,3.017 161 | F,1.177,4.075,4.251 162 | M,1.211,2.304,2.999 163 | F,1.921,3.935,5.075 164 | M,1.524,2.592,2.986 165 | M,2.177,3.264,3.6 166 | M,2.427,3.25,3.56 167 | M,2.523,3.31,3.967 168 | F,1.307,5.557,7.516 169 | F,1.315,3.005,3.315 170 | M,3.683,4.257,5.017 171 | F,1.719,9.851,8.152 172 | M,1.043,2.258,2.769 173 | F,1.478,2.54,4.423 174 | F,1.246,5.107,5.123 175 | F,8.921,8.803,8.412 176 | M,1.007,2.39,3.102 177 | F,1.606,4.474,5.105 178 | F,1.902,33.585,21.715 179 | M,1.186,2.237,2.845 180 | M,6.159,6.269,5.37 181 | F,2.668,19.839,13.923 182 | F,3.443,7.014,6.838 183 | M,1.01,2.272,3.383 184 | M,1.525,3.088,4.338 185 | F,1.191,2.998,3.647 186 | M,2.574,3.49,5.248 187 | M,1.65,2.59,3.009 188 | M,1.473,2.713,3.128 189 | M,1.063,2.178,3.362 190 | M,1.475,2.857,3.258 191 | F,1.648,3.314,3.52 192 | F,4.763,12.014,11.364 193 | F,1.552,6.49,5.345 194 | F,5.539,5.839,18.663 195 | M,5.104,5.7,6.133 196 | M,1.691,3.173,4.655 197 | F,1.423,3.609,4.463 198 | F,1.368,2.449,3.06 199 | F,3.02,4.832,6.015 200 | F,1.014,2.928,3.196 201 | F,1.062,2.63,3.743 202 | F,1.055,3.719,4.101 203 | M,2.028,2.991,4.018 204 | F,1.231,2.554,2.949 205 | F,1.662,5.873,5.312 206 | F,1.589,2.796,3.614 207 | F,1.276,7.184,5.831 208 | M,1.461,5.53,4.991 209 | F,1.679,3.491,6.773 210 | M,4.115,5.388,4.961 211 | M,1.535,2.504,3.045 212 | M,1.61,3.331,3.802 213 | F,1.036,32.801,21.125 214 | M,4.575,5.189,4.686 215 | F,1.456,2.777,4.676 216 | F,2.243,3.225,4.274 217 | M,1.026,3.568,3.552 218 | F,1.314,2.828,3.831 219 | F,1.16,3.314,3.571 220 | M,1.168,2.385,6.268 221 | M,2.19,3.204,4.254 222 | M,1.631,3.25,3.415 223 | M,1.336,4.056,4.08 224 | F,1.005,4.108,4.425 225 | M,5.34,7.701,6.118 226 | F,5.131,5.587,5.927 227 | M,1.131,2.487,4.078 228 | M,1.021,2.582,2.951 229 | F,1.459,5.377,4.73 230 | M,4.537,5.549,4.894 231 | M,3.341,4.046,7.996 232 | F,1.552,11.428,8.671 233 | F,1.198,2.341,2.941 234 | M,1.222,2.315,2.851 235 | F,3.13,4.763,7.315 236 | F,1.403,4.063,5.652 237 | F,1.073,2.561,3.806 238 | F,1.153,13.942,10.428 239 | F,1.176,3.13,4.844 240 | F,1.068,2.188,3.008 241 | M,1.365,3.213,3.896 242 | M,3.451,6.446,6.052 243 | F,1.738,3.226,4.085 244 | M,1.038,2.402,2.93 245 | F,1.003,3.68,14.0 246 | M,1.175,2.998,4.239 247 | F,1.253,2.417,3.412 248 | M,2.116,3.909,4.278 249 | F,5.505,8.715,8.087 250 | F,1.278,2.266,3.262 251 | F,1.787,4.2,5.261 252 | F,14.005,12.439,10.401 253 | M,1.983,3.095,3.575 254 | M,1.658,2.954,3.273 255 | M,1.041,2.512,3.404 256 | M,1.216,3.842,4.138 257 | F,3.398,4.425,4.636 258 | M,1.119,3.127,3.305 259 | M,2.529,3.489,4.404 260 | M,1.815,3.183,3.722 261 | F,1.256,7.253,6.207 262 | F,1.457,5.514,6.563 263 | F,1.479,7.051,5.793 264 | F,1.87,4.793,4.516 265 | M,1.438,3.205,3.891 266 | M,1.074,3.527,3.767 267 | M,2.101,4.305,4.162 268 | F,1.298,2.824,3.316 269 | M,5.205,8.115,6.616 270 | F,1.181,2.219,4.286 271 | F,1.165,4.06,5.609 272 | M,1.225,2.487,3.85 273 | M,1.529,2.533,4.404 274 | F,3.084,5.049,4.466 275 | M,1.102,2.109,6.629 276 | F,1.178,3.631,4.027 277 | M,1.546,3.518,3.615 278 | M,1.354,2.345,5.914 279 | M,1.345,2.444,3.97 280 | M,2.362,3.563,5.53 281 | M,3.624,4.292,4.367 282 | F,1.388,3.162,4.685 283 | M,1.788,2.808,3.472 284 | M,2.242,3.288,3.786 285 | F,1.441,3.067,8.197 286 | F,1.19,2.355,4.15 287 | F,1.662,2.828,3.824 288 | M,1.553,2.475,3.139 289 | F,3.187,4.804,4.414 290 | F,1.027,8.584,6.639 291 | M,3.336,3.907,3.921 292 | F,1.466,4.689,5.339 293 | F,1.008,2.876,3.283 294 | M,1.235,3.366,3.487 295 | F,1.905,3.408,3.503 296 | M,1.398,2.9,4.353 297 | F,7.099,7.677,6.213 298 | F,1.316,3.673,3.77 299 | M,1.219,2.948,3.42 300 | M,2.368,5.669,5.35 301 | M,1.487,2.449,3.348 302 | M,1.774,2.962,5.077 303 | M,2.269,3.073,3.895 304 | F,1.745,2.633,3.695 305 | F,1.316,5.814,6.095 306 | F,1.069,72.588,45.967 307 | F,1.543,4.201,5.424 308 | F,3.122,3.792,4.416 309 | F,1.312,2.328,4.586 310 | M,3.347,4.038,5.44 311 | F,1.419,3.074,4.385 312 | M,1.624,2.501,3.123 313 | F,2.447,9.585,7.401 314 | F,1.515,3.47,4.407 315 | F,1.049,280.408,170.551 316 | M,7.251,8.262,6.369 317 | F,1.152,3.325,4.779 318 | F,1.859,4.705,4.41 319 | M,1.422,2.498,2.925 320 | M,1.385,2.462,2.957 321 | M,1.15,2.177,3.306 322 | F,1.897,4.157,4.522 323 | F,1.062,2.156,4.872 324 | F,10.235,10.357,7.695 325 | F,2.543,3.804,5.673 326 | F,1.466,6.901,6.51 327 | F,1.318,2.995,3.377 328 | M,1.184,3.545,4.312 329 | M,1.416,2.42,3.649 330 | F,2.88,19.582,13.231 331 | F,1.174,3.89,3.969 332 | F,1.415,2.496,3.827 333 | M,1.143,2.428,3.099 334 | F,1.228,2.622,4.463 335 | M,1.111,2.791,3.483 336 | M,10.281,9.93,8.635 337 | M,1.528,2.448,2.925 338 | F,1.935,3.608,4.878 339 | F,1.053,11.475,8.798 340 | M,1.256,2.434,3.248 341 | F,3.052,7.122,5.928 342 | F,1.045,2.19,2.951 343 | F,1.095,9.893,7.491 344 | F,1.634,3.719,4.0 345 | F,1.628,24.191,16.12 346 | M,2.486,3.541,3.626 347 | F,3.937,8.35,12.172 348 | M,1.08,4.821,4.599 349 | F,1.162,5.363,5.686 350 | M,1.322,2.656,3.23 351 | M,1.0,2.198,3.173 352 | M,1.037,2.047,2.991 353 | F,1.137,3.024,4.064 354 | F,1.388,3.153,4.551 355 | M,1.156,3.062,3.851 356 | M,2.848,3.565,4.398 357 | M,1.217,2.86,3.192 358 | F,3.642,4.161,3.967 359 | F,6.298,15.598,11.081 360 | F,1.348,4.692,4.76 361 | M,1.137,2.351,2.934 362 | F,1.188,2.584,4.49 363 | M,2.114,2.976,3.924 364 | M,1.173,2.548,4.695 365 | F,1.271,3.051,4.52 366 | M,1.385,2.995,3.251 367 | F,1.534,14.099,10.878 368 | M,16.014,14.16,10.167 369 | F,1.141,4.341,4.231 370 | M,1.244,2.436,3.365 371 | M,1.165,2.149,2.868 372 | M,1.251,2.651,3.392 373 | F,1.055,2.73,3.788 374 | M,1.25,2.205,3.123 375 | M,2.986,3.874,3.729 376 | F,1.194,2.276,3.101 377 | F,1.262,4.237,5.6 378 | M,4.244,4.935,4.574 379 | M,1.919,3.047,3.603 380 | F,1.438,20.162,13.829 381 | M,2.119,4.131,3.986 382 | M,1.068,2.676,3.113 383 | F,1.367,3.934,5.154 384 | M,1.065,2.174,3.251 385 | M,1.142,2.117,4.701 386 | M,1.08,2.116,2.949 387 | M,1.252,2.366,3.382 388 | M,1.272,2.308,3.113 389 | F,4.356,6.276,5.696 390 | M,1.166,2.481,4.148 391 | F,1.377,3.068,3.736 392 | F,2.303,7.858,9.939 393 | F,2.329,6.327,6.069 394 | F,2.001,5.446,4.731 395 | M,1.185,2.463,2.911 396 | F,1.407,2.38,11.955 397 | M,1.109,2.332,3.059 398 | F,1.11,3.284,4.15 399 | F,1.331,3.238,3.8 400 | F,1.956,2.77,3.189 401 | F,1.453,4.615,4.266 402 | F,2.971,3.992,3.973 403 | M,2.432,3.164,3.807 404 | F,1.016,3.23,4.017 405 | M,1.522,4.009,4.004 406 | M,1.6,2.492,2.916 407 | F,5.101,5.298,4.882 408 | F,1.012,3.72,4.037 409 | F,1.46,3.794,5.113 410 | M,1.121,2.103,3.449 411 | F,1.028,2.16,2.883 412 | F,1.557,8.58,6.741 413 | F,2.097,3.87,4.617 414 | F,2.108,3.057,4.206 415 | F,1.015,2.234,3.454 416 | F,1.299,4.127,3.962 417 | F,1.023,2.606,3.22 418 | F,1.153,2.154,2.715 419 | F,1.113,4.187,5.38 420 | F,1.129,2.143,4.469 421 | M,1.23,2.232,4.595 422 | M,1.176,2.212,2.771 423 | M,5.149,5.383,6.311 424 | F,1.243,6.027,8.518 425 | F,3.074,3.783,31.5 426 | M,1.105,2.15,3.602 427 | F,2.057,3.816,3.92 428 | M,1.032,2.088,2.804 429 | F,1.364,5.833,6.007 430 | M,1.003,2.302,3.427 431 | F,2.296,11.807,9.486 432 | F,4.494,4.843,4.646 433 | M,1.018,3.1,3.648 434 | F,3.888,4.529,4.392 435 | M,2.103,4.536,4.617 436 | M,1.249,2.368,3.714 437 | F,3.313,5.103,5.612 438 | M,1.192,2.163,2.989 439 | F,1.301,5.471,5.313 440 | M,1.052,2.142,3.578 441 | F,1.707,15.757,11.053 442 | F,1.015,4.36,4.203 443 | M,1.393,2.456,3.22 444 | M,1.777,2.749,3.406 445 | F,2.365,3.339,3.42 446 | F,1.085,6.924,6.32 447 | F,2.017,3.75,4.085 448 | M,1.887,2.846,3.572 449 | M,1.507,4.526,5.898 450 | M,1.552,3.301,3.583 451 | M,1.049,2.45,2.924 452 | F,1.582,7.34,5.976 453 | M,1.272,2.27,2.943 454 | F,2.748,5.859,7.304 455 | F,1.207,2.741,3.729 456 | M,1.537,2.998,10.031 457 | F,1.321,32.353,21.068 458 | M,2.843,4.263,3.992 459 | F,1.158,3.688,3.888 460 | M,1.042,2.727,8.819 461 | M,1.995,3.077,4.048 462 | F,1.305,2.711,6.43 463 | F,1.56,2.499,3.699 464 | F,1.013,4.528,4.362 465 | M,4.57,4.919,6.871 466 | F,2.859,4.506,4.298 467 | F,1.631,4.905,4.746 468 | F,1.009,11.846,8.773 469 | F,1.268,4.086,4.796 470 | M,6.867,6.796,5.755 471 | F,1.771,3.699,8.979 472 | M,1.092,2.606,5.947 473 | M,1.362,2.379,2.876 474 | M,5.483,6.248,7.119 475 | M,1.466,3.114,4.255 476 | M,1.013,2.345,3.528 477 | M,1.622,3.602,3.788 478 | M,1.171,2.243,3.392 479 | M,1.053,2.395,3.875 480 | M,1.294,3.572,4.673 481 | F,1.505,5.26,6.333 482 | F,1.009,7.02,5.91 483 | F,1.506,2.747,3.199 484 | F,1.43,3.953,4.445 485 | F,2.203,3.537,3.744 486 | F,1.317,4.572,5.762 487 | M,1.496,2.733,3.061 488 | F,1.969,4.779,4.714 489 | M,3.118,4.148,4.803 490 | M,1.27,2.888,3.172 491 | M,1.584,3.316,4.051 492 | F,1.81,2.727,3.233 493 | M,1.022,4.041,3.889 494 | M,2.24,3.22,3.515 495 | F,1.267,2.46,2.89 496 | M,1.741,4.201,4.471 497 | F,1.376,6.656,5.708 498 | F,1.833,3.537,19.776 499 | F,1.905,4.523,4.188 500 | F,1.112,2.441,5.782 501 | M,1.72,2.81,3.447 502 | F,2.593,4.078,3.937 503 | F,1.144,5.794,7.167 504 | M,2.034,3.076,3.301 505 | M,1.653,3.239,3.922 506 | F,4.721,9.493,7.307 507 | M,1.163,2.342,3.113 508 | M,1.087,2.326,3.255 509 | F,1.206,3.468,7.021 510 | F,1.161,2.133,2.935 511 | F,2.028,3.113,3.657 512 | F,1.936,9.399,7.204 513 | F,1.74,6.412,5.575 514 | M,1.13,2.136,2.746 515 | M,2.69,3.831,4.123 516 | M,4.799,5.047,4.868 517 | M,1.461,2.717,3.569 518 | F,1.689,2.782,3.265 519 | F,1.415,9.321,7.451 520 | M,1.181,2.594,2.977 521 | M,1.184,2.174,2.723 522 | M,1.207,2.654,3.177 523 | F,1.112,12.021,9.171 524 | F,3.193,7.061,6.763 525 | M,2.657,3.376,4.274 526 | F,1.363,4.673,4.614 527 | F,1.257,4.088,5.285 528 | M,4.051,4.915,5.109 529 | M,1.134,2.943,3.72 530 | F,1.497,2.922,3.265 531 | F,1.028,2.685,3.269 532 | F,1.112,2.393,3.486 533 | F,1.589,3.482,5.335 534 | M,1.721,2.807,3.347 535 | F,1.545,2.546,9.242 536 | F,2.769,3.8,4.7 537 | F,12.314,11.215,8.418 538 | M,2.058,3.218,3.773 539 | M,1.367,2.38,3.065 540 | M,2.454,3.332,5.146 541 | M,1.066,2.967,3.203 542 | F,1.777,4.224,4.129 543 | M,1.441,2.685,3.059 544 | M,1.103,4.026,4.832 545 | M,6.078,6.316,5.292 546 | M,1.229,3.442,4.267 547 | F,1.613,4.133,4.594 548 | M,2.87,3.723,4.762 549 | M,1.424,2.522,9.672 550 | M,1.063,3.466,3.56 551 | F,2.349,4.639,4.302 552 | M,1.243,2.317,3.351 553 | F,7.685,8.645,6.613 554 | F,2.934,3.947,5.644 555 | M,2.612,3.405,3.682 556 | M,1.246,2.254,3.011 557 | F,2.029,5.486,5.431 558 | F,8.553,12.323,9.12 559 | F,1.453,2.937,3.436 560 | M,1.375,2.53,3.029 561 | M,1.007,2.835,3.838 562 | M,1.826,2.668,3.881 563 | F,2.658,3.925,4.591 564 | M,1.153,2.279,2.899 565 | M,1.208,2.525,3.594 566 | M,1.415,3.675,3.687 567 | M,1.038,2.047,4.053 568 | M,1.048,3.062,3.542 569 | M,1.314,2.626,3.312 570 | M,1.163,2.543,3.037 571 | M,1.298,4.462,4.603 572 | M,1.354,2.339,7.086 573 | F,6.492,6.853,6.296 574 | F,4.236,4.947,5.343 575 | F,1.078,3.122,3.533 576 | M,2.918,3.937,3.959 577 | F,1.043,5.244,4.708 578 | F,1.425,2.407,3.454 579 | M,1.094,2.319,2.868 580 | F,1.256,16.851,12.377 581 | M,1.974,3.055,3.558 582 | F,1.318,7.634,6.865 583 | M,2.276,3.069,3.276 584 | F,1.886,3.198,6.03 585 | F,4.183,7.881,6.505 586 | M,1.465,2.831,3.211 587 | F,2.248,3.954,4.354 588 | F,1.215,4.597,8.043 589 | F,1.236,6.228,6.269 590 | F,1.292,12.742,9.368 591 | M,1.303,2.498,3.079 592 | M,1.056,2.536,3.53 593 | M,1.442,2.562,2.981 594 | M,1.052,3.714,3.857 595 | M,3.012,3.902,4.081 596 | F,1.032,2.862,4.578 597 | M,1.348,4.135,4.077 598 | F,1.182,2.148,4.36 599 | F,1.088,2.667,4.603 600 | F,2.151,9.137,6.896 601 | M,1.873,2.964,3.281 602 | F,1.082,2.707,4.002 603 | F,1.65,4.231,4.511 604 | M,2.196,3.183,3.323 605 | F,2.1,3.47,3.832 606 | M,1.05,2.17,3.245 607 | F,1.783,3.173,17.258 608 | F,1.877,17.324,11.967 609 | F,2.694,31.912,20.668 610 | M,1.426,2.383,3.058 611 | F,1.362,5.625,5.464 612 | F,5.354,7.79,7.091 613 | F,2.217,5.025,4.766 614 | M,1.505,2.418,2.977 615 | F,1.222,2.629,2.981 616 | F,2.542,6.76,5.605 617 | F,1.355,3.464,3.554 618 | M,1.05,2.05,2.765 619 | M,1.354,2.623,3.168 620 | F,2.795,10.12,7.531 621 | M,1.346,3.499,3.765 622 | F,1.007,12.643,9.12 623 | M,1.604,2.824,3.566 624 | M,15.486,13.869,9.961 625 | M,2.339,3.189,3.881 626 | M,1.616,3.639,4.489 627 | M,3.418,4.786,4.313 628 | M,2.316,4.184,4.154 629 | M,1.412,2.437,6.442 630 | F,1.564,2.581,2.951 631 | F,1.929,5.523,5.217 632 | F,2.552,15.859,11.436 633 | F,1.03,15.209,12.46 634 | F,2.107,4.232,4.201 635 | M,1.345,2.766,3.965 636 | M,1.717,2.622,2.974 637 | M,2.061,2.985,3.544 638 | F,1.474,3.775,3.962 639 | F,1.09,10.937,9.758 640 | M,1.301,2.537,3.185 641 | M,1.041,2.452,2.905 642 | M,1.794,2.658,3.706 643 | M,4.648,7.375,5.831 644 | M,2.21,3.272,3.567 645 | F,1.28,2.453,3.448 646 | F,1.551,3.056,4.589 647 | F,1.199,3.425,3.744 648 | M,1.476,2.442,2.917 649 | M,1.196,2.248,3.853 650 | M,1.955,4.303,3.986 651 | F,1.162,10.345,10.138 652 | F,5.272,5.585,4.832 653 | M,1.72,2.714,3.093 654 | F,1.036,4.122,4.006 655 | F,1.005,2.425,2.972 656 | M,18.4,15.921,11.926 657 | F,1.133,4.922,6.174 658 | F,1.206,2.452,3.007 659 | F,1.124,2.677,3.092 660 | F,3.729,4.659,4.937 661 | M,1.695,2.624,3.665 662 | F,1.42,2.525,3.623 663 | M,1.504,2.467,2.893 664 | F,1.211,37.882,25.624 665 | F,1.61,5.681,6.027 666 | F,1.313,21.075,15.278 667 | F,1.117,3.695,3.789 668 | M,1.706,2.737,3.077 669 | F,1.264,2.446,28.333 670 | M,2.157,3.221,3.671 671 | M,1.308,2.552,3.687 672 | F,1.426,6.533,5.393 673 | F,2.169,4.28,4.558 674 | M,1.346,2.367,3.189 675 | F,5.441,10.811,7.981 676 | M,2.198,3.024,3.432 677 | M,2.4,3.462,5.012 678 | M,4.658,4.944,5.036 679 | M,1.279,2.423,3.624 680 | F,1.543,4.892,6.948 681 | F,1.807,2.838,3.389 682 | F,1.75,3.926,5.41 683 | F,4.61,6.29,5.247 684 | F,1.185,14.187,10.666 685 | M,1.188,2.43,3.264 686 | F,3.492,4.096,4.314 687 | M,2.232,3.051,3.344 688 | M,1.12,2.232,3.026 689 | M,1.525,3.268,4.563 690 | M,1.983,2.91,3.914 691 | F,1.243,4.067,4.312 692 | M,1.33,2.297,5.769 693 | F,1.535,2.732,4.66 694 | M,1.37,2.751,3.072 695 | F,2.012,2.94,4.568 696 | M,1.003,2.627,3.712 697 | F,1.33,3.242,3.381 698 | F,1.229,2.649,6.755 699 | F,1.6,10.796,8.395 700 | M,2.113,3.432,3.593 701 | M,1.04,2.059,2.942 702 | F,1.09,4.51,6.14 703 | F,1.728,2.879,3.345 704 | F,1.955,16.613,14.744 705 | F,1.558,2.665,3.046 706 | F,7.626,9.231,7.006 707 | F,1.413,2.715,3.841 708 | F,1.076,21.61,14.966 709 | F,1.785,3.205,4.365 710 | F,1.585,4.192,3.947 711 | M,1.563,2.507,3.052 712 | F,1.484,3.492,4.665 713 | M,4.052,4.882,4.541 714 | M,1.072,2.818,3.271 715 | F,1.039,3.54,5.422 716 | F,1.087,4.918,6.051 717 | F,1.151,9.436,8.434 718 | F,1.567,2.965,4.073 719 | M,1.606,2.663,5.517 720 | F,1.142,2.15,2.705 721 | M,1.399,2.69,3.094 722 | M,1.39,5.042,4.744 723 | M,1.352,2.953,3.334 724 | F,2.256,163.65,99.856 725 | M,1.376,2.569,6.725 726 | F,2.034,6.379,5.26 727 | M,1.095,2.149,2.702 728 | M,1.462,2.61,5.051 729 | M,2.384,3.6,3.644 730 | M,1.103,2.347,2.829 731 | F,1.367,2.33,3.301 732 | M,1.599,2.642,4.439 733 | F,1.108,4.591,4.435 734 | F,2.028,3.606,7.542 735 | F,1.042,3.009,5.62 736 | F,4.32,11.8,8.73 737 | M,1.371,2.429,3.152 738 | F,1.227,4.106,7.533 739 | M,1.064,3.089,3.316 740 | F,1.328,7.285,5.816 741 | F,1.714,2.948,3.323 742 | F,1.051,2.105,2.854 743 | M,1.201,2.297,2.874 744 | F,2.469,3.433,3.482 745 | F,1.681,2.579,4.182 746 | M,1.123,2.252,2.836 747 | F,1.092,3.378,3.924 748 | M,3.236,4.292,4.036 749 | M,1.184,2.353,3.041 750 | M,1.104,2.178,2.964 751 | M,166.71,134.957,84.133 752 | F,1.203,5.808,6.064 753 | M,1.069,2.638,4.663 754 | M,1.363,3.385,3.782 755 | M,1.33,2.393,2.925 756 | F,3.696,5.371,5.045 757 | M,1.075,2.36,3.306 758 | F,1.049,2.608,3.632 759 | F,1.05,4.667,7.148 760 | F,3.232,3.972,4.576 761 | F,1.348,7.237,5.966 762 | M,1.085,2.083,5.118 763 | F,1.569,3.217,3.47 764 | F,1.471,4.232,4.474 765 | F,1.117,2.978,5.964 766 | M,1.587,2.982,3.904 767 | M,1.231,2.201,3.128 768 | M,1.146,3.269,4.025 769 | F,1.429,2.444,3.334 770 | M,1.188,2.294,3.033 771 | M,1.134,2.254,3.299 772 | M,2.883,3.511,4.292 773 | F,1.088,2.195,6.915 774 | F,1.179,9.045,8.89 775 | F,1.276,6.374,10.886 776 | M,1.173,2.814,3.147 777 | F,1.126,4.763,16.503 778 | F,2.09,2.969,3.347 779 | F,1.221,2.688,3.073 780 | M,1.061,2.052,3.231 781 | M,1.476,2.406,3.477 782 | F,1.069,2.103,9.915 783 | F,1.248,2.496,4.423 784 | M,2.909,3.551,3.784 785 | M,1.259,2.214,3.229 786 | F,1.65,2.909,3.986 787 | F,1.435,7.114,7.159 788 | F,1.077,2.133,3.443 789 | F,1.688,79.017,49.197 790 | F,2.636,5.613,5.848 791 | F,1.05,9.851,7.516 792 | M,2.015,3.332,3.615 793 | F,1.797,6.815,5.542 794 | M,2.739,3.543,4.588 795 | F,1.056,2.461,2.929 796 | M,1.2,2.687,3.188 797 | M,1.809,3.028,5.146 798 | F,1.011,3.236,4.051 799 | F,1.939,3.01,3.389 800 | F,2.654,3.683,18.809 801 | F,1.352,3.747,6.302 802 | F,1.33,3.097,3.309 803 | M,1.177,4.527,4.244 804 | F,1.003,3.486,4.432 805 | F,1.109,2.998,3.363 806 | M,7.047,8.908,7.155 807 | M,2.745,3.435,3.548 808 | M,1.168,2.268,3.392 809 | F,5.252,6.038,5.667 810 | M,1.258,3.282,6.447 811 | M,1.193,2.903,3.21 812 | F,1.086,2.595,3.601 813 | M,3.188,4.935,4.547 814 | F,8.768,8.295,7.226 815 | M,1.219,2.481,2.999 816 | F,1.836,4.944,8.092 817 | F,1.227,2.726,3.503 818 | F,1.057,2.135,3.138 819 | F,1.283,2.642,4.614 820 | M,1.493,2.691,4.71 821 | M,1.068,2.218,3.087 822 | F,2.346,3.93,5.286 823 | F,1.41,2.452,2.984 824 | F,1.143,2.132,2.898 825 | F,1.567,11.059,9.162 826 | F,2.199,3.061,7.009 827 | M,1.22,2.323,2.853 828 | F,1.83,5.036,4.526 829 | M,1.322,3.289,6.776 830 | M,5.274,5.585,4.796 831 | F,2.089,5.12,4.503 832 | M,1.246,2.482,3.292 833 | F,1.009,2.072,2.833 834 | M,1.709,2.796,3.253 835 | M,1.117,2.105,3.193 836 | M,1.067,4.494,4.314 837 | F,3.829,8.109,26.102 838 | M,139.987,113.367,69.547 839 | F,1.17,2.504,5.317 840 | F,1.197,2.958,5.738 841 | M,1.094,2.238,3.039 842 | F,1.358,2.994,28.922 843 | F,2.73,16.947,11.821 844 | F,1.83,3.479,3.556 845 | M,2.551,3.924,4.205 846 | F,1.138,2.334,2.806 847 | M,1.926,3.088,3.588 848 | M,3.503,4.308,5.147 849 | F,1.18,3.879,4.165 850 | F,1.798,5.187,4.681 851 | M,1.292,3.35,3.555 852 | M,1.187,2.259,4.525 853 | M,5.738,5.999,5.609 854 | F,1.239,2.264,2.887 855 | M,1.059,2.51,3.229 856 | M,1.279,4.004,4.326 857 | M,1.346,2.496,3.268 858 | F,2.009,44.087,29.472 859 | F,4.468,6.559,5.34 860 | F,2.338,3.392,3.686 861 | F,3.805,5.595,5.503 862 | M,1.38,2.791,3.487 863 | M,1.888,3.24,3.396 864 | F,1.203,4.278,4.108 865 | F,1.037,2.31,4.203 866 | M,1.255,2.301,3.188 867 | M,1.819,2.771,3.631 868 | F,1.174,5.434,6.531 869 | F,2.686,4.546,4.898 870 | M,2.186,3.488,3.68 871 | F,1.114,6.872,6.151 872 | M,1.222,2.561,3.003 873 | F,2.393,4.183,4.151 874 | M,1.15,2.345,3.403 875 | F,1.223,3.566,3.569 876 | F,1.234,2.398,2.839 877 | F,2.242,7.413,8.614 878 | F,1.019,14.57,16.155 879 | F,1.039,7.227,8.893 880 | M,1.54,3.365,3.537 881 | M,1.288,3.194,4.153 882 | M,1.65,2.6,3.276 883 | F,1.168,287.517,173.963 884 | M,3.326,4.375,4.999 885 | M,2.045,3.076,4.273 886 | M,1.036,3.318,4.136 887 | F,2.151,4.594,26.594 888 | M,5.734,11.059,13.67 889 | M,4.168,5.245,4.642 890 | F,1.944,3.453,5.167 891 | M,1.068,2.741,3.65 892 | F,1.536,5.675,6.082 893 | F,1.182,2.692,16.292 894 | F,5.794,14.996,12.461 895 | M,1.881,2.767,3.313 896 | M,1.603,2.679,5.134 897 | F,1.811,4.748,6.811 898 | M,1.334,2.559,3.641 899 | M,1.263,2.761,5.174 900 | F,3.947,456.617,275.88 901 | F,1.223,2.28,3.983 902 | M,1.021,2.745,3.049 903 | F,1.292,7.606,6.695 904 | F,2.184,3.419,4.715 905 | F,1.687,2.96,3.559 906 | M,5.141,5.57,6.091 907 | M,1.058,2.264,3.105 908 | F,3.362,5.128,4.73 909 | F,1.259,2.529,3.603 910 | F,1.379,3.474,6.639 911 | F,1.323,7.467,6.965 912 | M,1.064,3.304,5.784 913 | F,1.153,4.523,4.598 914 | M,1.97,2.92,3.755 915 | F,1.012,10.276,8.462 916 | M,1.075,2.3,2.913 917 | M,1.013,2.121,3.479 918 | F,2.648,3.505,3.553 919 | F,1.617,32.599,21.707 920 | M,1.098,2.115,2.764 921 | F,2.08,4.216,4.083 922 | M,5.488,5.684,8.554 923 | M,3.909,5.486,4.937 924 | F,3.57,4.346,4.628 925 | M,1.004,2.675,3.621 926 | M,1.56,2.522,3.275 927 | M,1.16,3.962,4.532 928 | M,1.516,2.937,3.175 929 | F,1.211,3.02,4.274 930 | M,1.087,4.454,4.268 931 | F,1.342,3.595,6.188 932 | M,1.407,2.536,2.996 933 | F,9.885,9.341,7.026 934 | F,1.022,5.12,4.517 935 | F,1.196,3.93,4.383 936 | F,2.598,3.623,3.754 937 | M,1.714,2.692,3.847 938 | F,2.402,3.461,3.517 939 | F,1.716,3.753,3.852 940 | F,2.039,2.891,5.133 941 | M,1.404,2.468,2.903 942 | F,1.121,5.453,6.31 943 | F,2.294,5.003,4.488 944 | F,1.521,7.832,8.23 945 | M,1.078,2.754,3.986 946 | F,2.264,3.037,3.406 947 | F,4.914,6.719,5.842 948 | M,1.237,2.444,3.183 949 | F,1.19,2.831,3.496 950 | M,1.044,6.933,5.675 951 | M,1.726,3.095,3.382 952 | F,4.936,5.551,5.848 953 | M,1.076,2.407,2.923 954 | F,1.394,2.441,3.117 955 | F,1.053,5.553,4.778 956 | F,1.018,2.654,3.175 957 | F,1.726,2.825,3.122 958 | F,2.749,3.632,4.728 959 | M,1.229,2.189,2.977 960 | M,2.837,4.251,4.19 961 | M,1.064,2.705,3.37 962 | F,1.146,3.247,3.577 963 | M,3.188,3.906,3.968 964 | F,1.426,3.114,4.057 965 | F,1.598,11.631,8.568 966 | F,1.02,2.181,3.217 967 | F,1.071,2.093,3.403 968 | F,1.029,2.353,2.92 969 | M,3.244,4.129,4.059 970 | F,1.075,2.069,3.334 971 | M,2.579,3.308,3.646 972 | M,1.241,2.781,3.799 973 | F,2.239,3.966,3.976 974 | M,1.255,4.232,4.27 975 | M,1.169,3.62,4.656 976 | M,1.05,2.177,2.78 977 | F,1.179,2.872,6.042 978 | M,1.376,3.864,4.025 979 | F,2.341,4.725,4.776 980 | F,1.351,2.985,4.111 981 | M,5.917,6.787,5.888 982 | M,1.477,4.021,4.907 983 | M,1.013,2.553,3.032 984 | M,1.308,2.356,2.88 985 | M,1.793,3.557,3.684 986 | M,1.143,2.354,12.198 987 | F,1.822,5.431,4.734 988 | M,1.419,2.634,3.382 989 | M,1.013,3.891,4.631 990 | F,2.105,2.972,5.205 991 | M,1.508,2.476,5.495 992 | F,1.044,2.325,21.533 993 | F,1.38,2.645,3.679 994 | F,1.185,2.517,3.117 995 | M,2.883,3.575,3.933 996 | M,1.183,2.725,3.817 997 | F,4.141,4.848,4.844 998 | M,1.484,2.5,3.056 999 | M,1.216,2.264,3.848 1000 | F,2.316,3.848,5.696 1001 | M,1.818,4.923,4.782 1002 | M,1.306,2.442,3.368 1003 | F,1.643,3.023,3.821 1004 | F,2.125,2.989,4.793 1005 | M,2.596,3.464,4.975 1006 | F,2.334,3.43,3.459 1007 | M,1.095,2.815,6.392 1008 | M,2.414,3.179,3.519 1009 | F,1.031,2.226,3.142 1010 | F,1.118,2.558,3.295 1011 | M,1.628,2.647,4.191 1012 | M,1.063,3.09,4.039 1013 | F,1.588,7.02,5.757 1014 | F,1.202,3.81,4.105 1015 | F,1.324,2.746,3.049 1016 | F,1.208,2.729,4.792 1017 | F,1.037,3.772,3.865 1018 | F,1.415,5.745,4.909 1019 | F,5.241,6.141,6.089 1020 | M,1.605,2.806,3.204 1021 | M,1.195,3.446,3.893 1022 | F,4.775,7.247,5.877 1023 | M,1.28,2.573,3.9 1024 | M,1.818,2.685,6.95 1025 | M,1.653,2.603,3.016 1026 | M,4.608,4.98,5.574 1027 | M,3.422,4.399,4.391 1028 | F,1.083,2.212,2.765 1029 | F,1.046,2.072,3.267 1030 | M,2.292,3.226,3.679 1031 | F,3.243,6.863,8.366 1032 | F,1.404,5.035,4.745 1033 | F,1.798,7.226,7.179 1034 | M,1.037,2.615,3.037 1035 | M,1.132,2.553,3.181 1036 | M,1.084,2.366,3.232 1037 | F,1.583,2.783,3.217 1038 | F,1.116,3.674,3.768 1039 | F,1.031,4.127,4.088 1040 | F,1.197,2.327,4.157 1041 | M,1.76,2.992,5.443 1042 | F,1.539,2.561,3.035 1043 | F,1.222,3.627,4.259 1044 | M,2.451,3.232,3.415 1045 | M,1.175,2.192,2.742 1046 | F,1.163,2.283,2.798 1047 | F,1.507,14.693,10.668 1048 | M,1.384,2.734,3.324 1049 | M,1.343,2.396,3.452 1050 | F,1.088,2.163,3.09 1051 | M,1.421,2.687,3.139 1052 | F,1.162,2.333,2.872 1053 | F,1.283,6.441,6.003 1054 | F,1.937,3.931,3.941 1055 | F,3.98,7.571,6.316 1056 | M,2.103,3.102,3.269 1057 | F,1.297,5.069,4.657 1058 | F,1.568,5.059,5.405 1059 | M,1.986,3.168,3.364 1060 | M,1.307,3.283,3.978 1061 | M,1.25,2.606,4.262 1062 | M,1.075,2.46,4.235 1063 | F,1.947,3.292,3.5 1064 | F,2.488,19.511,13.625 1065 | F,1.21,3.453,6.383 1066 | M,2.149,3.136,4.047 1067 | F,1.602,3.899,6.17 1068 | F,2.152,3.126,3.663 1069 | M,1.303,2.372,3.186 1070 | M,1.99,2.948,4.738 1071 | F,1.3,3.515,3.962 1072 | F,1.048,4.779,5.305 1073 | M,1.492,2.537,3.205 1074 | F,1.354,2.472,4.074 1075 | F,1.157,3.648,4.44 1076 | M,3.045,4.718,4.531 1077 | F,1.273,3.081,3.933 1078 | F,1.02,3.105,4.072 1079 | M,1.272,2.362,4.248 1080 | M,1.318,3.138,3.923 1081 | M,2.688,3.403,4.166 1082 | F,2.232,3.233,10.013 1083 | M,1.118,35.045,22.46 1084 | F,2.492,5.77,5.015 1085 | M,1.153,2.486,3.082 1086 | M,1.233,3.022,5.518 1087 | M,1.041,9.047,6.955 1088 | F,1.029,2.306,3.507 1089 | M,1.77,3.439,3.523 1090 | M,3.612,4.269,4.117 1091 | M,1.404,2.983,3.349 1092 | F,2.533,6.131,6.271 1093 | F,2.202,720.343,433.689 1094 | M,1.727,2.63,3.821 1095 | M,6.777,6.623,5.553 1096 | F,2.248,6.557,6.646 1097 | M,1.174,2.528,3.147 1098 | F,2.177,5.624,5.223 1099 | M,1.804,3.357,3.478 1100 | M,1.29,2.538,2.976 1101 | M,1.041,2.223,3.15 1102 | F,1.128,6.128,6.001 1103 | M,2.221,3.184,3.356 1104 | F,1.154,4.099,3.969 1105 | M,21.607,19.816,13.305 1106 | M,1.808,2.717,3.115 1107 | M,1.383,2.31,2.909 1108 | M,1.526,2.545,3.597 1109 | F,1.603,7.208,5.773 1110 | F,5.675,7.31,6.89 1111 | F,1.092,23.162,15.713 1112 | F,1.172,3.592,3.667 1113 | F,1.856,3.119,12.403 1114 | F,1.147,6.043,5.614 1115 | F,2.787,5.734,5.107 1116 | F,1.237,7.682,6.05 1117 | F,1.105,4.498,4.39 1118 | M,1.025,2.286,3.292 1119 | F,1.573,2.918,3.363 1120 | M,2.392,3.137,3.736 1121 | M,1.173,2.295,2.938 1122 | M,3.482,4.005,3.824 1123 | M,2.032,3.073,3.516 1124 | M,1.032,2.133,2.901 1125 | F,1.53,5.273,4.776 1126 | M,1.52,2.52,3.311 1127 | M,1.12,2.13,2.929 1128 | M,1.226,3.186,5.71 1129 | M,1.359,2.312,3.322 1130 | F,1.025,5.638,5.131 1131 | M,1.085,3.771,3.78 1132 | F,1.094,2.219,3.751 1133 | F,1.269,3.741,7.198 1134 | M,1.99,3.058,3.78 1135 | F,2.435,7.909,8.135 1136 | M,1.093,2.536,3.578 1137 | F,2.008,3.269,8.053 1138 | M,1.743,2.595,3.223 1139 | M,3.025,3.915,4.643 1140 | F,5.661,15.861,11.515 1141 | M,1.069,3.488,3.517 1142 | F,1.043,2.206,2.733 1143 | F,2.235,10.401,8.087 1144 | F,1.093,2.117,3.671 1145 | M,1.114,2.131,3.996 1146 | F,2.912,37.854,24.136 1147 | F,4.048,5.196,8.923 1148 | F,1.211,2.26,5.48 1149 | M,2.517,3.497,4.888 1150 | F,2.662,3.387,4.375 1151 | M,1.592,2.48,3.214 1152 | F,1.518,3.953,5.534 1153 | M,1.535,2.527,3.028 1154 | F,1.196,4.131,4.143 1155 | F,1.62,3.1,3.399 1156 | M,1.15,2.178,12.385 1157 | M,1.103,5.685,4.914 1158 | F,1.305,2.644,4.146 1159 | M,1.844,2.701,3.342 1160 | F,1.625,2.964,3.202 1161 | M,5.336,5.591,4.795 1162 | M,1.682,2.697,5.006 1163 | F,1.079,2.726,4.405 1164 | F,1.092,7.033,6.297 1165 | M,1.05,2.065,2.753 1166 | F,1.112,2.749,3.054 1167 | F,1.577,2.601,4.497 1168 | M,2.487,6.585,5.537 1169 | F,3.07,3.857,3.894 1170 | M,1.291,2.524,3.006 1171 | M,1.505,2.696,4.048 1172 | F,2.289,7.315,6.662 1173 | F,1.206,2.613,3.905 1174 | F,1.573,5.834,8.628 1175 | M,1.1,2.091,4.193 1176 | M,1.382,3.979,4.435 1177 | M,1.1,2.122,5.403 1178 | F,1.364,3.402,3.636 1179 | F,1.288,2.482,2.903 1180 | M,1.328,2.461,4.749 1181 | F,1.15,4.272,4.195 1182 | M,1.076,2.124,5.947 1183 | M,1.175,2.285,2.894 1184 | M,1.147,2.67,3.163 1185 | F,1.94,9.271,10.215 1186 | F,1.88,4.451,5.905 1187 | F,1.551,3.757,3.728 1188 | M,1.049,2.087,3.115 1189 | M,1.518,2.48,2.97 1190 | M,1.042,4.291,4.01 1191 | M,1.009,2.008,3.125 1192 | M,1.243,2.491,2.933 1193 | M,1.147,2.839,3.436 1194 | F,1.571,2.775,3.92 1195 | F,3.744,5.215,8.802 1196 | F,1.889,3.879,7.317 1197 | M,2.073,2.986,3.703 1198 | M,4.513,6.035,5.388 1199 | F,1.653,17.356,12.781 1200 | F,1.539,6.018,8.722 1201 | F,1.585,2.478,16.196 1202 | F,2.73,5.418,4.674 1203 | M,1.278,2.333,5.883 1204 | M,2.21,3.099,4.266 1205 | M,1.696,2.641,3.021 1206 | M,1.199,2.552,3.926 1207 | F,1.007,2.974,4.195 1208 | M,1.125,2.189,4.39 1209 | M,1.826,4.41,4.363 1210 | F,1.542,2.811,3.673 1211 | M,1.174,2.923,4.319 1212 | F,1.33,2.294,3.325 1213 | M,1.718,2.658,3.391 1214 | M,1.07,2.977,3.323 1215 | F,1.327,3.65,3.901 1216 | M,1.309,2.744,3.214 1217 | M,1.479,2.629,3.0 1218 | F,1.446,3.283,4.138 1219 | F,1.258,2.378,4.956 1220 | M,2.053,2.92,4.038 1221 | M,1.035,3.602,3.7 1222 | M,1.018,2.286,3.251 1223 | M,1.313,2.536,3.274 1224 | M,3.111,4.219,4.995 1225 | F,1.177,2.158,3.036 1226 | M,1.099,2.426,2.873 1227 | F,3.732,13.451,12.24 1228 | F,1.096,2.937,4.2 1229 | M,1.265,2.445,2.964 1230 | F,1.921,3.732,3.81 1231 | M,1.163,3.215,3.587 1232 | F,1.139,3.989,4.328 1233 | F,1.288,5.78,5.179 1234 | F,2.169,5.992,5.607 1235 | F,3.352,3.946,6.636 1236 | F,1.016,52.314,33.69 1237 | F,1.094,4.96,4.739 1238 | M,4.915,5.534,6.02 1239 | F,1.567,2.51,4.044 1240 | F,1.493,15.843,11.702 1241 | F,2.316,4.115,4.482 1242 | F,1.021,14.329,10.063 1243 | F,1.007,2.869,3.916 1244 | M,5.546,6.036,5.28 1245 | F,2.415,13.223,10.021 1246 | M,1.99,3.066,3.303 1247 | M,1.088,2.152,3.633 1248 | M,1.382,2.549,3.308 1249 | M,3.993,4.603,5.294 1250 | M,3.881,4.963,4.49 1251 | F,1.005,8.338,10.629 1252 | M,2.01,2.813,3.554 1253 | M,1.003,2.309,2.823 1254 | F,7.981,8.023,6.504 1255 | M,1.31,2.322,6.805 1256 | M,6.145,6.645,5.909 1257 | F,1.258,8.303,6.82 1258 | F,1.189,3.585,6.973 1259 | M,1.209,2.257,2.98 1260 | M,1.927,3.45,4.284 1261 | M,1.118,2.428,2.933 1262 | F,2.712,8.312,7.531 1263 | M,1.563,4.909,4.699 1264 | F,5.765,6.679,5.853 1265 | M,8.799,8.403,6.571 1266 | M,1.108,2.226,7.361 1267 | M,4.756,5.579,4.811 1268 | M,1.024,4.765,4.37 1269 | F,1.014,2.492,3.269 1270 | M,4.221,4.852,4.378 1271 | M,5.157,5.723,6.922 1272 | F,1.083,26.91,20.823 1273 | F,1.339,2.665,3.467 1274 | M,1.406,4.683,4.565 1275 | M,2.675,3.677,3.637 1276 | M,1.639,3.164,4.474 1277 | M,2.106,3.677,4.527 1278 | M,1.394,2.389,3.087 1279 | F,1.686,48.864,31.254 1280 | M,1.944,5.722,5.438 1281 | M,1.953,3.909,4.07 1282 | F,1.001,8.461,6.719 1283 | M,1.054,2.212,2.902 1284 | F,1.254,9.115,7.484 1285 | F,1.032,11.571,25.874 1286 | F,1.273,2.655,3.553 1287 | M,1.28,2.301,2.808 1288 | F,3.541,7.77,10.317 1289 | F,1.52,4.058,4.115 1290 | F,1.845,2.821,3.122 1291 | F,2.977,4.38,4.082 1292 | F,1.339,2.867,3.258 1293 | M,1.001,2.521,3.47 1294 | M,1.183,2.386,3.063 1295 | F,2.32,5.271,8.031 1296 | F,3.192,8.535,8.2 1297 | M,1.242,2.8,3.273 1298 | M,1.19,2.605,7.388 1299 | F,3.639,15.741,11.869 1300 | M,1.241,2.313,2.796 1301 | F,1.696,3.793,4.187 1302 | M,1.179,2.864,4.846 1303 | F,1.053,2.389,3.102 1304 | F,1.416,2.655,6.77 1305 | M,3.609,4.65,4.715 1306 | M,1.619,3.285,3.845 1307 | M,1.124,3.377,3.656 1308 | M,1.775,2.883,5.723 1309 | F,2.078,5.892,5.391 1310 | M,1.213,2.248,3.307 1311 | M,1.506,2.566,3.502 1312 | M,1.773,3.093,3.83 1313 | F,1.091,2.281,3.049 1314 | F,5.278,31.3,22.586 1315 | F,1.35,2.456,3.67 1316 | M,7.012,7.588,6.202 1317 | M,1.111,2.252,2.945 1318 | M,1.392,2.977,3.244 1319 | M,1.095,2.302,3.298 1320 | M,1.005,2.703,3.95 1321 | M,1.145,3.505,3.784 1322 | M,1.294,2.659,4.788 1323 | F,1.326,2.496,2.995 1324 | F,2.968,26.899,18.096 1325 | F,1.657,3.892,4.677 1326 | M,1.33,2.378,3.281 1327 | M,9.128,8.732,8.156 1328 | M,1.61,3.125,3.93 1329 | F,1.215,19.519,15.059 1330 | F,1.8,14.286,10.98 1331 | M,1.408,2.389,3.045 1332 | F,2.901,11.68,8.65 1333 | M,3.109,4.102,4.078 1334 | M,1.257,2.436,3.129 1335 | F,1.512,3.45,5.434 1336 | M,1.167,2.967,3.898 1337 | F,1.637,9.04,8.788 1338 | M,11.431,10.861,9.838 1339 | M,2.444,3.18,4.364 1340 | F,1.256,7.27,11.57 1341 | F,1.051,2.073,7.496 1342 | F,5.478,6.343,5.505 1343 | M,1.28,2.483,3.143 1344 | M,1.19,2.47,3.344 1345 | M,1.209,2.292,3.445 1346 | M,1.4,2.558,3.259 1347 | M,4.809,5.857,5.861 1348 | F,8.646,8.563,7.446 1349 | F,1.192,7.379,6.63 1350 | F,1.242,2.209,2.84 1351 | M,1.431,2.408,2.935 1352 | F,1.004,16.868,11.81 1353 | F,1.101,3.147,9.115 1354 | F,3.955,4.428,4.113 1355 | M,1.015,2.455,5.575 1356 | M,1.055,2.314,3.126 1357 | F,1.314,2.368,3.285 1358 | F,1.93,3.384,5.608 1359 | F,1.17,4.048,5.839 1360 | M,1.2,2.628,3.046 1361 | M,1.2,3.441,4.508 1362 | M,2.802,3.746,4.024 1363 | M,1.137,2.154,2.887 1364 | F,1.512,2.563,3.02 1365 | M,120.514,97.848,60.597 1366 | M,1.919,2.82,4.012 1367 | M,1.228,3.778,5.151 1368 | M,2.065,2.951,6.36 1369 | F,4.658,5.651,4.886 1370 | M,1.263,2.535,3.178 1371 | M,1.851,2.852,3.135 1372 | M,1.04,2.559,3.496 1373 | M,3.09,4.108,5.366 1374 | M,1.052,3.896,4.4 1375 | F,1.263,8.151,6.681 1376 | F,1.478,4.205,5.38 1377 | M,1.165,2.394,10.759 1378 | F,1.689,4.466,4.08 1379 | M,1.498,2.86,4.233 1380 | F,1.88,3.147,3.594 1381 | F,1.244,2.455,4.257 1382 | M,1.484,2.719,3.163 1383 | F,2.307,3.578,3.714 1384 | M,2.298,3.25,4.384 1385 | F,1.871,2.699,4.522 1386 | M,1.478,2.94,4.204 1387 | M,1.749,2.624,3.819 1388 | M,1.046,2.707,3.072 1389 | F,1.375,2.615,5.66 1390 | F,2.674,3.576,3.92 1391 | F,1.596,4.281,4.153 1392 | F,4.141,75.921,47.682 1393 | M,1.164,2.372,3.036 1394 | F,1.052,10.024,8.614 1395 | M,1.637,2.535,3.6 1396 | M,1.049,2.36,4.051 1397 | M,2.142,3.472,9.607 1398 | M,1.16,2.332,3.791 1399 | M,1.472,2.435,2.934 1400 | M,2.303,3.048,4.09 1401 | M,2.172,3.15,3.74 1402 | F,1.409,5.791,5.593 1403 | F,6.434,132.155,81.013 1404 | F,1.411,3.364,3.546 1405 | F,1.178,2.644,3.126 1406 | M,1.197,2.341,2.832 1407 | M,1.975,2.819,4.107 1408 | F,1.333,3.249,4.716 1409 | F,1.312,4.268,6.259 1410 | M,1.01,2.47,3.583 1411 | M,1.2,2.165,2.787 1412 | F,2.676,5.417,5.975 1413 | M,2.256,3.534,3.958 1414 | M,1.986,3.103,3.316 1415 | F,1.012,22.58,18.093 1416 | F,1.014,2.428,5.936 1417 | F,1.205,9.068,7.736 1418 | F,1.379,2.557,3.372 1419 | F,3.329,4.289,4.177 1420 | F,1.275,2.529,2.991 1421 | M,1.186,3.418,4.469 1422 | F,1.527,7.033,11.898 1423 | F,3.424,4.923,4.364 1424 | F,1.956,3.494,4.037 1425 | F,2.641,3.329,3.478 1426 | F,1.106,4.911,4.782 1427 | F,1.069,35.081,23.21 1428 | M,1.481,3.168,3.589 1429 | M,1.818,2.765,3.067 1430 | M,4.713,5.1,9.149 1431 | M,1.261,2.45,4.802 1432 | F,1.237,3.016,4.744 1433 | F,1.437,2.713,3.436 1434 | F,1.782,7.184,6.823 1435 | F,1.518,6.824,6.693 1436 | F,1.9,5.608,5.089 1437 | M,1.27,2.218,2.75 1438 | F,2.694,16.679,12.286 1439 | M,1.106,2.262,5.11 1440 | M,1.209,2.179,3.523 1441 | M,2.102,3.364,3.545 1442 | F,1.227,5.555,5.433 1443 | F,1.736,5.036,4.814 1444 | F,1.185,2.918,3.83 1445 | M,1.109,3.205,4.073 1446 | F,1.196,2.822,3.647 1447 | F,2.975,4.979,7.715 1448 | M,1.362,3.895,4.41 1449 | M,1.136,2.761,3.275 1450 | M,1.214,2.212,3.247 1451 | M,1.001,2.78,3.383 1452 | M,2.024,4.219,4.894 1453 | F,1.136,7.782,6.074 1454 | M,1.577,2.751,3.528 1455 | M,1.013,2.956,3.185 1456 | F,2.458,3.265,11.698 1457 | M,1.109,2.211,3.099 1458 | M,1.002,3.152,3.452 1459 | M,1.196,2.174,2.76 1460 | M,3.546,4.258,4.164 1461 | F,1.165,9.532,8.034 1462 | M,1.419,2.596,6.218 1463 | M,1.299,2.275,2.812 1464 | F,1.19,3.171,3.478 1465 | M,3.71,4.83,4.458 1466 | M,2.177,3.104,4.134 1467 | M,2.049,4.284,4.009 1468 | F,1.453,21.431,17.167 1469 | F,2.39,3.354,3.596 1470 | M,1.359,2.327,3.531 1471 | M,1.367,2.445,3.722 1472 | F,1.405,3.384,6.312 1473 | M,1.145,2.186,2.825 1474 | F,3.619,4.477,5.348 1475 | M,1.161,3.888,3.952 1476 | F,1.117,5.102,4.851 1477 | F,1.15,3.905,4.339 1478 | M,2.34,3.681,3.676 1479 | F,2.079,2.866,3.468 1480 | M,1.321,2.322,4.979 1481 | M,1.007,2.582,3.045 1482 | F,6.42,9.346,7.299 1483 | F,1.074,9.021,8.601 1484 | F,2.594,4.971,4.599 1485 | M,2.14,3.287,3.459 1486 | M,4.019,4.636,4.284 1487 | M,2.101,3.793,8.04 1488 | M,1.223,3.247,3.621 1489 | M,1.141,2.379,3.083 1490 | F,1.268,2.936,4.602 1491 | F,1.12,2.16,2.742 1492 | F,1.888,7.282,5.906 1493 | M,2.401,3.663,4.337 1494 | F,1.682,3.485,3.788 1495 | M,1.108,2.403,3.537 1496 | M,1.019,3.368,3.431 1497 | F,1.544,11.045,8.814 1498 | F,1.364,2.553,3.606 1499 | F,1.118,8.842,6.819 1500 | F,1.258,3.454,3.564 1501 | F,1.477,2.524,6.737 1502 | F,1.651,3.063,3.828 1503 | M,1.382,2.873,3.148 1504 | F,5.912,15.991,11.112 1505 | F,1.024,2.165,3.746 1506 | M,1.71,3.01,3.544 1507 | M,3.325,4.411,4.543 1508 | M,1.144,2.252,3.069 1509 | M,1.128,2.824,5.022 1510 | M,2.051,2.885,4.235 1511 | M,1.395,2.431,6.629 1512 | F,11.306,10.246,11.827 1513 | F,1.56,3.661,4.885 1514 | F,3.614,4.52,4.151 1515 | M,1.006,2.038,15.733 1516 | M,1.088,3.309,3.719 1517 | F,1.78,2.922,3.198 1518 | M,1.309,2.634,8.42 1519 | M,2.469,3.309,3.841 1520 | F,1.323,4.04,4.327 1521 | M,1.867,3.203,3.331 1522 | M,1.518,3.061,3.524 1523 | M,1.066,2.202,2.819 1524 | M,1.883,2.726,3.773 1525 | M,1.845,3.773,3.667 1526 | M,1.063,4.683,4.614 1527 | M,1.511,3.685,3.632 1528 | F,1.227,2.29,3.995 1529 | M,1.359,3.091,5.735 1530 | F,1.316,3.388,3.464 1531 | M,1.057,2.52,2.964 1532 | F,1.09,3.962,4.389 1533 | M,1.046,2.386,6.82 1534 | M,1.113,2.636,3.252 1535 | F,2.603,5.21,5.384 1536 | F,1.012,3.646,5.055 1537 | M,1.326,2.324,4.759 1538 | M,2.241,4.132,3.973 1539 | M,1.054,2.757,4.795 1540 | M,1.138,4.557,4.678 1541 | F,1.915,7.294,7.552 1542 | F,1.684,4.222,4.201 1543 | M,1.513,3.963,4.142 1544 | F,1.099,4.35,4.184 1545 | F,2.206,3.504,5.774 1546 | F,1.079,2.319,2.961 1547 | F,1.075,3.893,4.419 1548 | M,2.209,3.638,3.86 1549 | M,1.259,3.149,3.313 1550 | F,1.206,2.644,3.412 1551 | M,1.177,3.545,4.462 1552 | M,1.217,2.574,3.343 1553 | M,1.231,2.826,3.276 1554 | M,1.815,3.532,3.823 1555 | F,1.147,18.38,13.975 1556 | F,1.217,2.664,4.029 1557 | M,2.114,3.108,3.321 1558 | F,3.393,14.711,10.871 1559 | F,1.607,8.535,6.685 1560 | M,1.057,2.268,6.388 1561 | M,1.477,2.662,3.787 1562 | M,1.639,3.139,3.324 1563 | M,1.207,2.191,2.855 1564 | F,2.411,3.826,3.754 1565 | M,2.142,3.01,3.439 1566 | M,1.534,2.759,4.147 1567 | F,1.081,6.131,5.128 1568 | F,1.818,2.833,3.232 1569 | F,3.091,92.933,57.395 1570 | F,1.155,3.176,4.189 1571 | F,4.92,9.223,14.332 1572 | M,2.091,3.06,4.328 1573 | M,1.196,2.457,2.983 1574 | F,1.615,35.446,23.867 1575 | F,1.202,4.836,5.003 1576 | F,1.054,2.075,3.208 1577 | F,2.385,3.47,6.707 1578 | F,1.73,3.004,3.984 1579 | M,1.61,4.765,4.33 1580 | M,1.08,2.821,3.179 1581 | M,1.267,2.766,4.936 1582 | M,2.847,3.507,3.544 1583 | M,1.093,2.94,3.235 1584 | M,1.025,2.103,3.254 1585 | M,1.112,2.156,2.817 1586 | M,1.155,3.286,4.48 1587 | M,2.15,2.922,3.428 1588 | M,1.686,2.575,3.289 1589 | F,1.009,15.696,10.918 1590 | M,1.009,2.129,2.691 1591 | F,1.52,6.533,6.773 1592 | M,1.651,3.036,3.258 1593 | M,1.069,2.104,3.231 1594 | F,1.602,7.133,6.339 1595 | F,1.147,2.432,3.477 1596 | F,1.228,4.922,4.626 1597 | M,1.301,2.448,3.71 1598 | F,1.064,3.487,3.9 1599 | M,5.205,7.343,5.885 1600 | M,6.174,6.265,5.186 1601 | F,1.342,2.791,3.401 1602 | M,1.16,2.275,3.278 1603 | F,4.914,5.836,5.087 1604 | F,2.344,4.71,5.583 1605 | M,1.904,3.576,3.601 1606 | M,1.363,3.619,3.904 1607 | F,1.303,2.32,3.449 1608 | M,2.129,3.406,4.528 1609 | F,1.443,4.098,3.95 1610 | M,1.716,3.003,3.203 1611 | M,1.518,3.244,3.752 1612 | M,1.864,4.521,4.191 1613 | F,1.051,5.607,5.504 1614 | F,1.268,2.463,2.901 1615 | F,1.096,27.338,18.365 1616 | M,1.149,3.259,3.607 1617 | M,1.119,2.246,2.829 1618 | M,1.419,2.388,3.161 1619 | F,1.01,6.993,6.132 1620 | F,5.268,54.958,34.425 1621 | F,1.442,2.529,3.98 1622 | F,1.027,4.264,7.324 1623 | F,1.773,2.631,3.83 1624 | M,1.17,2.15,3.235 1625 | M,1.058,2.85,3.928 1626 | M,2.428,4.05,5.931 1627 | M,1.117,2.278,6.757 1628 | M,1.057,2.308,3.14 1629 | M,1.03,2.81,5.368 1630 | M,1.919,3.834,3.924 1631 | M,1.703,2.699,3.779 1632 | F,1.004,6.366,9.388 1633 | M,1.133,2.2,2.728 1634 | F,1.84,3.643,7.153 1635 | F,1.086,5.138,7.212 1636 | F,1.537,5.049,4.6 1637 | F,1.127,3.313,3.81 1638 | M,1.347,2.814,3.151 1639 | F,2.746,3.461,4.861 1640 | M,1.197,2.302,3.691 1641 | M,1.784,2.729,4.483 1642 | F,1.334,2.374,3.298 1643 | F,1.052,2.356,3.715 1644 | M,1.251,3.312,4.586 1645 | F,2.51,13.578,9.617 1646 | M,6.091,6.42,5.312 1647 | M,2.541,3.529,4.587 1648 | M,1.093,2.351,3.111 1649 | F,1.236,30.289,21.327 1650 | M,2.434,5.026,4.416 1651 | F,1.497,2.729,3.126 1652 | F,2.114,3.017,3.572 1653 | F,2.121,2.966,3.584 1654 | F,1.038,2.698,5.053 1655 | M,1.233,2.423,3.23 1656 | M,1.385,2.428,4.679 1657 | F,4.273,18.461,12.922 1658 | M,3.135,4.705,4.256 1659 | F,1.317,5.749,5.351 1660 | M,1.052,2.337,3.073 1661 | M,1.296,3.515,3.935 1662 | M,1.468,4.333,4.568 1663 | F,3.234,13.27,9.405 1664 | M,1.191,2.28,3.297 1665 | F,1.203,9.801,7.383 1666 | M,1.638,2.696,3.308 1667 | F,1.422,2.506,5.77 1668 | F,1.115,5.573,4.848 1669 | M,1.081,2.948,3.283 1670 | F,1.4,91.896,56.981 1671 | F,2.129,4.015,3.853 1672 | M,2.126,3.022,3.38 1673 | M,6.429,6.37,5.26 1674 | F,1.273,3.063,3.774 1675 | F,1.282,3.866,4.463 1676 | M,1.001,2.309,3.606 1677 | M,2.425,3.213,5.222 1678 | M,1.682,2.747,3.344 1679 | F,2.085,16.285,12.066 1680 | F,1.374,3.319,3.435 1681 | F,3.54,5.292,5.108 1682 | M,1.015,2.297,4.142 1683 | M,1.063,2.261,3.245 1684 | M,1.266,2.238,2.98 1685 | F,1.045,2.393,2.903 1686 | F,1.047,3.238,3.92 1687 | F,1.519,4.103,7.372 1688 | F,1.129,3.203,3.377 1689 | M,1.636,2.704,3.424 1690 | M,3.764,5.075,4.73 1691 | M,2.383,3.689,4.464 1692 | M,1.153,4.086,3.93 1693 | F,1.048,2.073,2.781 1694 | M,4.481,5.475,5.415 1695 | F,13.479,12.062,9.712 1696 | F,1.264,2.704,3.638 1697 | M,1.362,3.841,3.707 1698 | F,1.082,6.207,7.409 1699 | M,1.858,3.209,7.941 1700 | F,1.315,3.051,4.258 1701 | M,2.253,3.023,5.265 1702 | M,1.538,2.557,3.78 1703 | M,1.022,2.311,3.442 1704 | M,1.226,2.422,3.071 1705 | F,2.286,4.043,3.885 1706 | F,1.791,2.67,3.025 1707 | M,1.65,2.996,3.507 1708 | F,1.747,3.584,4.054 1709 | F,1.591,2.493,3.283 1710 | F,1.669,21.077,14.067 1711 | M,1.623,2.59,3.062 1712 | F,1.464,2.616,3.076 1713 | F,2.032,6.525,5.324 1714 | F,1.259,2.85,3.978 1715 | M,1.38,2.749,3.099 1716 | F,1.293,2.241,2.862 1717 | F,1.125,3.01,3.281 1718 | F,1.214,2.202,4.207 1719 | M,1.029,2.121,4.138 1720 | F,1.218,2.464,2.97 1721 | M,1.281,4.927,4.882 1722 | M,1.05,2.193,3.248 1723 | M,1.133,3.113,3.431 1724 | F,1.154,2.995,3.98 1725 | F,1.138,9.614,7.628 1726 | M,1.241,2.716,3.084 1727 | F,1.081,2.074,8.096 1728 | F,1.93,2.895,4.206 1729 | F,1.233,2.226,7.86 1730 | F,1.067,2.173,2.823 1731 | F,1.569,2.794,4.762 1732 | F,1.104,6.48,5.727 1733 | F,1.03,5.33,8.478 1734 | F,1.093,2.463,3.98 1735 | F,1.313,3.019,3.327 1736 | F,1.806,9.985,7.414 1737 | F,1.67,2.63,3.075 1738 | F,1.003,3.56,4.748 1739 | M,2.199,3.009,3.211 1740 | M,1.227,7.606,6.302 1741 | F,1.767,3.563,4.232 1742 | M,1.017,3.546,4.572 1743 | M,1.284,2.296,3.083 1744 | F,1.01,124.598,76.163 1745 | M,2.333,3.091,3.375 1746 | M,1.109,2.112,2.69 1747 | M,1.753,3.541,7.367 1748 | F,1.176,6.312,6.116 1749 | F,1.075,2.456,2.875 1750 | F,3.788,4.623,4.202 1751 | F,1.571,3.533,3.71 1752 | M,3.024,5.548,5.644 1753 | F,1.201,4.168,4.307 1754 | M,2.424,4.116,4.24 1755 | F,4.141,12.342,11.326 1756 | F,1.286,2.415,5.694 1757 | F,3.23,5.433,5.111 1758 | M,1.226,6.077,5.899 1759 | M,1.217,2.214,2.859 1760 | F,15.308,14.403,10.183 1761 | M,4.584,5.611,8.24 1762 | F,1.139,116.042,71.952 1763 | M,2.478,3.235,3.941 1764 | F,1.233,3.001,5.806 1765 | M,6.941,7.465,5.892 1766 | F,2.58,5.021,4.669 1767 | M,3.243,5.018,5.149 1768 | M,1.532,2.469,3.195 1769 | M,1.19,2.51,5.141 1770 | M,1.116,2.534,3.23 1771 | F,1.455,7.625,6.073 1772 | M,1.745,3.633,5.273 1773 | M,1.968,3.061,3.239 1774 | F,1.098,3.911,5.197 1775 | M,1.468,2.377,2.83 1776 | F,1.332,4.924,4.865 1777 | F,1.124,2.118,2.841 1778 | F,1.496,4.597,9.126 1779 | F,1.175,3.369,3.824 1780 | F,1.467,27.294,17.799 1781 | M,1.118,2.168,3.609 1782 | M,3.161,3.939,3.953 1783 | M,1.229,3.28,3.935 1784 | M,1.602,2.808,3.35 1785 | F,1.067,7.327,6.265 1786 | M,1.644,2.835,3.251 1787 | F,1.172,4.716,5.873 1788 | F,4.796,13.967,10.292 1789 | F,1.285,2.297,2.807 1790 | M,1.596,3.715,5.905 1791 | F,1.129,2.365,3.393 1792 | M,2.687,4.068,4.188 1793 | M,2.261,3.393,3.649 1794 | F,1.151,2.72,3.95 1795 | M,3.353,6.149,5.35 1796 | M,1.021,3.034,4.041 1797 | M,2.01,2.951,4.582 1798 | M,1.358,2.381,3.18 1799 | M,2.465,3.364,4.01 1800 | M,1.368,2.467,3.054 1801 | F,1.034,2.256,3.641 1802 | M,1.137,3.932,4.319 1803 | F,13.333,21.345,14.811 1804 | M,1.226,3.379,3.511 1805 | F,1.091,3.078,4.518 1806 | F,2.269,7.519,6.209 1807 | F,1.023,2.695,3.407 1808 | M,1.035,3.142,4.529 1809 | F,1.193,13.781,10.748 1810 | M,1.025,2.372,2.864 1811 | M,15.272,13.707,10.072 1812 | M,1.799,2.986,3.235 1813 | M,1.443,2.468,3.459 1814 | M,2.266,3.052,3.486 1815 | M,1.721,2.79,4.122 1816 | M,1.1,2.88,4.048 1817 | M,1.132,2.663,22.71 1818 | F,2.749,9.741,7.517 1819 | F,1.228,3.17,3.444 1820 | M,1.346,2.331,2.897 1821 | M,1.282,2.561,3.435 1822 | M,1.027,2.038,2.826 1823 | F,1.84,3.58,6.735 1824 | F,1.475,2.682,3.068 1825 | M,1.757,3.636,4.45 1826 | M,1.177,2.198,3.071 1827 | M,1.298,2.526,3.479 1828 | M,1.113,2.302,3.262 1829 | M,1.313,3.286,3.773 1830 | F,1.699,4.096,5.007 1831 | F,4.252,5.687,5.489 1832 | F,1.724,4.351,7.638 1833 | M,1.451,2.471,3.312 1834 | F,1.309,3.554,7.072 1835 | M,1.057,2.231,3.759 1836 | M,1.383,2.353,4.033 1837 | F,1.088,6.626,8.344 1838 | M,1.547,2.631,3.088 1839 | F,1.925,3.204,3.649 1840 | M,4.323,4.659,5.805 1841 | F,1.193,2.201,2.839 1842 | M,1.288,2.352,3.164 1843 | M,1.106,2.256,2.806 1844 | F,2.862,6.278,5.288 1845 | F,2.384,3.807,4.468 1846 | M,2.108,3.727,3.892 1847 | M,1.03,2.436,3.144 1848 | F,1.502,3.049,3.826 1849 | M,1.143,2.185,3.318 1850 | F,1.066,2.054,3.211 1851 | F,2.14,3.657,3.92 1852 | F,1.126,2.924,3.312 1853 | F,1.415,3.019,3.724 1854 | F,1.453,7.235,6.113 1855 | F,1.127,2.229,4.596 1856 | M,1.403,2.373,2.831 1857 | F,1.028,2.387,3.568 1858 | F,1.0,3.268,4.227 1859 | M,2.891,4.16,8.593 1860 | M,1.308,3.664,5.08 1861 | F,3.287,4.267,4.576 1862 | M,1.409,2.383,2.998 1863 | F,1.326,3.506,3.511 1864 | F,1.192,2.667,3.207 1865 | F,1.044,78.214,50.513 1866 | F,1.204,2.213,9.888 1867 | F,1.598,2.762,4.218 1868 | F,2.053,6.512,6.131 1869 | M,1.476,2.593,3.466 1870 | M,2.034,3.207,3.911 1871 | M,1.09,2.979,3.188 1872 | M,1.549,2.97,3.415 1873 | M,2.919,3.968,3.98 1874 | F,1.131,4.676,12.23 1875 | F,1.138,2.193,2.716 1876 | F,1.994,2.925,4.482 1877 | M,2.307,3.484,3.755 1878 | F,1.153,2.821,3.14 1879 | F,1.223,280.972,170.335 1880 | M,1.648,3.446,3.533 1881 | F,1.289,17.353,11.839 1882 | M,1.631,2.587,3.606 1883 | F,1.409,4.325,4.013 1884 | F,2.102,2.916,3.158 1885 | F,2.547,6.569,5.789 1886 | M,2.71,3.385,3.498 1887 | F,1.604,4.965,4.86 1888 | F,1.607,2.809,3.444 1889 | M,1.348,2.695,3.068 1890 | F,1.014,2.469,3.814 1891 | M,1.195,2.165,3.285 1892 | M,1.033,2.591,3.531 1893 | M,1.334,2.53,4.245 1894 | M,2.578,3.906,3.747 1895 | M,1.575,2.483,2.903 1896 | F,1.756,3.959,4.403 1897 | M,1.11,2.11,2.992 1898 | M,1.164,2.195,7.943 1899 | M,1.093,2.876,3.348 1900 | F,2.521,3.573,3.935 1901 | M,1.179,2.183,3.866 1902 | M,1.512,2.472,3.421 1903 | M,1.079,2.126,2.71 1904 | M,1.068,3.083,3.278 1905 | F,1.238,3.917,4.389 1906 | M,1.222,3.004,3.459 1907 | M,1.221,2.302,3.562 1908 | M,1.583,2.932,3.706 1909 | M,1.209,3.543,3.526 1910 | M,2.079,3.211,3.335 1911 | M,1.049,3.212,4.505 1912 | F,1.217,2.508,3.037 1913 | M,1.739,5.129,4.932 1914 | F,1.587,2.573,7.283 1915 | F,1.066,5.876,11.187 1916 | F,1.336,2.572,5.091 1917 | F,1.203,2.321,5.593 1918 | M,1.648,2.895,4.806 1919 | M,1.072,2.22,2.77 1920 | F,1.742,2.937,5.468 1921 | F,1.366,3.232,3.771 1922 | F,1.174,104.579,64.178 1923 | M,1.99,3.267,3.765 1924 | F,1.11,2.551,3.02 1925 | F,1.086,85.989,53.052 1926 | M,1.008,2.145,3.014 1927 | M,2.685,3.982,3.977 1928 | F,1.404,2.752,5.715 1929 | M,1.438,3.122,3.462 1930 | M,1.063,2.543,4.018 1931 | F,1.059,3.655,3.597 1932 | F,1.225,3.198,8.131 1933 | F,1.438,2.735,3.081 1934 | F,1.828,4.535,4.352 1935 | M,1.413,3.526,3.528 1936 | F,2.437,3.188,8.857 1937 | M,1.267,2.877,3.151 1938 | F,1.014,10.805,8.218 1939 | F,1.32,4.188,4.928 1940 | M,1.045,2.162,2.891 1941 | F,1.215,2.822,3.098 1942 | M,8.207,8.468,6.615 1943 | M,2.648,3.516,4.236 1944 | F,1.144,2.125,3.051 1945 | M,1.266,2.258,3.836 1946 | M,1.326,2.403,3.632 1947 | F,2.058,3.624,4.35 1948 | F,1.017,2.701,3.092 1949 | F,1.02,7.015,14.644 1950 | M,1.064,2.156,3.082 1951 | M,1.64,2.743,3.194 1952 | M,1.307,3.149,3.793 1953 | M,2.573,4.088,4.56 1954 | F,1.182,2.455,3.392 1955 | M,1.399,2.515,3.48 1956 | F,1.847,2.9,3.222 1957 | M,1.483,2.425,4.248 1958 | M,1.21,2.539,3.572 1959 | M,1.086,2.233,3.635 1960 | F,1.475,3.648,3.676 1961 | F,1.08,3.776,4.285 1962 | F,4.059,6.294,6.302 1963 | M,1.474,4.258,4.346 1964 | M,1.101,2.193,2.765 1965 | F,1.892,13.288,9.417 1966 | M,1.056,2.066,3.166 1967 | F,2.093,2.912,4.853 1968 | F,1.357,2.432,25.572 1969 | F,1.074,4.227,4.667 1970 | M,1.019,2.359,2.943 1971 | F,12.289,11.263,8.573 1972 | M,1.174,2.205,2.777 1973 | F,4.576,6.211,5.555 1974 | F,1.417,30.406,21.745 1975 | F,1.418,2.603,3.355 1976 | F,1.049,2.459,2.913 1977 | M,4.504,4.856,4.401 1978 | F,1.935,4.508,5.141 1979 | M,1.441,4.021,4.484 1980 | M,1.066,2.167,2.807 1981 | F,1.101,3.156,5.106 1982 | M,1.327,3.716,3.792 1983 | M,1.252,2.811,3.521 1984 | F,1.504,3.747,3.931 1985 | M,1.041,2.518,3.586 1986 | M,1.021,2.675,3.243 1987 | F,1.43,5.564,6.207 1988 | F,1.015,3.142,3.833 1989 | F,1.031,2.495,3.831 1990 | M,1.266,2.309,4.721 1991 | M,1.032,3.595,3.851 1992 | F,1.276,2.295,3.465 1993 | M,1.148,2.295,2.878 1994 | F,1.11,4.759,5.384 1995 | M,1.296,2.666,3.116 1996 | F,1.066,2.97,4.296 1997 | M,1.24,2.237,4.635 1998 | M,1.33,2.326,4.998 1999 | F,2.425,5.894,6.682 2000 | M,3.858,4.582,4.562 2001 | M,1.202,2.34,3.968 2002 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy==1.19.2 2 | pandas==0.23.4 3 | jupyter==1.0.0 4 | matplotlib==3.0.0 5 | seaborn --------------------------------------------------------------------------------