{ "cells": [ { "cell_type": "markdown", "id": "00cac1f9", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# ACRO Demonstration" ] }, { "cell_type": "code", "execution_count": 1, "id": "e33fd4fb", "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "import os\n", "\n", "import numpy as np\n", "import pandas as pd" ] }, { "cell_type": "code", "execution_count": 2, "id": "c01cfe12", "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "# uncomment this line if acro is not installed\n", "# ie you are in development mode\n", "# sys.path.insert(0, os.path.abspath(\"..\"))" ] }, { "cell_type": "code", "execution_count": 3, "id": "cc8d993a", "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "from acro import ACRO, add_constant, add_to_acro" ] }, { "cell_type": "markdown", "id": "530efcfe", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Instantiate ACRO" ] }, { "cell_type": "code", "execution_count": 4, "id": "4b8a77e2", "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:version: 0.4.8\n", "INFO:acro:config: {'safe_threshold': 10, 'safe_dof_threshold': 10, 'safe_nk_n': 2, 'safe_nk_k': 0.9, 'safe_pratio_p': 0.1, 'check_missing_values': False, 'survival_safe_threshold': 10, 'zeros_are_disclosive': True}\n", "INFO:acro:automatic suppression: True\n" ] } ], "source": [ "acro = ACRO(suppress=True)" ] }, { "cell_type": "markdown", "id": "27a2baaa", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Load test data\n", "The dataset used in this notebook is the nursery dataset from OpenML. \n", "- The dataset can be read directly from OpenML using the code commented in the next cell.\n", "- In this version, it can be read directly from the local machine if it has been downloaded. \n", "- The code below reads the data from a folder called \"data\" which we assume is at the same level as the folder where you are working.\n", "- The path might need to be changed if the data has been downloaded and stored elsewhere.\n", " - for example use: \n", " path = os.path.join(\"data\", \"nursery.arff\") \n", " if the data is in a sub-folder of your work folder" ] }, { "cell_type": "code", "execution_count": 5, "id": "ac790b2b-b02f-49f7-8237-a033abed6e87", "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
parentshas_nursformchildrenhousingfinancesocialhealthrecommend
0usualpropercomplete1convenientconvenientnonprobrecommendedrecommend
1usualpropercomplete1convenientconvenientnonprobprioritypriority
2usualpropercomplete1convenientconvenientnonprobnot_recomnot_recom
3usualpropercomplete1convenientconvenientslightly_probrecommendedrecommend
4usualpropercomplete1convenientconvenientslightly_probprioritypriority
\n", "
" ], "text/plain": [ " parents has_nurs form children housing finance social \\\n", "0 usual proper complete 1 convenient convenient nonprob \n", "1 usual proper complete 1 convenient convenient nonprob \n", "2 usual proper complete 1 convenient convenient nonprob \n", "3 usual proper complete 1 convenient convenient slightly_prob \n", "4 usual proper complete 1 convenient convenient slightly_prob \n", "\n", " health recommend \n", "0 recommended recommend \n", "1 priority priority \n", "2 not_recom not_recom \n", "3 recommended recommend \n", "4 priority priority " ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from scipy.io.arff import loadarff\n", "\n", "path = os.path.join(\"../data\", \"nursery.arff\")\n", "data = loadarff(path)\n", "df = pd.DataFrame(data[0])\n", "df = df.select_dtypes([object])\n", "df = df.stack().str.decode(\"utf-8\").unstack()\n", "df.rename(columns={\"class\": \"recommend\"}, inplace=True)\n", "df.head()" ] }, { "cell_type": "markdown", "id": "ea2a0d76-ba68-4a74-93c3-bdaa88c48929", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Convert 'more than 3' children to random between 4 and 10\n", "Change the children column from categorical to numeric in order to be able to test some of the ACRO functions that require a numeric feature" ] }, { "cell_type": "code", "execution_count": 6, "id": "b43810a8-4da9-4cec-a613-e2562ed95601", "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " children column entries in raw file ['1' '2' '3' 'more']\n" ] } ], "source": [ "print(f\" children column entries in raw file {df.children.unique()}\")" ] }, { "cell_type": "code", "execution_count": 7, "id": "042f8e9d-b33b-4daf-851e-9f70b5d4859a", "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "df[\"children\"].replace(to_replace={\"more\": \"4\"}, inplace=True)\n", "df[\"children\"] = pd.to_numeric(df[\"children\"])\n", "\n", "df[\"children\"] = df.apply(\n", " lambda row: (\n", " row[\"children\"] if row[\"children\"] in (1, 2, 3) else np.random.randint(4, 10)\n", " ),\n", " axis=1,\n", ")" ] }, { "cell_type": "markdown", "id": "d098c704", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Examples of producing tabular output\n", "We rely on the industry-standard package **pandas** for tabulating data. \n", "In the next few examples we show:\n", "- first, how a researcher would normally make a call in pandas, saving the results in a variable that they can view on screen (or save to file?)\n", "- then how the call is identical in SACRO, except that:\n", " - \"pd\" is replaced by \"acro\"\n", " - the researcher immediately sees a copy of what the TRE output checker will see.\n", " " ] }, { "cell_type": "markdown", "id": "4ae844a0", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Pandas crosstab\n", "This is an example of crosstab using pandas. \n", "We first make the call, then the second line print the outputs to screen." ] }, { "cell_type": "code", "execution_count": 8, "id": "961684cb", "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "parents great_pret pretentious usual\n", "recommend \n", "not_recom 1440 1440 1440\n", "priority 858 1484 1924\n", "recommend 0 0 2\n", "spec_prior 2022 1264 758\n", "very_recom 0 132 196\n" ] } ], "source": [ "table = pd.crosstab(df.recommend, df.parents)\n", "print(table)" ] }, { "cell_type": "markdown", "id": "d642ed00", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### ACRO crosstab\n", "This is an example of crosstab using ACRO. \n", "The INFO lines show the researcher what will be reported to the output checkers.\n", "Then the (suppressed as necessary) table is shown via. the print command as before." ] }, { "cell_type": "code", "execution_count": 9, "id": "bb4b2677", "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:get_summary(): fail; threshold: 4 cells suppressed; \n", "INFO:acro:outcome_df:\n", "----------------------------------------------------|\n", "parents |great_pret |pretentious |usual |\n", "recommend | | | |\n", "----------------------------------------------------|\n", "not_recom | ok | ok | ok|\n", "priority | ok | ok | ok|\n", "recommend | threshold; | threshold; | threshold; |\n", "spec_prior | ok | ok | ok|\n", "very_recom | threshold; | ok | ok|\n", "----------------------------------------------------|\n", "\n", "INFO:acro:records:add(): output_0\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "parents great_pret pretentious usual\n", "recommend \n", "not_recom 1440.0 1440.0 1440.0\n", "priority 858.0 1484.0 1924.0\n", "recommend NaN NaN NaN\n", "spec_prior 2022.0 1264.0 758.0\n", "very_recom NaN 132.0 196.0\n" ] } ], "source": [ "safe_table = acro.crosstab(\n", " df.recommend,\n", " df.parents,\n", ")\n", "print(safe_table)" ] }, { "cell_type": "markdown", "id": "b3d09450", "metadata": {}, "source": [ "### ACRO crosstab with totals\n", "This is an example of crosstab with totals columns and suppression. \n", "Note that when margins is true any row or column where all the cells are discolsive is deleted. If you wish to see such row or column set show_suppressed to True. \n", "show_suppressed parameter does not work with herichical tables and when the aggregation function is the standard deviation." ] }, { "cell_type": "code", "execution_count": 10, "id": "42825f24", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:get_summary(): fail; threshold: 5 cells suppressed; \n", "INFO:acro:outcome_df:\n", "------------------------------------------------------------------|\n", "parents |great_pret |pretentious |usual |All |\n", "recommend | | | | |\n", "------------------------------------------------------------------|\n", "not_recom | ok | ok | ok | ok|\n", "priority | ok | ok | ok | ok|\n", "recommend | threshold; | threshold; | threshold; | threshold; |\n", "spec_prior | ok | ok | ok | ok|\n", "very_recom | threshold; | ok | ok | ok|\n", "All | ok | ok | ok | ok|\n", "------------------------------------------------------------------|\n", "\n", "INFO:acro:records:add(): output_1\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "parents great_pret pretentious usual All\n", "recommend \n", "not_recom 1440.0 1440 1440 4320\n", "priority 858.0 1484 1924 4266\n", "spec_prior 2022.0 1264 758 4044\n", "very_recom NaN 132 196 328\n", "All 4320.0 4320 4318 12958\n" ] } ], "source": [ "safe_table = acro.crosstab(df.recommend, df.parents, margins=True)\n", "print(safe_table)" ] }, { "cell_type": "markdown", "id": "b3e48dec", "metadata": {}, "source": [ "### ACRO crosstab without suppression\n", "This is an example of crosstab without suppressing the cells that violate the disclosure tests. \n", "Note that you need to change the value of the suppress variable in the acro object to False. Then run the crosstab command. \n", "If you wish to continue the research while suppressing the outputs, turn on the suppress variable otherwise leave it as it is." ] }, { "cell_type": "code", "execution_count": 11, "id": "27329e57", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:get_summary(): fail; threshold: 4 cells may need suppressing; \n", "INFO:acro:outcome_df:\n", "----------------------------------------------------|\n", "parents |great_pret |pretentious |usual |\n", "recommend | | | |\n", "----------------------------------------------------|\n", "not_recom | ok | ok | ok|\n", "priority | ok | ok | ok|\n", "recommend | threshold; | threshold; | threshold; |\n", "spec_prior | ok | ok | ok|\n", "very_recom | threshold; | ok | ok|\n", "----------------------------------------------------|\n", "\n", "INFO:acro:records:add(): output_2\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "parents great_pret pretentious usual\n", "recommend \n", "not_recom 1440 1440 1440\n", "priority 858 1484 1924\n", "recommend 0 0 2\n", "spec_prior 2022 1264 758\n", "very_recom 0 132 196\n" ] } ], "source": [ "acro.suppress = False\n", "\n", "safe_table = acro.crosstab(df.recommend, df.parents)\n", "print(safe_table)" ] }, { "cell_type": "code", "execution_count": 12, "id": "ed5134ab", "metadata": {}, "outputs": [], "source": [ "acro.suppress = True" ] }, { "cell_type": "markdown", "id": "8b603548", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### ACRO crosstab with aggregation function" ] }, { "cell_type": "code", "execution_count": 13, "id": "298d2b40", "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:get_summary(): fail; threshold: 1 cells suppressed; p-ratio: 4 cells suppressed; nk-rule: 4 cells suppressed; \n", "INFO:acro:outcome_df:\n", "------------------------------------------------------------------------------------|\n", "parents |great_pret |pretentious |usual |\n", "recommend | | | |\n", "------------------------------------------------------------------------------------|\n", "not_recom | ok | ok | ok|\n", "priority | ok | ok | ok|\n", "recommend | p-ratio; nk-rule; | p-ratio; nk-rule; | threshold; p-ratio; nk-rule; |\n", "spec_prior | ok | ok | ok|\n", "very_recom | p-ratio; nk-rule; | ok | ok|\n", "------------------------------------------------------------------------------------|\n", "\n", "INFO:acro:records:add(): output_3\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "parents great_pret pretentious usual\n", "recommend \n", "not_recom 1440.0 1440.0 1440.0\n", "priority 858.0 1484.0 1924.0\n", "recommend NaN NaN NaN\n", "spec_prior 2022.0 1264.0 758.0\n", "very_recom NaN 132.0 196.0\n" ] } ], "source": [ "safe_table = acro.crosstab(\n", " df.recommend, df.parents, values=df.children, aggfunc=\"count\"\n", ")\n", "print(safe_table)" ] }, { "cell_type": "code", "execution_count": 14, "id": "b4aea046", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:get_summary(): fail; threshold: 2 cells suppressed; p-ratio: 8 cells suppressed; nk-rule: 8 cells suppressed; \n", "INFO:acro:outcome_df:\n", "---------------------------------------------------------------------------------------------------------------------------------------------------------|\n", " mode_aggfunc |mean |\n", "parents great_pret pretentious usual |great_pret pretentious usual |\n", "recommend | |\n", "---------------------------------------------------------------------------------------------------------------------------------------------------------|\n", "not_recom ok ok ok | ok ok ok|\n", "priority ok ok ok | ok ok ok|\n", "recommend p-ratio; nk-rule; p-ratio; nk-rule; threshold; p-ratio; nk-rule; | p-ratio; nk-rule; p-ratio; nk-rule; threshold; p-ratio; nk-rule; |\n", "spec_prior ok ok ok | ok ok ok|\n", "very_recom p-ratio; nk-rule; ok ok | p-ratio; nk-rule; ok ok|\n", "---------------------------------------------------------------------------------------------------------------------------------------------------------|\n", "\n", "INFO:acro:records:add(): output_4\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " mode_aggfunc mean \n", "parents great_pret pretentious usual great_pret pretentious usual\n", "recommend \n", "not_recom 2.0 1.0 1.0 3.125694 3.105556 3.074306\n", "priority 1.0 1.0 1.0 2.665501 3.030323 3.116944\n", "recommend NaN NaN NaN NaN NaN NaN\n", "spec_prior 3.0 3.0 3.0 3.353610 3.370253 3.393140\n", "very_recom NaN 1.0 1.0 NaN 2.204545 2.244898\n" ] } ], "source": [ "safe_table = acro.crosstab(\n", " df.recommend, df.parents, values=df.children, aggfunc=[\"mode\", \"mean\"]\n", ")\n", "print(safe_table)" ] }, { "cell_type": "markdown", "id": "d66e565b", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### ACRO pivot_table\n", "This is an example of pivot table using ACRO. \n", "- Some researchers may prefer this to using crosstab. \n", "- Again the call syntax is identical to the pandas \"pd.pivot_table\"\n", "- in this case the output is non-disclosive" ] }, { "cell_type": "code", "execution_count": 15, "id": "966c1a9b", "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:get_summary(): pass\n", "INFO:acro:outcome_df:\n", "------------------------------|\n", " mean |std |\n", " children |children|\n", "parents | |\n", "------------------------------|\n", "great_pret ok | ok |\n", "pretentious ok | ok |\n", "usual ok | ok |\n", "------------------------------|\n", "\n", "INFO:acro:records:add(): output_5\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " mean std\n", " children children\n", "parents \n", "great_pret 3.140972 2.270396\n", "pretentious 3.129630 2.250436\n", "usual 3.110648 2.213072\n" ] } ], "source": [ "table = acro.pivot_table(\n", " df, index=[\"parents\"], values=[\"children\"], aggfunc=[\"mean\", \"std\"]\n", ")\n", "print(table)" ] }, { "cell_type": "markdown", "id": "4adc374b", "metadata": {}, "source": [ "### ACRO pivot_table with margins" ] }, { "cell_type": "code", "execution_count": 16, "id": "9c024b65", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:get_summary(): fail; threshold: 5 cells suppressed; p-ratio: 5 cells suppressed; nk-rule: 5 cells suppressed; \n", "INFO:acro:outcome_df:\n", "-----------------------------------------------------------------------------------------------------------|\n", " children |\n", "recommend not_recom priority recommend spec_prior very_recom All|\n", "parents |\n", "-----------------------------------------------------------------------------------------------------------|\n", "great_pret ok ok threshold; p-ratio; nk-rule; ok threshold; p-ratio; nk-rule; ok|\n", "pretentious ok ok threshold; p-ratio; nk-rule; ok ok ok|\n", "usual ok ok threshold; p-ratio; nk-rule; ok ok ok|\n", "All ok ok threshold; p-ratio; nk-rule; ok ok ok|\n", "-----------------------------------------------------------------------------------------------------------|\n", "\n", "INFO:acro:Disclosive cells were deleted from the dataframe before calculating the pivot table\n", "INFO:acro:records:add(): output_6\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " children \n", "recommend not_recom priority spec_prior very_recom All\n", "parents \n", "great_pret 3.125694 2.665501 3.353610 NaN 3.140972\n", "pretentious 3.105556 3.030323 3.370253 2.204545 3.129630\n", "usual 3.074306 3.116944 3.393140 2.244898 3.111626\n", "All 3.101852 2.996015 3.366222 2.228659 3.127412\n" ] } ], "source": [ "safe_table = acro.pivot_table(\n", " df, columns=[\"recommend\"], index=[\"parents\"], values=[\"children\"], margins=True\n", ")\n", "print(safe_table)" ] }, { "cell_type": "markdown", "id": "8446fa99-c073-48b8-875e-700dfa17ea0c", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Regression examples using ACRO\n", "\n", "Again there is an industry-standard package in python, this time called **statsmodels**.\n", "- The examples below illustrate the use of the ACRO wrapper standard statsmodel functions\n", "- Note that statsmodels can be called using an 'R-like' format (using an 'r' suffix on the command names)\n", "- most statsmodels functiobns return a \"results object\" which has a \"summary\" function that produces printable/saveable outputs \n", "\n", "### Start by manipulating the nursery data to get two numeric variables\n", "- The 'recommend' column is converted to an integer scale" ] }, { "cell_type": "code", "execution_count": 17, "id": "72aefb22", "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "df[\"recommend\"].replace(\n", " to_replace={\n", " \"not_recom\": \"0\",\n", " \"recommend\": \"1\",\n", " \"very_recom\": \"2\",\n", " \"priority\": \"3\",\n", " \"spec_prior\": \"4\",\n", " },\n", " inplace=True,\n", ")\n", "df[\"recommend\"] = pd.to_numeric(df[\"recommend\"])\n", "\n", "new_df = df[[\"recommend\", \"children\"]]\n", "new_df = new_df.dropna()" ] }, { "cell_type": "markdown", "id": "3ef880e6-726f-4a0b-9bcd-da8861dbd5a7", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### ACRO OLS \n", "This is an example of ordinary least square regression using ACRO. \n", "- Above recommend column was converted form categorical to numeric. \n", "- Now we perform a the linear regression between recommend and children. \n", "- This version includes a constant (intercept)\n", "- This is just to show how the regression is done using ACRO. \n", "- **No correlation is expected to be seen by using these variables**" ] }, { "cell_type": "code", "execution_count": 18, "id": "2f462e42", "metadata": { "scrolled": true, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:ols() outcome: pass; dof=12958.0 >= 10\n", "INFO:acro:records:add(): output_7\n" ] }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
OLS Regression Results
Dep. Variable: recommend R-squared: 0.001
Model: OLS Adj. R-squared: 0.001
Method: Least Squares F-statistic: 13.83
Date: Thu, 06 Mar 2025 Prob (F-statistic): 0.000201
Time: 19:39:47 Log-Likelihood: -25121.
No. Observations: 12960 AIC: 5.025e+04
Df Residuals: 12958 BIC: 5.026e+04
Df Model: 1
Covariance Type: nonrobust
\n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
coef std err t P>|t| [0.025 0.975]
const 2.2099 0.025 87.263 0.000 2.160 2.260
children 0.0245 0.007 3.718 0.000 0.012 0.037
\n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
Omnibus: 77090.215 Durbin-Watson: 2.883
Prob(Omnibus): 0.000 Jarque-Bera (JB): 1741.570
Skew: -0.486 Prob(JB): 0.00
Kurtosis: 1.489 Cond. No. 6.90


Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified." ], "text/latex": [ "\\begin{center}\n", "\\begin{tabular}{lclc}\n", "\\toprule\n", "\\textbf{Dep. Variable:} & recommend & \\textbf{ R-squared: } & 0.001 \\\\\n", "\\textbf{Model:} & OLS & \\textbf{ Adj. R-squared: } & 0.001 \\\\\n", "\\textbf{Method:} & Least Squares & \\textbf{ F-statistic: } & 13.83 \\\\\n", "\\textbf{Date:} & Thu, 06 Mar 2025 & \\textbf{ Prob (F-statistic):} & 0.000201 \\\\\n", "\\textbf{Time:} & 19:39:47 & \\textbf{ Log-Likelihood: } & -25121. \\\\\n", "\\textbf{No. Observations:} & 12960 & \\textbf{ AIC: } & 5.025e+04 \\\\\n", "\\textbf{Df Residuals:} & 12958 & \\textbf{ BIC: } & 5.026e+04 \\\\\n", "\\textbf{Df Model:} & 1 & \\textbf{ } & \\\\\n", "\\textbf{Covariance Type:} & nonrobust & \\textbf{ } & \\\\\n", "\\bottomrule\n", "\\end{tabular}\n", "\\begin{tabular}{lcccccc}\n", " & \\textbf{coef} & \\textbf{std err} & \\textbf{t} & \\textbf{P$> |$t$|$} & \\textbf{[0.025} & \\textbf{0.975]} \\\\\n", "\\midrule\n", "\\textbf{const} & 2.2099 & 0.025 & 87.263 & 0.000 & 2.160 & 2.260 \\\\\n", "\\textbf{children} & 0.0245 & 0.007 & 3.718 & 0.000 & 0.012 & 0.037 \\\\\n", "\\bottomrule\n", "\\end{tabular}\n", "\\begin{tabular}{lclc}\n", "\\textbf{Omnibus:} & 77090.215 & \\textbf{ Durbin-Watson: } & 2.883 \\\\\n", "\\textbf{Prob(Omnibus):} & 0.000 & \\textbf{ Jarque-Bera (JB): } & 1741.570 \\\\\n", "\\textbf{Skew:} & -0.486 & \\textbf{ Prob(JB): } & 0.00 \\\\\n", "\\textbf{Kurtosis:} & 1.489 & \\textbf{ Cond. No. } & 6.90 \\\\\n", "\\bottomrule\n", "\\end{tabular}\n", "%\\caption{OLS Regression Results}\n", "\\end{center}\n", "\n", "Notes: \\newline\n", " [1] Standard Errors assume that the covariance matrix of the errors is correctly specified." ], "text/plain": [ "\n", "\"\"\"\n", " OLS Regression Results \n", "==============================================================================\n", "Dep. Variable: recommend R-squared: 0.001\n", "Model: OLS Adj. R-squared: 0.001\n", "Method: Least Squares F-statistic: 13.83\n", "Date: Thu, 06 Mar 2025 Prob (F-statistic): 0.000201\n", "Time: 19:39:47 Log-Likelihood: -25121.\n", "No. Observations: 12960 AIC: 5.025e+04\n", "Df Residuals: 12958 BIC: 5.026e+04\n", "Df Model: 1 \n", "Covariance Type: nonrobust \n", "==============================================================================\n", " coef std err t P>|t| [0.025 0.975]\n", "------------------------------------------------------------------------------\n", "const 2.2099 0.025 87.263 0.000 2.160 2.260\n", "children 0.0245 0.007 3.718 0.000 0.012 0.037\n", "==============================================================================\n", "Omnibus: 77090.215 Durbin-Watson: 2.883\n", "Prob(Omnibus): 0.000 Jarque-Bera (JB): 1741.570\n", "Skew: -0.486 Prob(JB): 0.00\n", "Kurtosis: 1.489 Cond. No. 6.90\n", "==============================================================================\n", "\n", "Notes:\n", "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", "\"\"\"" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
OLS Regression Results
Dep. Variable: recommend R-squared: 0.000
Model: OLS Adj. R-squared: 0.000
Method: Least Squares F-statistic: 6.417
Date: Mon, 04 Mar 2024 Prob (F-statistic): 0.0113
Time: 21:21:09 Log-Likelihood: -25124.
No. Observations: 12960 AIC: 5.025e+04
Df Residuals: 12958 BIC: 5.027e+04
Df Model: 1
Covariance Type: nonrobust
\n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
coef std err t P>|t| [0.025 0.975]
const 2.2341 0.025 87.965 0.000 2.184 2.284
children 0.0168 0.007 2.533 0.011 0.004 0.030
\n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
Omnibus: 76735.931 Durbin-Watson: 2.883
Prob(Omnibus): 0.000 Jarque-Bera (JB): 1742.843
Skew: -0.485 Prob(JB): 0.00
Kurtosis: 1.487 Cond. No. 6.89


Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified." ], "text/plain": [ "\n", "\"\"\"\n", " OLS Regression Results \n", "==============================================================================\n", "Dep. Variable: recommend R-squared: 0.000\n", "Model: OLS Adj. R-squared: 0.000\n", "Method: Least Squares F-statistic: 6.417\n", "Date: Mon, 04 Mar 2024 Prob (F-statistic): 0.0113\n", "Time: 21:21:09 Log-Likelihood: -25124.\n", "No. Observations: 12960 AIC: 5.025e+04\n", "Df Residuals: 12958 BIC: 5.027e+04\n", "Df Model: 1 \n", "Covariance Type: nonrobust \n", "==============================================================================\n", " coef std err t P>|t| [0.025 0.975]\n", "------------------------------------------------------------------------------\n", "const 2.2341 0.025 87.965 0.000 2.184 2.284\n", "children 0.0168 0.007 2.533 0.011 0.004 0.030\n", "==============================================================================\n", "Omnibus: 76735.931 Durbin-Watson: 2.883\n", "Prob(Omnibus): 0.000 Jarque-Bera (JB): 1742.843\n", "Skew: -0.485 Prob(JB): 0.00\n", "Kurtosis: 1.487 Cond. No. 6.89\n", "==============================================================================\n", "\n", "Notes:\n", "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n", "\"\"\"" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = new_df[\"recommend\"]\n", "x = new_df[\"children\"]\n", "x = add_constant(x)\n", "\n", "results = acro.ols(y, x)\n", "results.summary()" ] }, { "cell_type": "markdown", "id": "0c826271", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### ACRO OLSR\n", "This is an example of ordinary least squares regression using the 'R-like' statsmodels api, i.e. from a formula and dataframe using ACRO " ] }, { "cell_type": "code", "execution_count": 19, "id": "cc90f7c9", "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:olsr() outcome: pass; dof=12958.0 >= 10\n", "INFO:acro:records:add(): output_8\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " OLS Regression Results \n", "==============================================================================\n", "Dep. Variable: recommend R-squared: 0.001\n", "Model: OLS Adj. R-squared: 0.001\n", "Method: Least Squares F-statistic: 13.83\n", "Date: Thu, 06 Mar 2025 Prob (F-statistic): 0.000201\n", "Time: 19:39:47 Log-Likelihood: -25121.\n", "No. Observations: 12960 AIC: 5.025e+04\n", "Df Residuals: 12958 BIC: 5.026e+04\n", "Df Model: 1 \n", "Covariance Type: nonrobust \n", "==============================================================================\n", " coef std err t P>|t| [0.025 0.975]\n", "------------------------------------------------------------------------------\n", "Intercept 2.2099 0.025 87.263 0.000 2.160 2.260\n", "children 0.0245 0.007 3.718 0.000 0.012 0.037\n", "==============================================================================\n", "Omnibus: 77090.215 Durbin-Watson: 2.883\n", "Prob(Omnibus): 0.000 Jarque-Bera (JB): 1741.570\n", "Skew: -0.486 Prob(JB): 0.00\n", "Kurtosis: 1.489 Cond. No. 6.90\n", "==============================================================================\n", "\n", "Notes:\n", "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " OLS Regression Results \n", "==============================================================================\n", "Dep. Variable: recommend R-squared: 0.000\n", "Model: OLS Adj. R-squared: 0.000\n", "Method: Least Squares F-statistic: 6.417\n", "Date: Mon, 04 Mar 2024 Prob (F-statistic): 0.0113\n", "Time: 21:21:09 Log-Likelihood: -25124.\n", "No. Observations: 12960 AIC: 5.025e+04\n", "Df Residuals: 12958 BIC: 5.027e+04\n", "Df Model: 1 \n", "Covariance Type: nonrobust \n", "==============================================================================\n", " coef std err t P>|t| [0.025 0.975]\n", "------------------------------------------------------------------------------\n", "Intercept 2.2341 0.025 87.965 0.000 2.184 2.284\n", "children 0.0168 0.007 2.533 0.011 0.004 0.030\n", "==============================================================================\n", "Omnibus: 76735.931 Durbin-Watson: 2.883\n", "Prob(Omnibus): 0.000 Jarque-Bera (JB): 1742.843\n", "Skew: -0.485 Prob(JB): 0.00\n", "Kurtosis: 1.487 Cond. No. 6.89\n", "==============================================================================\n", "\n", "Notes:\n", "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n" ] } ], "source": [ "results = acro.olsr(formula=\"recommend ~ children\", data=new_df)\n", "print(results.summary())" ] }, { "cell_type": "markdown", "id": "2816eac7", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### ACRO Probit\n", "This is an example of probit regression using ACRO \n", "We use a different combination of variables from the original dataset.\n", "\n", "Again, we support the use of R-like formulas - because we support R " ] }, { "cell_type": "code", "execution_count": 20, "id": "5b1a1611", "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:probit() outcome: pass; dof=12958.0 >= 10\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimization terminated successfully.\n", " Current function value: 0.693145\n", " Iterations 2\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:records:add(): output_9\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " Probit Regression Results \n", "==============================================================================\n", "Dep. Variable: finance No. Observations: 12960\n", "Model: Probit Df Residuals: 12958\n", "Method: MLE Df Model: 1\n", "Date: Thu, 06 Mar 2025 Pseudo R-squ.: 3.602e-06\n", "Time: 19:39:47 Log-Likelihood: -8983.2\n", "converged: True LL-Null: -8983.2\n", "Covariance Type: nonrobust LLR p-value: 0.7992\n", "==============================================================================\n", " coef std err z P>|z| [0.025 0.975]\n", "------------------------------------------------------------------------------\n", "const -0.0039 0.019 -0.207 0.836 -0.041 0.033\n", "children 0.0012 0.005 0.254 0.799 -0.008 0.011\n", "==============================================================================\n" ] } ], "source": [ "new_df = df[[\"finance\", \"children\"]]\n", "new_df = new_df.dropna()\n", "\n", "y = new_df[\"finance\"].astype(\"category\").cat.codes # numeric\n", "y.name = \"finance\"\n", "x = new_df[\"children\"]\n", "x = add_constant(x)\n", "\n", "results = acro.probit(y, x)\n", "print(results.summary())" ] }, { "cell_type": "markdown", "id": "f38b4334", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### ACRO Logit\n", "This is an example of logistic regression using ACRO using the statmodels function" ] }, { "cell_type": "code", "execution_count": 21, "id": "dcf30f8f", "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:logit() outcome: pass; dof=12958.0 >= 10\n", "INFO:acro:records:add(): output_10\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Optimization terminated successfully.\n", " Current function value: 0.693145\n", " Iterations 3\n" ] }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
Logit Regression Results
Dep. Variable: finance No. Observations: 12960
Model: Logit Df Residuals: 12958
Method: MLE Df Model: 1
Date: Thu, 06 Mar 2025 Pseudo R-squ.: 3.602e-06
Time: 19:39:47 Log-Likelihood: -8983.2
converged: True LL-Null: -8983.2
Covariance Type: nonrobust LLR p-value: 0.7992
\n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
coef std err z P>|z| [0.025 0.975]
const -0.0062 0.030 -0.207 0.836 -0.065 0.053
children 0.0020 0.008 0.254 0.799 -0.013 0.017
" ], "text/latex": [ "\\begin{center}\n", "\\begin{tabular}{lclc}\n", "\\toprule\n", "\\textbf{Dep. Variable:} & finance & \\textbf{ No. Observations: } & 12960 \\\\\n", "\\textbf{Model:} & Logit & \\textbf{ Df Residuals: } & 12958 \\\\\n", "\\textbf{Method:} & MLE & \\textbf{ Df Model: } & 1 \\\\\n", "\\textbf{Date:} & Thu, 06 Mar 2025 & \\textbf{ Pseudo R-squ.: } & 3.602e-06 \\\\\n", "\\textbf{Time:} & 19:39:47 & \\textbf{ Log-Likelihood: } & -8983.2 \\\\\n", "\\textbf{converged:} & True & \\textbf{ LL-Null: } & -8983.2 \\\\\n", "\\textbf{Covariance Type:} & nonrobust & \\textbf{ LLR p-value: } & 0.7992 \\\\\n", "\\bottomrule\n", "\\end{tabular}\n", "\\begin{tabular}{lcccccc}\n", " & \\textbf{coef} & \\textbf{std err} & \\textbf{z} & \\textbf{P$> |$z$|$} & \\textbf{[0.025} & \\textbf{0.975]} \\\\\n", "\\midrule\n", "\\textbf{const} & -0.0062 & 0.030 & -0.207 & 0.836 & -0.065 & 0.053 \\\\\n", "\\textbf{children} & 0.0020 & 0.008 & 0.254 & 0.799 & -0.013 & 0.017 \\\\\n", "\\bottomrule\n", "\\end{tabular}\n", "%\\caption{Logit Regression Results}\n", "\\end{center}" ], "text/plain": [ "\n", "\"\"\"\n", " Logit Regression Results \n", "==============================================================================\n", "Dep. Variable: finance No. Observations: 12960\n", "Model: Logit Df Residuals: 12958\n", "Method: MLE Df Model: 1\n", "Date: Thu, 06 Mar 2025 Pseudo R-squ.: 3.602e-06\n", "Time: 19:39:47 Log-Likelihood: -8983.2\n", "converged: True LL-Null: -8983.2\n", "Covariance Type: nonrobust LLR p-value: 0.7992\n", "==============================================================================\n", " coef std err z P>|z| [0.025 0.975]\n", "------------------------------------------------------------------------------\n", "const -0.0062 0.030 -0.207 0.836 -0.065 0.053\n", "children 0.0020 0.008 0.254 0.799 -0.013 0.017\n", "==============================================================================\n", "\"\"\"" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
Logit Regression Results
Dep. Variable: finance No. Observations: 12960
Model: Logit Df Residuals: 12958
Method: MLE Df Model: 1
Date: Mon, 04 Mar 2024 Pseudo R-squ.: 1.186e-06
Time: 21:21:09 Log-Likelihood: -8983.2
converged: True LL-Null: -8983.2
Covariance Type: nonrobust LLR p-value: 0.8839
\n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "\n", " \n", "\n", "
coef std err z P>|z| [0.025 0.975]
const -0.0036 0.030 -0.119 0.905 -0.063 0.056
children 0.0012 0.008 0.146 0.884 -0.014 0.017
" ], "text/plain": [ "\n", "\"\"\"\n", " Logit Regression Results \n", "==============================================================================\n", "Dep. Variable: finance No. Observations: 12960\n", "Model: Logit Df Residuals: 12958\n", "Method: MLE Df Model: 1\n", "Date: Mon, 04 Mar 2024 Pseudo R-squ.: 1.186e-06\n", "Time: 21:21:09 Log-Likelihood: -8983.2\n", "converged: True LL-Null: -8983.2\n", "Covariance Type: nonrobust LLR p-value: 0.8839\n", "==============================================================================\n", " coef std err z P>|z| [0.025 0.975]\n", "------------------------------------------------------------------------------\n", "const -0.0036 0.030 -0.119 0.905 -0.063 0.056\n", "children 0.0012 0.008 0.146 0.884 -0.014 0.017\n", "==============================================================================\n", "\"\"\"" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "results = acro.logit(y, x)\n", "results.summary()" ] }, { "cell_type": "markdown", "id": "a962ff17", "metadata": {}, "source": [ "### ACRO survival analysis\n", "This is an example of survival tables and plots using ACRO. \n", "- A dataset from statsmodels is used for the survival analysis.\n", "- A subset of tha dataset is used in this example to demostrate the survival analysis.\n", "- The output parameter in the surv_func define the type of output (table or plot)." ] }, { "cell_type": "code", "execution_count": 22, "id": "dcf2c86d", "metadata": {}, "outputs": [], "source": [ "import statsmodels.api as sm\n", "\n", "data = sm.datasets.get_rdataset(\"flchain\", \"survival\").data\n", "data = data.loc[data.sex == \"F\", :]\n", "data = data.iloc[:20, :]\n", "# data.head()" ] }, { "cell_type": "code", "execution_count": 23, "id": "df1cbb9e", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:get_summary(): fail; threshold: 76 cells suppressed; \n", "INFO:acro:outcome_df:\n", "-----------------------------------------------------------|\n", " Surv_prob |Surv_prob_SE |num_at_risk |num_events |\n", "Time | | | |\n", "-----------------------------------------------------------|\n", "51 ok | ok | ok | ok|\n", "69 threshold; | threshold; | threshold; | threshold; |\n", "85 threshold; | threshold; | threshold; | threshold; |\n", "91 threshold; | threshold; | threshold; | threshold; |\n", "115 threshold; | threshold; | threshold; | threshold; |\n", "372 threshold; | threshold; | threshold; | threshold; |\n", "667 threshold; | threshold; | threshold; | threshold; |\n", "874 threshold; | threshold; | threshold; | threshold; |\n", "1039 threshold; | threshold; | threshold; | threshold; |\n", "1046 threshold; | threshold; | threshold; | threshold; |\n", "1281 threshold; | threshold; | threshold; | threshold; |\n", "1286 threshold; | threshold; | threshold; | threshold; |\n", "1326 threshold; | threshold; | threshold; | threshold; |\n", "1355 threshold; | threshold; | threshold; | threshold; |\n", "1626 threshold; | threshold; | threshold; | threshold; |\n", "1903 threshold; | threshold; | threshold; | threshold; |\n", "1914 threshold; | threshold; | threshold; | threshold; |\n", "2776 threshold; | threshold; | threshold; | threshold; |\n", "2851 threshold; | threshold; | threshold; | threshold; |\n", "3309 threshold; | threshold; | threshold; | threshold; |\n", "-----------------------------------------------------------|\n", "\n", "INFO:acro:records:add(): output_11\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " Surv prob Surv prob SE num at risk num events\n", "Time \n", "51 0.95 0.048734 20.0 1.0\n", "69 NaN NaN NaN NaN\n", "85 NaN NaN NaN NaN\n", "91 NaN NaN NaN NaN\n", "115 NaN NaN NaN NaN\n", "372 NaN NaN NaN NaN\n", "667 NaN NaN NaN NaN\n", "874 NaN NaN NaN NaN\n", "1039 NaN NaN NaN NaN\n", "1046 NaN NaN NaN NaN\n", "1281 NaN NaN NaN NaN\n", "1286 NaN NaN NaN NaN\n", "1326 NaN NaN NaN NaN\n", "1355 NaN NaN NaN NaN\n", "1626 NaN NaN NaN NaN\n", "1903 NaN NaN NaN NaN\n", "1914 NaN NaN NaN NaN\n", "2776 NaN NaN NaN NaN\n", "2851 NaN NaN NaN NaN\n", "3309 NaN NaN NaN NaN\n" ] } ], "source": [ "safe_table = acro.surv_func(data.futime, data.death, output=\"table\")\n", "print(safe_table)" ] }, { "cell_type": "code", "execution_count": 24, "id": "8762ab29", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:get_summary(): fail; threshold: 76 cells suppressed; \n", "INFO:acro:outcome_df:\n", "-----------------------------------------------------------|\n", " Surv_prob |Surv_prob_SE |num_at_risk |num_events |\n", "Time | | | |\n", "-----------------------------------------------------------|\n", "51 ok | ok | ok | ok|\n", "69 threshold; | threshold; | threshold; | threshold; |\n", "85 threshold; | threshold; | threshold; | threshold; |\n", "91 threshold; | threshold; | threshold; | threshold; |\n", "115 threshold; | threshold; | threshold; | threshold; |\n", "372 threshold; | threshold; | threshold; | threshold; |\n", "667 threshold; | threshold; | threshold; | threshold; |\n", "874 threshold; | threshold; | threshold; | threshold; |\n", "1039 threshold; | threshold; | threshold; | threshold; |\n", "1046 threshold; | threshold; | threshold; | threshold; |\n", "1281 threshold; | threshold; | threshold; | threshold; |\n", "1286 threshold; | threshold; | threshold; | threshold; |\n", "1326 threshold; | threshold; | threshold; | threshold; |\n", "1355 threshold; | threshold; | threshold; | threshold; |\n", "1626 threshold; | threshold; | threshold; | threshold; |\n", "1903 threshold; | threshold; | threshold; | threshold; |\n", "1914 threshold; | threshold; | threshold; | threshold; |\n", "2776 threshold; | threshold; | threshold; | threshold; |\n", "2851 threshold; | threshold; | threshold; | threshold; |\n", "3309 threshold; | threshold; | threshold; | threshold; |\n", "-----------------------------------------------------------|\n", "\n", "INFO:acro:records:add(): output_12\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "(, 'acro_artifacts/kaplan-mier_0.png')\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGwCAYAAAB7MGXBAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAANFlJREFUeJzt3Xl4VPXd///XZJkkZBmEbCwhRK1IiWANLQSKVqoBXCn1Ngo/AUVvI6LFqBW0FaReRu0XSlHBKovSC4Wror3pZaqmVRYNqESgIEipoEFJDEklkxDIen5/hBkYsjAzmZmTZJ6P65rrIifnzLzPhxPy4rOcYzEMwxAAAIBJQswuAAAABDfCCAAAMBVhBAAAmIowAgAATEUYAQAApiKMAAAAUxFGAACAqcLMLsAdTU1NOnLkiGJjY2WxWMwuBwAAuMEwDFVVValv374KCWm7/6NLhJEjR44oJSXF7DIAAIAXDh8+rP79+7f5/S4RRmJjYyU1n0xcXJzJ1QAAAHfY7XalpKQ4f4+3pUuEEcfQTFxcHGEEAIAu5lxTLJjACgAATEUYAQAApiKMAAAAU3WJOSMA0Jk0Njaqvr7e7DIA04WHhys0NLTD70MYAQA3GYah0tJSHTt2zOxSgE6jZ8+eSk5O7tB9wAgjAOAmRxBJTExUjx49uAkjgpphGKqpqVFZWZkkqU+fPl6/F2EEANzQ2NjoDCK9e/c2uxygU4iKipIklZWVKTEx0eshGyawAoAbHHNEevToYXIlQOfi+JnoyDwqwggAeIChGcCVL34mCCMAAMBUhBEAAGAqwggAIGA2btwoi8XS4eXRAwcO1OLFi31Skz989dVXslgs2rlzp8/e85VXXlHPnj3d3v+ll15SSkqKQkJCOnVbSaymAQDA51JSUlRSUqL4+HhTPt9ut2vWrFlatGiRfvnLX8pms5lSh7u6fBh5/4vvVNfQZHYZ6IISYiN12YCeTEhE0Kmrq5PVajW7jC6rvr5e4eHh7e4TGhqq5OTkAFXUUnFxserr63Xttdd26P4fgdLlw8iv3/iXyqvrzC4DXdT6ezKVkdrL7DLQRRmGoRP1jQH/3KjwUI9C9M9+9jOlp6fLarVq9erVGjJkiBYsWKCHH35Yu3btUq9evTRt2jQ9+eSTCgtr/rUwcOBAzZ49W7Nnz3a+z6WXXqqJEydq/vz5kppXUbz88st6++239e6776pfv35auHChbrjhBucx+fn5mj17tg4fPqyRI0dq2rRpLeorLCzUnDlz9Omnnyo+Pl6/+MUvlJeXp+joaEnN97CYMWOG/vGPfyg5OVlPPvmkR+01f/58rVy5Ut9995169+6tm266SUuWLHGew1tvvaWJEyc69+/Zs6cWL16s6dOn66uvvlJaWprWrVunpUuXatu2bXrmmWc0Z84cvfXWWxo/frzzuDfffFO33XabvvvuO5WXlystLU07duzQ0KFDNWDAAP3mN79RTk6Oc//PPvtMGRkZ+vLLL3X++edr0aJFWrVqlQ4ePKhevXrp+uuv17PPPquYmBiPzveVV17R7bffLkk6//zzJUmHDh3S/PnzdezYMf31r3917jt79mzt3LlTGzdulNR8rQwdOlSRkZFavny5rFarcnJynH/n/tLlw8iw/j1VeYJnRMAz27/+XpK0v7SaMAKvnahv1A8ffzfgn7t3wTj1sHr2z/err76qe+65Rx999JHKy8uVlZWl6dOna/Xq1friiy901113KTIy0uNfOk888YSeffZZ/f73v9dzzz2nKVOm6Ouvv1avXr10+PBhTZo0STk5Obrnnnu0fft2Pfjggy7H7969W+PGjdPvfvc7rVixQkePHtWsWbM0a9YsrVq1SpI0ffp0HT58WO+//76sVqvuv/9+510/z+WNN97QH/7wB61du1ZDhgxRaWmpdu3a5dE5StIjjzyihQsXatWqVYqIiNCWLVu0Zs0alzDy2muv6cYbb1RMTIzKy8ud20NCQnTLLbdozZo1LmHktddeU2ZmpjMwhISEaMmSJRo4cKAOHTqkmTNn6te//rWWLl3qUa3Z2dlKSUnRVVddpU8++UQpKSlKSEhw+/hXX31Vubm5+vjjj7V161ZNnz5do0eP1tVXX+1RHZ7o8mFkxfQfm10CuqC5b/5Lr39yWEeras0uBQiICy+8UM8++6wkafXq1UpJSdHzzz8vi8Wiiy++WEeOHNEjjzyixx9/XCEh7q9tmD59um699VZJ0lNPPaXnnntOn3zyicaPH69ly5bp/PPP1x/+8AdZLBYNGjRIu3fv1jPPPOM8/ve//70mT57s7IH5wQ9+oCVLluiKK67QsmXLVFxcrL///e/atm2bRowYIUlasWKFBg8e7FZ9xcXFSk5O1lVXXaXw8HANGDBAP/nJT9w+P4fZs2dr0qRJzq+nTJmiqVOnqqamRj169JDdbtfbb7+t9evXt3r8lClTtGjRIn399ddKTU1VU1OT1q5dq0cffdTlMxzS0tL0u9/9Tvfcc4/HYSQqKsp5l+CEhASPh4uGDh2qefPmSWr++3j++ef1z3/+kzAC+FpCbKQkqazqpMmVoCuLCg/V3gXjTPlcTw0fPtz553379ikzM9NlqGf06NGqrq7WN998owEDBrj9vkOHDnX+OTo6WrGxsc5ei3379mnkyJEun5OZmelyfFFRkf7zn/9ozZo1zm2GYaipqUmHDh3Sv//9b4WFhbnUf/HFF7u9quR//ud/tHjxYp1//vkaP368rrnmGl1//fXO4Sh3nfn5knTttdcqLCxMGzZs0C233KL169crNjZWWVlZrR7/ox/9SBdffLFef/11zZkzR5s2bVJZWZluvvlm5z4ffPCBnnrqKe3du1d2u10NDQ06efKkjh8/7hyyCoQz/06l5mfOuNsT5S2W9iIoJcRGSBI9I+gQi8WiHtawgL+8mXR95i8zwzBavIdhGM5zkpqHDBzbHFq73ffZEzktFouamppc3rM9TU1Nuvvuu7Vz507na9euXTpw4IAuuOCCFnV5KiUlRfv379cLL7ygqKgozZw5U5dffrnzXCwWi1vneXYYsFqtuummm/Taa69Jah5yyc7ObjfkTJkyxWX/cePGOVfbfP3117rmmmuUnp6u9evXq6ioSC+88EKb9XjDF3+n/kIYQVBKPBVGyggjCEI//OEPVVhY6PKLqbCwULGxserXr5+k5u79kpIS5/ftdrsOHTrk8eds27bNZdvZX1922WX6/PPPdeGFF7Z4Wa1WDR48WA0NDdq+fbvzmP3793t0n5KoqCjdcMMNWrJkiTZu3KitW7dq9+7drZ7ngQMHVFNT49b7TpkyRe+8844+//xzffDBB5oyZUq7+0+ePFm7d+9WUVGR3njjDZf9t2/froaGBi1cuFAjR47URRddpCNHjrh9ju44+1wl+fQ+KB1BGEFQomcEwWzmzJk6fPiw7rvvPn3xxRf6v//7P82bN0+5ubnO+SJjx47Vn//8Z23ZskV79uzRtGnTPH4ia05Ojr788kvl5uZq//79eu211/TKK6+47PPII49o69atuvfee7Vz504dOHBAGzZs0H333SdJGjRokMaPH6+77rpLH3/8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R1LzEMvUqVOd++fk5Ojrr79Wbm6u9u3bp5UrV2rFihV66KGHfHcWAACgy/J4zkh2drYqKiq0YMEClZSUKD09Xfn5+UpNTZUklZSUuNxzJC0tTfn5+XrggQf0wgsvqG/fvlqyZIl++ctfuv2ZERERmjdvXqtDN8GOtmkf7dM22qZ9tE/baJu20Tbe8fg+IwAAAL7Es2kAAICpCCMAAMBUhBEAAGAqwggAADBVpw8jS5cuVVpamiIjI5WRkaEtW7aYXZLfzZ8/XxaLxeWVnJzs/L5hGJo/f7769u2rqKgo/exnP9Pnn3/u8h61tbW67777FB8fr+joaN1www365ptvAn0qPrF582Zdf/316tu3rywWi/7617+6fN9X7fH999/rtttuk81mk81m02233aZjx475+ew65lxtM3369BbX0siRI1326a5tk5eXpx//+MeKjY1VYmKiJk6cqP3797vsE6zXjjttE8zXzrJlyzR06FDnjcsyMzP197//3fn9YL1u/MroxNauXWuEh4cbL7/8srF3717jV7/6lREdHW18/fXXZpfmV/PmzTOGDBlilJSUOF9lZWXO7z/99NNGbGyssX79emP37t1Gdna20adPH8Nutzv3ycnJMfr162cUFBQYn332mXHllVcaw4YNMxoaGsw4pQ7Jz883HnvsMWP9+vWGJOOtt95y+b6v2mP8+PFGenq6UVhYaBQWFhrp6enGddddF6jT9Mq52mbatGnG+PHjXa6liooKl326a9uMGzfOWLVqlbFnzx5j586dxrXXXmsMGDDAqK6udu4TrNeOO20TzNfOhg0bjLffftvYv3+/sX//fuPRRx81wsPDjT179hiGEbzXjT916jDyk5/8xMjJyXHZdvHFFxtz5swxqaLAmDdvnjFs2LBWv9fU1GQkJycbTz/9tHPbyZMnDZvNZrz44ouGYRjGsWPHjPDwcGPt2rXOfb799lsjJCTEeOedd/xau7+d/QvXV+2xd+9eQ5Kxbds25z5bt241JBlffPGFn8/KN9oKIzfeeGObxwRL2xiGYZSVlRmSjE2bNhmGwbVzprPbxjC4ds523nnnGcuXL+e68ZNOO0xTV1enoqIiZWVluWzPyspSYWGhSVUFzoEDB9S3b1+lpaXplltu0cGDByVJhw4dUmlpqUu7RERE6IorrnC2S1FRkerr61326du3r9LT07td2/mqPbZu3SqbzaYRI0Y49xk5cqRsNluXb7ONGzcqMTFRF110ke666y6VlZU5vxdMbVNZWSlJ6tWrlySunTOd3TYOXDtSY2Oj1q5dq+PHjyszM5Prxk86bRgpLy9XY2NjiwfwJSUltXjwXnczYsQIrV69Wu+++65efvlllZaWatSoUaqoqHCee3vtUlpaKqvVqvPOO6/NfboLX7VHaWmpEhMTW7x/YmJil26zCRMmaM2aNXr//fe1cOFCffrppxo7dqxqa2slBU/bGIah3Nxc/fSnP1V6erokrh2H1tpG4trZvXu3YmJiFBERoZycHL311lv64Q9/yHXjJx7fDj7QLBaLy9eGYbTY1t1MmDDB+edLLrlEmZmZuuCCC/Tqq686J5B50y7due180R6t7d/V2yw7O9v55/T0dA0fPlypqal6++23NWnSpDaP625tM2vWLP3rX//Shx9+2OJ7wX7ttNU2wX7tDBo0SDt37tSxY8e0fv16TZs2TZs2bXJ+P9ivG1/rtD0j8fHxCg0NbZEQy8rKWiTS7i46OlqXXHKJDhw44FxV0167JCcnq66uTt9//32b+3QXvmqP5ORkfffddy3e/+jRo92qzfr06aPU1FQdOHBAUnC0zX333acNGzbogw8+UP/+/Z3buXbabpvWBNu1Y7VadeGFF2r48OHKy8vTsGHD9Mc//pHrxk86bRixWq3KyMhQQUGBy/aCggKNGjXKpKrMUVtbq3379qlPnz5KS0tTcnKyS7vU1dVp06ZNznbJyMhQeHi4yz4lJSXas2dPt2s7X7VHZmamKisr9cknnzj3+fjjj1VZWdmt2qyiokKHDx9Wnz59JHXvtjEMQ7NmzdKbb76p999/X2lpaS7fD+Zr51xt05pgunZaYxiGamtrg/q68auATpf1kGNp74oVK4y9e/cas2fPNqKjo42vvvrK7NL86sEHHzQ2btxoHDx40Ni2bZtx3XXXGbGxsc7zfvrppw2bzWa8+eabxu7du41bb7211WVl/fv3N/7xj38Yn332mTF27Nguu7S3qqrK2LFjh7Fjxw5DkrFo0SJjx44dziXevmqP8ePHG0OHDjW2bt1qbN261bjkkks6/TK79tqmqqrKePDBB43CwkLj0KFDxgcffGBkZmYa/fr1C4q2ueeeewybzWZs3LjRZXlqTU2Nc59gvXbO1TbBfu3MnTvX2Lx5s3Ho0CHjX//6l/Hoo48aISEhxnvvvWcYRvBeN/7UqcOIYRjGCy+8YKSmphpWq9W47LLLXJaedVeONevh4eFG3759jUmTJhmff/658/tNTU3GvHnzjOTkZCMiIsK4/PLLjd27d7u8x4kTJ4xZs2YZvXr1MqKioozrrrvOKC4uDvSp+MQHH3xgSGrxmjZtmmEYvmuPiooKY8qUKUZsbKwRGxtrTJkyxfj+++8DdJbeaa9tampqjKysLCMhIcEIDw83BgwYYEybNq3FeXfXtmmtXSQZq1atcu4TrNfOudom2K+dO+64w/l7JyEhwfj5z3/uDCKGEbzXjT9ZDMMwAtcPAwAA4KrTzhkBAADBgTACAABMRRgBAACmIowAAABTEUYAAICpCCMAAMBUhBEAAGAqwggAADAVYQSA382fP1+XXnqp2WUA6KS4AyuADjnX486nTZum559/XrW1terdu3eAqgLQlRBGAHTImY9SX7dunR5//HHt37/fuS0qKko2m82M0gB0EQzTAOiQ5ORk58tms8lisbTYdvYwzfTp0zVx4kQ99dRTSkpKUs+ePfXEE0+ooaFBDz/8sHr16qX+/ftr5cqVLp/17bffKjs7W+edd5569+6tG2+8UV999VVgTxiAzxFGAJji/fff15EjR7R582YtWrRI8+fP13XXXafzzjtPH3/8sXJycpSTk6PDhw9LkmpqanTllVcqJiZGmzdv1ocffqiYmBiNHz9edXV1Jp8NgI4gjAAwRa9evbRkyRINGjRId9xxhwYNGqSamho9+uij+sEPfqC5c+fKarXqo48+kiStXbtWISEhWr58uS655BINHjxYq1atUnFxsTZu3GjuyQDokDCzCwAQnIYMGaKQkNP/H0pKSlJ6errz69DQUPXu3VtlZWWSpKKiIv3nP/9RbGysy/ucPHlSX375ZWCKBuAXhBEApggPD3f52mKxtLqtqalJktTU1KSMjAytWbOmxXslJCT4r1AAfkcYAdAlXHbZZVq3bp0SExMVFxdndjkAfIg5IwC6hClTpig+Pl433nijtmzZokOHDmnTpk361a9+pW+++cbs8gB0AGEEQJfQo0cPbd68WQMGDNCkSZM0ePBg3XHHHTpx4gQ9JUAXx03PAACAqegZAQAApiKMAAAAUxFGAACAqQgjAADAVIQRAABgKsIIAAAwFWEEAACYijACAABMRRgBAACmIowAAABTEUYAAICp/n+L3AbcO2Xl5QAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGwCAYAAAB7MGXBAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAA27UlEQVR4nO3de3hU9Z3H8c9MksmF3IBkEqCBgCCoEEDQGKmX1VRQi6W2XYo8clmLBcGVprUQq0Rb16hdWKqibKmobaGwVdFuRVxFsF5SKRFQKiJyMVTJBSgJCZDLzG//iDNhIAkzycycXN6v55nnIWd+Z+Z7DjPkw+9yjs0YYwQAAGARu9UFAACA7o0wAgAALEUYAQAAliKMAAAASxFGAACApQgjAADAUoQRAABgqUirC/CH2+3Wl19+qYSEBNlsNqvLAQAAfjDG6Pjx4+rbt6/s9pb7PzpFGPnyyy+VkZFhdRkAAKANDh48qK997WstPt8pwkhCQoKkxoNJTEy0uBoAAOCPqqoqZWRkeH+Pt6RThBHP0ExiYiJhBACATuZcUyyYwAoAACxFGAEAAJYijAAAAEt1ijkjANCRuFwu1dfXW10GYLmoqChFRES0+3UIIwDgJ2OMSktLdezYMatLATqM5ORkpaent+s6YIQRAPCTJ4g4nU7FxcVxEUZ0a8YYnThxQuXl5ZKkPn36tPm1CCMA4AeXy+UNIr1797a6HKBDiI2NlSSVl5fL6XS2eciGCawA4AfPHJG4uDiLKwE6Fs93oj3zqAgjABAAhmYAX8H4ThBGAACApQgjAADAUoQRAEDYbN68WTabrd3LozMzM7V06dKg1BQKBw4ckM1m0/bt24P2ms8++6ySk5P9bv/rX/9aGRkZstvtHfpcSaymAQAg6DIyMnTo0CGlpKRY8v5VVVWaN2+elixZou985ztKSkqypA5/deow4nIbvf5xqdVloJMa0LuHLujDXaDR/dTV1cnhcFhdRqdVX1+vqKioVttEREQoPT09TBWdraSkRPX19brxxhvbdf2PcOnUYaTe5dbs339gdRnopOw26e0F16hfcqzVpaCTMsboZL0r7O8bGxUR0AqGq6++WsOHD1dkZKR+//vfa8SIEbr//vt19913a8eOHerVq5emT5+uBx98UJGRjb8WMjMzNX/+fM2fP9/7OqNGjdKkSZN0//33S2pcRbFixQq98soreu2119SvXz8tXrxYN910k3ef9evXa/78+Tp48KAuu+wyTZ8+/az63nnnHeXn52vr1q1KSUnRt7/9bRUWFqpHjx6SGq9hcdttt+mNN95Qenq6HnzwQb+P3RijBx54QCtXrlRZWZl69+6t7373u3rssce8x7Bu3TpNmjTJu09ycrKWLl2qGTNm6MCBAxo4cKDWrFmjJ598Uu+//74effRRLViwQC+++KKuv/56737r1q3TtGnTVFZWpvLycg0cOFDbtm1TVlaW+vfvr5/97GeaM2eOt/22bds0ZswY7d+/XwMGDNCSJUv0zDPPaN++ferVq5cmTpyoRx99VPHx8X4fr9Q4nDNz5kxJ0qBBgyRJ+/fv1/33369jx47ppZde8radP3++tm/frs2bN0tq/KxkZWUpJiZGv/nNb+RwODR79mzv33modOowYrNJYwf0tLoMdEJbP/+n3EbaW15NGEGbnax36cJFr4X9fT/++XjFOQL75/u5557TnDlz9O6776q0tFQ33HCDZsyYod/+9rf65JNPNGvWLMXExAT8S+eBBx7Qo48+ql/+8pd6/PHHNXXqVH3++efq1auXDh48qJtvvllz587V7bffrq1bt+rHP/6xz/579+7VhAkT9OCDD2rlypWqqKjQvHnzNG/ePD3zzDOSpBkzZujLL7/Upk2bFBUVpX//93/3XvXzXF544QX913/9l9asWaOLLrpIpaWl2rFjR0DHKEkLFy7U4sWLNXr0aMXExOjtt9/W6tWrfcLIqlWrNGnSpLOuRWO32zVlyhStXr3aJ4ysWrVK48aN04ABA7ztHnvsMQ0cOFD79u3THXfcoZ/+9Kd68sknA6p18uTJysjIUG5urrZs2aKMjAylpqb6vf9zzz2nvLw8vf/++yoqKtKMGTM0btw4feMb3wiojkB06jASHRmh5+dcbnUZ6IRuffp9vb3nsCqO11pdChAWQ4YM0aOPPipJ+u1vf6uMjAw98cQTstlsGjZsmL788kstWLBAixYtkt3u/9qGGTNmaMqUKZKkhx56SI899pi2bNmiCRMm6KmnntJ5552nxYsXS5KGDh2qjz76SI888oh3/8LCQk2dOtXbAzNkyBA99thjuuqqq/TUU0+ppKREr776qrZs2aJLLrlEkvT000/rggsu8Ku+kpISpaenKzc3V1FRUerfv78uvfRSv4/PY/78+br55pu9P0+dOlW33nqrTpw4obi4OFVVVemVV17RunXrmt1/6tSpWrx4sUpKStS/f3+53W6tWbNG9957r897eGRmZurBBx/U7NmzAw4jsbGx3qsEp6amBjxclJWVpYKCAkmNfx9PPPGENm7cSBgBgi01IVqSVE4YQTvERkXo45+Pt+R9AzVmzBjvn3ft2qWcnByfoZ5x48apurpa//jHP9S/f3+/XzcrK8v75x49eigxMdHba7Fr1y5lZ2f7tM/JyfH5eceOHfrwww+1atUq7zZjjNxut/bv369PP/1UkZGRPvUPGzbM71Ul3/ve97R06VINGjRIEyZM0A033KCJEyd6h6P8NXbsWJ+fb7jhBkVFRelPf/qTvv/97+uFF15QYmKicnNzm91/1KhRuuCCC7R69WotXLhQb731lsrLy/W9733P2+aNN95QYWGhPvnkE1VVVamhoUGnTp3yBp5wOf3vVGq854y/PVFtxdJedEueMELPCNrDZrMpzhEZ9kdbrnjpmX/hL7vdLmOMz7bmLvd95kROm80mt9vt9/tUV1frhz/8obZv3+597NixQ3v27NF5550XUM3NycjI0O7du/Xkk08qNjZWd9xxh6688krvsdhsNr+O88zz53A49N3vflerV6+WJK1evVqTJ09uNeRMnTrVp/2ECRO8PRgHDhzQN7/5TWVlZemFF15QcXGxli1bJqlxwnEwhOvvtE21hfTVgQ7KmRAjSSo/fsriSoDwu+CCC1RUVOTzi+ndd99VQkKCvva1r0lq7N4/dOiQ9/mqqirt378/4PfZsmWLz7a//vWvPj9ffPHF+vjjjzV48OCzHg6HQ8OGDVNDQ4OKi4u9++zevTug65TExsZq4sSJeuyxx7R582YVFRXpo48+avY49+zZoxMnTvj1ulOnTtWGDRv097//XW+++aamTp3aavtbbrlFO3fuVHFxsZ5//nmf9sXFxXK73Vq8eLEuu+wynX/++fryyy/9PkZ/nHmskoJ6HZT2IIygW6JnBN3ZHXfcoYMHD+rOO+/UJ598opdfflkFBQXKy8vzzhe55ppr9Lvf/U5vv/22PvroI02fPj3gO7LOnj1be/bs0d13363du3dr9erVevbZZ33aLFiwQO+9957mzZun7du3a8+ePXr55Zc1b948SY3zTCZMmKAf/vCHev/991VcXKwf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kd3e1OFy+eWXa/Xq1br33nt1zz33aMiQIXrppZc0fPhwv98zOjpaBQUFzQ7ddHecm9ZxflrGuWkZ56Z1nJ+WcW7aJuDrjAAAAAQT96YBAACWIowAAABLEUYAAIClCCMAAMBSHT6MLFu2TJmZmYqJiVF2dra2bNlidUkhd//998tms/k8hg0b5n3+1KlTmjt3rnr37q34+Hh95zvfOevCciUlJbrxxhsVFxcnp9Opu+++Ww0NDeE+lKD4y1/+ookTJ6pv376y2Wxn3dfIGKNFixapT58+io2NVW5urvbs2ePT5ujRo5o6daoSExOVnJys2267TdXV1T5tPvzwQ11xxRWKiYlRRkaGHn300VAfWrud69zMmDHjrM/ShAkTfNp01XNTWFioSy65RAkJCXI6nZo0aZJ2797t0yZY36XNmzfr4osvVnR0tAYPHqxnn3021IfXLv6cm6uvvvqsz87s2bN92nTFcyNJTz31lLKysrwXLsvJydGrr77qfb67fm5CynRga9asMQ6Hw6xcudL8/e9/N7NmzTLJycmmrKzM6tJCqqCgwFx00UXm0KFD3kdFRYX3+dmzZ5uMjAyzceNGs3XrVnPZZZeZyy+/3Pt8Q0ODGT58uMnNzTXbtm0z69evNykpKSY/P9+Kw2m39evXm5/97GfmxRdfNJLMunXrfJ5/+OGHTVJSknnppZfMjh07zE033WQGDhxoTp486W0zYcIEM3LkSPPXv/7VvP3222bw4MFmypQp3ucrKytNWlqamTp1qtm5c6f5wx/+YGJjY81///d/h+sw2+Rc52b69OlmwoQJPp+lo0eP+rTpqudm/Pjx5plnnjE7d+4027dvNzfccIPp37+/qa6u9rYJxndp3759Ji4uzuTl5ZmPP/7YPP744yYiIsJs2LAhrMcbCH/OzVVXXWVmzZrl89mprKz0Pt9Vz40xxvzpT38yr7zyivn000/N7t27zT333GOioqLMzp07jTHd93MTSh06jFx66aVm7ty53p9dLpfp27evKSwstLCq0CsoKDAjR45s9rljx46ZqKgo88c//tG7bdeuXUaSKSoqMsY0/oKy2+2mtLTU2+app54yiYmJpra2NqS1h9qZv3DdbrdJT083v/zlL73bjh07ZqKjo80f/vAHY4wxH3/8sZFk/va3v3nbvPrqq8Zms5kvvvjCGGPMk08+aXr27OlzfhYsWGCGDh0a4iMKnpbCyLe+9a0W9+ku58YYY8rLy40k89Zbbxljgvdd+ulPf2ouuugin/eaPHmyGT9+fKgPKWjOPDfGNIaRu+66q8V9usu58ejZs6f5zW9+w+cmRDrsME1dXZ2Ki4uVm5vr3Wa325Wbm6uioiILKwuPPXv2qG/fvho0aJCmTp2qkpISSVJxcbHq6+t9zsuwYcPUv39/73kpKirSiBEjfO6WPH78eFVVVenvf/97eA8kxPbv36/S0lKf85GUlKTs7Gyf85GcnKyxY8d62+Tm5sput+v999/3trnyyivlcDi8bcaPH6/du3frn//8Z5iOJjQ2b94sp9OpoUOHas6cOTpy5Ij3ue50biorKyVJvXr1khS871JRUZHPa3jadKZ/p848Nx6rVq1SSkqKhg8frvz8fJ04ccL7XHc5Ny6XS2vWrFFNTY1ycnL43IRIh7xrryQdPnxYLpfL5y9TktLS0vTJJ59YVFV4ZGdn69lnn9XQoUN16NAhPfDAA7riiiu0c+dOlZaWyuFwKDk52WeftLQ0lZaWSpJKS0ubPW+e57oSz/E0d7ynnw+n0+nzfGRkpHr16uXTZuDAgWe9hue5nj17hqT+UJswYYJuvvlmDRw4UHv37tU999yj66+/XkVFRYqIiOg258btdmv+/PkaN26c9+rPwfoutdSmqqpKJ0+eVGxsbCgOKWiaOzeSdMstt2jAgAHq27evPvzwQy1YsEC7d+/Wiy++KKnrn5uPPvpIOTk5OnXqlOLj47Vu3TpdeOGF2r59O5+bEOiwYaQ7u/76671/zsrKUnZ2tgYMGKD/+Z//6XYfULTP97//fe+fR4wYoaysLJ133nnavHmzrr32WgsrC6+5c+dq586deuedd6wupcNp6dzcfvvt3j+PGDFCffr00bXXXqu9e/fqvPPOC3eZYTd06FBt375dlZWVev755zV9+nS99dZbVpfVZXXYYZqUlBRFREScNUO5rKxM6enpFlVljeTkZJ1//vn67LPPlJ6errq6Oh07dsynzennJT09vdnz5nmuK/EcT2ufk/T0dJWXl/s839DQoKNHj3a7czZo0CClpKTos88+k9Q9zs28efP05z//WZs2bdLXvvY17/ZgfZdaapOYmNjh//PQ0rlpTnZ2tiT5fHa68rlxOBwaPHiwxowZo8LCQo0cOVK/+tWv+NyESIcNIw6HQ2PGjNHGjRu929xutzZu3KicnBwLKwu/6upq7d27V3369NGYMWMUFRXlc152796tkpIS73nJycnRRx995PNL5vXXX1diYqIuvPDCsNcfSgMHDlR6errP+aiqqtL777/vcz6OHTum4uJib5s333xTbrfb+w9sTk6O/vKXv6i+vt7b5vXXX9fQoUM7xTCEv/7xj3/oyJEj6tOnj6SufW6MMZo3b57WrVunN99886yhpmB9l3Jycnxew9OmI/87da5z05zt27dLks9npyuem5a43W7V1tZ2689NSFk9g7Y1a9asMdHR0ebZZ581H3/8sbn99ttNcnKyzwzlrujHP/6x2bx5s9m/f7959913TW5urklJSTHl5eXGmMZlZf379zdvvvmm2bp1q8nJyTE5OTne/T3Lyq677jqzfft2s2HDBpOamtppl/YeP37cbNu2zWzbts1IMkuWLDHbtm0zn3/+uTGmcWlvcnKyefnll82HH35ovvWtbzW7tHf06NHm/fffN++8844ZMmSIz/LVY8eOmbS0NHPrrbeanTt3mjVr1pi4uLgOv3y1tXNz/Phx85Of/MQUFRWZ/fv3mzfeeMNcfPHFZsiQIebUqVPe1+iq52bOnDkmKSnJbN682Wd56okTJ7xtgvFd8izRvPvuu82uXbvMsmXLOvwSzXOdm88++8z8/Oc/N1u3bjX79+83L7/8shk0aJC58sorva/RVc+NMcYsXLjQvPXWW2b//v3mww8/NAsXLjQ2m8383//9nzGm+35uQqlDhxFjjHn88cdN//79jcPhMJdeeqn561//anVJITd58mTTp08f43A4TL9+/czkyZPNZ5995n3+5MmT5o477jA9e/Y0cXFx5tvf/rY5dOiQz2scOHDAXH/99SY2NtakpKSYH//4x6a+vj7chxIUmzZtMpLOekyfPt0Y07i897777jNpaWkmOjraXHvttWb37t0+r3HkyBEzZcoUEx8fbxITE83MmTPN8ePHfdrs2LHDfP3rXzfR0dGmX79+5uGHHw7XIbZZa+fmxIkT5rrrrjOpqakmKirKDBgwwMyaNeusMN9Vz01z50WSeeaZZ7xtgvVd2rRpkxk1apRxOBxm0KBBPu/REZ3r3JSUlJgrr7zS9OrVy0RHR5vBgwebu+++2+c6I8Z0zXNjjDH/9m//ZgYMGGAcDodJTU011157rTeIGNN9PzehZDPGmPD1wwAAAPjqsHNGAABA90AYAQAAliKMAAAASxFGAACApQgjAADAUoQRAABgKcIIAACwFGEEAABYijACIORmzJihSZMmWV0GgA4q0uoCAHRuNput1ecLCgr0q1/9SlzsGUBLCCMA2uXQoUPeP69du1aLFi3S7t27vdvi4+MVHx9vRWkAOgmGaQC0S3p6uveRlJQkm83msy0+Pv6sYZqrr75ad955p+bPn6+ePXsqLS1NK1asUE1NjWbOnKmEhAQNHjxYr776qs977dy5U9dff73i4+OVlpamW2+9VYcPHw7zEQMINsIIAEs899xzSklJ0ZYtW3TnnXdqzpw5+t73vqfLL79cH3zwga677jrdeuutOnHihCTp2LFjuuaaazR69Ght3bpVGzZsUFlZmf71X//V4iMB0F6EEQCWGDlypO69914NGTJE+fn5iomJUUpKimbNmqUhQ4Zo0aJFOnLkiD788ENJ0hNPPKHRo0froYce0rBhwzR69GitXLlSmzZt0qeffmrx0QBoD+aMALBEVlaW988RERHq3bu3RowY4d2WlpYmSSovL5ck7dixQ5s2bWp2/snevXt1/vnnh7hiAKFCGAFgiaioKJ+fbTabzzbPKh232y1Jqq6u1sSJE/XII4+c9Vp9+vQJYaUAQo0wAqBTuPjii/XCCy8oMzNTkZH80wV0JcwZAdApzJ07V0ePHtWUKVP0t7/9TXv37tVrr72mmTNnyuVyWV0egHYgjADoFPr27at3331XLpdL1113nUaMGKH58+crOTlZdjv/lAGdmc1wWUQAAGAh/jsBAAAsRRgBAACWIowAAABLEUYAAIClCCMAAMBShBEAAGApwggAALAUYQQAAFiKMAIAACxFGAEAAJYijAAAAEv9P6VlgXOlX8h0AAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "safe_plot = acro.surv_func(\n", " data.futime, data.death, output=\"plot\", filename=\"kaplan-mier.png\"\n", ")\n", "print(safe_plot)" ] }, { "cell_type": "markdown", "id": "9e554eea", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# ACRO functionality to let users manage their outputs\n", "\n", "### 1: List current ACRO outputs\n", "This is an example of using the print_output function to list all the outputs created so far" ] }, { "cell_type": "code", "execution_count": 25, "id": "ec960039", "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "uid: output_0\n", "status: fail\n", "type: table\n", "properties: {'method': 'crosstab'}\n", "sdc: {'summary': {'suppressed': True, 'negative': 0, 'missing': 0, 'threshold': 4, 'p-ratio': 0, 'nk-rule': 0, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [[2, 0], [2, 1], [2, 2], [4, 0]], 'p-ratio': [], 'nk-rule': [], 'all-values-are-same': []}}\n", "command: safe_table = acro.crosstab(\n", "summary: fail; threshold: 4 cells suppressed; \n", "outcome: parents great_pret pretentious usual\n", "recommend \n", "not_recom ok ok ok\n", "priority ok ok ok\n", "recommend threshold; threshold; threshold; \n", "spec_prior ok ok ok\n", "very_recom threshold; ok ok\n", "output: [parents great_pret pretentious usual\n", "recommend \n", "not_recom 1440.0 1440.0 1440.0\n", "priority 858.0 1484.0 1924.0\n", "recommend NaN NaN NaN\n", "spec_prior 2022.0 1264.0 758.0\n", "very_recom NaN 132.0 196.0]\n", "timestamp: 2025-03-06T19:39:46.897407\n", "comments: []\n", "exception: \n", "\n", "uid: output_1\n", "status: fail\n", "type: table\n", "properties: {'method': 'crosstab'}\n", "sdc: {'summary': {'suppressed': True, 'negative': 0, 'missing': 0, 'threshold': 5, 'p-ratio': 0, 'nk-rule': 0, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [[2, 0], [2, 1], [2, 2], [2, 3], [4, 0]], 'p-ratio': [], 'nk-rule': [], 'all-values-are-same': []}}\n", "command: safe_table = acro.crosstab(df.recommend, df.parents, margins=True)\n", "summary: fail; threshold: 5 cells suppressed; \n", "outcome: parents great_pret pretentious usual All\n", "recommend \n", "not_recom ok ok ok ok\n", "priority ok ok ok ok\n", "recommend threshold; threshold; threshold; threshold; \n", "spec_prior ok ok ok ok\n", "very_recom threshold; ok ok ok\n", "All ok ok ok ok\n", "output: [parents great_pret pretentious usual All\n", "recommend \n", "not_recom 1440.0 1440 1440 4320\n", "priority 858.0 1484 1924 4266\n", "spec_prior 2022.0 1264 758 4044\n", "very_recom NaN 132 196 328\n", "All 4320.0 4320 4318 12958]\n", "timestamp: 2025-03-06T19:39:46.961631\n", "comments: []\n", "exception: \n", "\n", "uid: output_2\n", "status: fail\n", "type: table\n", "properties: {'method': 'crosstab'}\n", "sdc: {'summary': {'suppressed': False, 'negative': 0, 'missing': 0, 'threshold': 4, 'p-ratio': 0, 'nk-rule': 0, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [[2, 0], [2, 1], [2, 2], [4, 0]], 'p-ratio': [], 'nk-rule': [], 'all-values-are-same': []}}\n", "command: safe_table = acro.crosstab(df.recommend, df.parents)\n", "summary: fail; threshold: 4 cells may need suppressing; \n", "outcome: parents great_pret pretentious usual\n", "recommend \n", "not_recom ok ok ok\n", "priority ok ok ok\n", "recommend threshold; threshold; threshold; \n", "spec_prior ok ok ok\n", "very_recom threshold; ok ok\n", "output: [parents great_pret pretentious usual\n", "recommend \n", "not_recom 1440 1440 1440\n", "priority 858 1484 1924\n", "recommend 0 0 2\n", "spec_prior 2022 1264 758\n", "very_recom 0 132 196]\n", "timestamp: 2025-03-06T19:39:46.980090\n", "comments: []\n", "exception: \n", "\n", "uid: output_3\n", "status: fail\n", "type: table\n", "properties: {'method': 'crosstab'}\n", "sdc: {'summary': {'suppressed': True, 'negative': 0, 'missing': 0, 'threshold': 1, 'p-ratio': 4, 'nk-rule': 4, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [[2, 2]], 'p-ratio': [[2, 0], [2, 1], [2, 2], [4, 0]], 'nk-rule': [[2, 0], [2, 1], [2, 2], [4, 0]], 'all-values-are-same': []}}\n", "command: safe_table = acro.crosstab(\n", "summary: fail; threshold: 1 cells suppressed; p-ratio: 4 cells suppressed; nk-rule: 4 cells suppressed; \n", "outcome: parents great_pret pretentious \\\n", "recommend \n", "not_recom ok ok \n", "priority ok ok \n", "recommend p-ratio; nk-rule; p-ratio; nk-rule; \n", "spec_prior ok ok \n", "very_recom p-ratio; nk-rule; ok \n", "\n", "parents usual \n", "recommend \n", "not_recom ok \n", "priority ok \n", "recommend threshold; p-ratio; nk-rule; \n", "spec_prior ok \n", "very_recom ok \n", "output: [parents great_pret pretentious usual\n", "recommend \n", "not_recom 1440.0 1440.0 1440.0\n", "priority 858.0 1484.0 1924.0\n", "recommend NaN NaN NaN\n", "spec_prior 2022.0 1264.0 758.0\n", "very_recom NaN 132.0 196.0]\n", "timestamp: 2025-03-06T19:39:47.019919\n", "comments: []\n", "exception: \n", "\n", "uid: output_4\n", "status: fail\n", "type: table\n", "properties: {'method': 'crosstab'}\n", "sdc: {'summary': {'suppressed': True, 'negative': 0, 'missing': 0, 'threshold': 2, 'p-ratio': 8, 'nk-rule': 8, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [[2, 2], [2, 5]], 'p-ratio': [[2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [4, 0], [4, 3]], 'nk-rule': [[2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [4, 0], [4, 3]], 'all-values-are-same': []}}\n", "command: safe_table = acro.crosstab(\n", "summary: fail; threshold: 2 cells suppressed; p-ratio: 8 cells suppressed; nk-rule: 8 cells suppressed; \n", "outcome: mode_aggfunc \\\n", "parents great_pret pretentious \n", "recommend \n", "not_recom ok ok \n", "priority ok ok \n", "recommend p-ratio; nk-rule; p-ratio; nk-rule; \n", "spec_prior ok ok \n", "very_recom p-ratio; nk-rule; ok \n", "\n", " mean \\\n", "parents usual great_pret \n", "recommend \n", "not_recom ok ok \n", "priority ok ok \n", "recommend threshold; p-ratio; nk-rule; p-ratio; nk-rule; \n", "spec_prior ok ok \n", "very_recom ok p-ratio; nk-rule; \n", "\n", " \n", "parents pretentious usual \n", "recommend \n", "not_recom ok ok \n", "priority ok ok \n", "recommend p-ratio; nk-rule; threshold; p-ratio; nk-rule; \n", "spec_prior ok ok \n", "very_recom ok ok \n", "output: [ mode_aggfunc mean \n", "parents great_pret pretentious usual great_pret pretentious usual\n", "recommend \n", "not_recom 2.0 1.0 1.0 3.125694 3.105556 3.074306\n", "priority 1.0 1.0 1.0 2.665501 3.030323 3.116944\n", "recommend NaN NaN NaN NaN NaN NaN\n", "spec_prior 3.0 3.0 3.0 3.353610 3.370253 3.393140\n", "very_recom NaN 1.0 1.0 NaN 2.204545 2.244898]\n", "timestamp: 2025-03-06T19:39:47.068066\n", "comments: []\n", "exception: \n", "\n", "uid: output_5\n", "status: pass\n", "type: table\n", "properties: {'method': 'pivot_table'}\n", "sdc: {'summary': {'suppressed': True, 'negative': 0, 'missing': 0, 'threshold': 0, 'p-ratio': 0, 'nk-rule': 0, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [], 'p-ratio': [], 'nk-rule': [], 'all-values-are-same': []}}\n", "command: table = acro.pivot_table(\n", "summary: pass\n", "outcome: mean std\n", " children children\n", "parents \n", "great_pret ok ok\n", "pretentious ok ok\n", "usual ok ok\n", "output: [ mean std\n", " children children\n", "parents \n", "great_pret 3.140972 2.270396\n", "pretentious 3.129630 2.250436\n", "usual 3.110648 2.213072]\n", "timestamp: 2025-03-06T19:39:47.105651\n", "comments: []\n", "exception: \n", "\n", "uid: output_6\n", "status: fail\n", "type: table\n", "properties: {'method': 'pivot_table'}\n", "sdc: {'summary': {'suppressed': True, 'negative': 0, 'missing': 0, 'threshold': 5, 'p-ratio': 5, 'nk-rule': 5, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [[0, 2], [0, 4], [1, 2], [2, 2], [3, 2]], 'p-ratio': [[0, 2], [0, 4], [1, 2], [2, 2], [3, 2]], 'nk-rule': [[0, 2], [0, 4], [1, 2], [2, 2], [3, 2]], 'all-values-are-same': []}}\n", "command: safe_table = acro.pivot_table(\n", "summary: fail; threshold: 5 cells suppressed; p-ratio: 5 cells suppressed; nk-rule: 5 cells suppressed; \n", "outcome: children \\\n", "recommend not_recom priority recommend spec_prior \n", "parents \n", "great_pret ok ok threshold; p-ratio; nk-rule; ok \n", "pretentious ok ok threshold; p-ratio; nk-rule; ok \n", "usual ok ok threshold; p-ratio; nk-rule; ok \n", "All ok ok threshold; p-ratio; nk-rule; ok \n", "\n", " \n", "recommend very_recom All \n", "parents \n", "great_pret threshold; p-ratio; nk-rule; ok \n", "pretentious ok ok \n", "usual ok ok \n", "All ok ok \n", "output: [ children \n", "recommend not_recom priority spec_prior very_recom All\n", "parents \n", "great_pret 3.125694 2.665501 3.353610 NaN 3.140972\n", "pretentious 3.105556 3.030323 3.370253 2.204545 3.129630\n", "usual 3.074306 3.116944 3.393140 2.244898 3.111626\n", "All 3.101852 2.996015 3.366222 2.228659 3.127412]\n", "timestamp: 2025-03-06T19:39:47.231513\n", "comments: []\n", "exception: \n", "\n", "uid: output_7\n", "status: pass\n", "type: regression\n", "properties: {'method': 'ols', 'dof': 12958.0}\n", "sdc: {}\n", "command: results = acro.ols(y, x)\n", "summary: pass; dof=12958.0 >= 10\n", "outcome: Empty DataFrame\n", "Columns: []\n", "Index: []\n", "output: [ recommend R-squared: 0.001\n", "Dep. Variable: \n", "Model: OLS Adj. R-squared: 0.001000\n", "Method: Least Squares F-statistic: 13.830000\n", "Date: Thu, 06 Mar 2025 Prob (F-statistic): 0.000201\n", "Time: 19:39:47 Log-Likelihood: -25121.000000\n", "No. Observations: 12960 AIC: 50250.000000\n", "Df Residuals: 12958 BIC: 50260.000000\n", "Df Model: 1 NaN NaN\n", "Covariance Type: nonrobust NaN NaN, coef std err t P>|t| [0.025 0.975]\n", "const 2.2099 0.025 87.263 0.0 2.160 2.260\n", "children 0.0245 0.007 3.718 0.0 0.012 0.037, 77090.215 Durbin-Watson: 2.883\n", "Omnibus: \n", "Prob(Omnibus): 0.000 Jarque-Bera (JB): 1741.57\n", "Skew: -0.486 Prob(JB): 0.00\n", "Kurtosis: 1.489 Cond. No. 6.90]\n", "timestamp: 2025-03-06T19:39:47.388052\n", "comments: []\n", "exception: \n", "\n", "uid: output_8\n", "status: pass\n", "type: regression\n", "properties: {'method': 'olsr', 'dof': 12958.0}\n", "sdc: {}\n", "command: results = acro.olsr(formula=\"recommend ~ children\", data=new_df)\n", "summary: pass; dof=12958.0 >= 10\n", "outcome: Empty DataFrame\n", "Columns: []\n", "Index: []\n", "output: [ recommend R-squared: 0.001\n", "Dep. Variable: \n", "Model: OLS Adj. R-squared: 0.001000\n", "Method: Least Squares F-statistic: 13.830000\n", "Date: Thu, 06 Mar 2025 Prob (F-statistic): 0.000201\n", "Time: 19:39:47 Log-Likelihood: -25121.000000\n", "No. Observations: 12960 AIC: 50250.000000\n", "Df Residuals: 12958 BIC: 50260.000000\n", "Df Model: 1 NaN NaN\n", "Covariance Type: nonrobust NaN NaN, coef std err t P>|t| [0.025 0.975]\n", "Intercept 2.2099 0.025 87.263 0.0 2.160 2.260\n", "children 0.0245 0.007 3.718 0.0 0.012 0.037, 77090.215 Durbin-Watson: 2.883\n", "Omnibus: \n", "Prob(Omnibus): 0.000 Jarque-Bera (JB): 1741.57\n", "Skew: -0.486 Prob(JB): 0.00\n", "Kurtosis: 1.489 Cond. No. 6.90]\n", "timestamp: 2025-03-06T19:39:47.414293\n", "comments: []\n", "exception: \n", "\n", "uid: output_9\n", "status: pass\n", "type: regression\n", "properties: {'method': 'probit', 'dof': 12958.0}\n", "sdc: {}\n", "command: results = acro.probit(y, x)\n", "summary: pass; dof=12958.0 >= 10\n", "outcome: Empty DataFrame\n", "Columns: []\n", "Index: []\n", "output: [ finance No. Observations: 12960\n", "Dep. Variable: \n", "Model: Probit Df Residuals: 12958.000000\n", "Method: MLE Df Model: 1.000000\n", "Date: Thu, 06 Mar 2025 Pseudo R-squ.: 0.000004\n", "Time: 19:39:47 Log-Likelihood: -8983.200000\n", "converged: True LL-Null: -8983.200000\n", "Covariance Type: nonrobust LLR p-value: 0.799200, coef std err z P>|z| [0.025 0.975]\n", "const -0.0039 0.019 -0.207 0.836 -0.041 0.033\n", "children 0.0012 0.005 0.254 0.799 -0.008 0.011]\n", "timestamp: 2025-03-06T19:39:47.439598\n", "comments: []\n", "exception: \n", "\n", "uid: output_10\n", "status: pass\n", "type: regression\n", "properties: {'method': 'logit', 'dof': 12958.0}\n", "sdc: {}\n", "command: results = acro.logit(y, x)\n", "summary: pass; dof=12958.0 >= 10\n", "outcome: Empty DataFrame\n", "Columns: []\n", "Index: []\n", "output: [ finance No. Observations: 12960\n", "Dep. Variable: \n", "Model: Logit Df Residuals: 12958.000000\n", "Method: MLE Df Model: 1.000000\n", "Date: Thu, 06 Mar 2025 Pseudo R-squ.: 0.000004\n", "Time: 19:39:47 Log-Likelihood: -8983.200000\n", "converged: True LL-Null: -8983.200000\n", "Covariance Type: nonrobust LLR p-value: 0.799200, coef std err z P>|z| [0.025 0.975]\n", "const -0.0062 0.030 -0.207 0.836 -0.065 0.053\n", "children 0.0020 0.008 0.254 0.799 -0.013 0.017]\n", "timestamp: 2025-03-06T19:39:47.457696\n", "comments: []\n", "exception: \n", "\n", "uid: output_11\n", "status: fail\n", "type: table\n", "properties: {'method': 'surv_func'}\n", "sdc: {'summary': {'suppressed': True, 'negative': 0, 'missing': 0, 'threshold': 76, 'p-ratio': 0, 'nk-rule': 0, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [[1, 0], [1, 1], [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3], [4, 0], [4, 1], [4, 2], [4, 3], [5, 0], [5, 1], [5, 2], [5, 3], [6, 0], [6, 1], [6, 2], [6, 3], [7, 0], [7, 1], [7, 2], [7, 3], [8, 0], [8, 1], [8, 2], [8, 3], [9, 0], [9, 1], [9, 2], [9, 3], [10, 0], [10, 1], [10, 2], [10, 3], [11, 0], [11, 1], [11, 2], [11, 3], [12, 0], [12, 1], [12, 2], [12, 3], [13, 0], [13, 1], [13, 2], [13, 3], [14, 0], [14, 1], [14, 2], [14, 3], [15, 0], [15, 1], [15, 2], [15, 3], [16, 0], [16, 1], [16, 2], [16, 3], [17, 0], [17, 1], [17, 2], [17, 3], [18, 0], [18, 1], [18, 2], [18, 3], [19, 0], [19, 1], [19, 2], [19, 3]], 'p-ratio': [], 'nk-rule': [], 'all-values-are-same': []}}\n", "command: safe_table = acro.surv_func(data.futime, data.death, output=\"table\")\n", "summary: fail; threshold: 76 cells suppressed; \n", "outcome: Surv_prob Surv_prob_SE num_at_risk num_events\n", "Time \n", "51 ok ok ok ok\n", "69 threshold; threshold; threshold; threshold; \n", "85 threshold; threshold; threshold; threshold; \n", "91 threshold; threshold; threshold; threshold; \n", "115 threshold; threshold; threshold; threshold; \n", "372 threshold; threshold; threshold; threshold; \n", "667 threshold; threshold; threshold; threshold; \n", "874 threshold; threshold; threshold; threshold; \n", "1039 threshold; threshold; threshold; threshold; \n", "1046 threshold; threshold; threshold; threshold; \n", "1281 threshold; threshold; threshold; threshold; \n", "1286 threshold; threshold; threshold; threshold; \n", "1326 threshold; threshold; threshold; threshold; \n", "1355 threshold; threshold; threshold; threshold; \n", "1626 threshold; threshold; threshold; threshold; \n", "1903 threshold; threshold; threshold; threshold; \n", "1914 threshold; threshold; threshold; threshold; \n", "2776 threshold; threshold; threshold; threshold; \n", "2851 threshold; threshold; threshold; threshold; \n", "3309 threshold; threshold; threshold; threshold; \n", "output: [ Surv prob Surv prob SE num at risk num events\n", "Time \n", "51 0.95 0.048734 20.0 1.0\n", "69 NaN NaN NaN NaN\n", "85 NaN NaN NaN NaN\n", "91 NaN NaN NaN NaN\n", "115 NaN NaN NaN NaN\n", "372 NaN NaN NaN NaN\n", "667 NaN NaN NaN NaN\n", "874 NaN NaN NaN NaN\n", "1039 NaN NaN NaN NaN\n", "1046 NaN NaN NaN NaN\n", "1281 NaN NaN NaN NaN\n", "1286 NaN NaN NaN NaN\n", "1326 NaN NaN NaN NaN\n", "1355 NaN NaN NaN NaN\n", "1626 NaN NaN NaN NaN\n", "1903 NaN NaN NaN NaN\n", "1914 NaN NaN NaN NaN\n", "2776 NaN NaN NaN NaN\n", "2851 NaN NaN NaN NaN\n", "3309 NaN NaN NaN NaN]\n", "timestamp: 2025-03-06T19:39:48.298262\n", "comments: []\n", "exception: \n", "\n", "uid: output_12\n", "status: fail\n", "type: survival plot\n", "properties: {'method': 'surv_func'}\n", "sdc: {'summary': {'suppressed': True, 'negative': 0, 'missing': 0, 'threshold': 76, 'p-ratio': 0, 'nk-rule': 0, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [[1, 0], [1, 1], [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3], [4, 0], [4, 1], [4, 2], [4, 3], [5, 0], [5, 1], [5, 2], [5, 3], [6, 0], [6, 1], [6, 2], [6, 3], [7, 0], [7, 1], [7, 2], [7, 3], [8, 0], [8, 1], [8, 2], [8, 3], [9, 0], [9, 1], [9, 2], [9, 3], [10, 0], [10, 1], [10, 2], [10, 3], [11, 0], [11, 1], [11, 2], [11, 3], [12, 0], [12, 1], [12, 2], [12, 3], [13, 0], [13, 1], [13, 2], [13, 3], [14, 0], [14, 1], [14, 2], [14, 3], [15, 0], [15, 1], [15, 2], [15, 3], [16, 0], [16, 1], [16, 2], [16, 3], [17, 0], [17, 1], [17, 2], [17, 3], [18, 0], [18, 1], [18, 2], [18, 3], [19, 0], [19, 1], [19, 2], [19, 3]], 'p-ratio': [], 'nk-rule': [], 'all-values-are-same': []}}\n", "command: safe_plot = acro.surv_func(\n", "summary: fail; threshold: 76 cells suppressed; \n", "outcome: Empty DataFrame\n", "Columns: []\n", "Index: []\n", "output: ['acro_artifacts/kaplan-mier_0.png']\n", "timestamp: 2025-03-06T19:39:48.450221\n", "comments: []\n", "exception: \n", "\n", "\n" ] }, { "data": { "text/plain": [ "'uid: output_0\\nstatus: fail\\ntype: table\\nproperties: {\\'method\\': \\'crosstab\\'}\\nsdc: {\\'summary\\': {\\'suppressed\\': True, \\'negative\\': 0, \\'missing\\': 0, \\'threshold\\': 4, \\'p-ratio\\': 0, \\'nk-rule\\': 0, \\'all-values-are-same\\': 0}, \\'cells\\': {\\'negative\\': [], \\'missing\\': [], \\'threshold\\': [[2, 0], [2, 1], [2, 2], [4, 0]], \\'p-ratio\\': [], \\'nk-rule\\': [], \\'all-values-are-same\\': []}}\\ncommand: safe_table = acro.crosstab(\\nsummary: fail; threshold: 4 cells suppressed; \\noutcome: parents great_pret pretentious usual\\nrecommend \\nnot_recom ok ok ok\\npriority ok ok ok\\nrecommend threshold; threshold; threshold; \\nspec_prior ok ok ok\\nvery_recom threshold; ok ok\\noutput: [parents great_pret pretentious usual\\nrecommend \\nnot_recom 1440.0 1440.0 1440.0\\npriority 858.0 1484.0 1924.0\\nrecommend NaN NaN NaN\\nspec_prior 2022.0 1264.0 758.0\\nvery_recom NaN 132.0 196.0]\\ntimestamp: 2025-03-06T19:39:46.897407\\ncomments: []\\nexception: \\n\\nuid: output_1\\nstatus: fail\\ntype: table\\nproperties: {\\'method\\': \\'crosstab\\'}\\nsdc: {\\'summary\\': {\\'suppressed\\': True, \\'negative\\': 0, \\'missing\\': 0, \\'threshold\\': 5, \\'p-ratio\\': 0, \\'nk-rule\\': 0, \\'all-values-are-same\\': 0}, \\'cells\\': {\\'negative\\': [], \\'missing\\': [], \\'threshold\\': [[2, 0], [2, 1], [2, 2], [2, 3], [4, 0]], \\'p-ratio\\': [], \\'nk-rule\\': [], \\'all-values-are-same\\': []}}\\ncommand: safe_table = acro.crosstab(df.recommend, df.parents, margins=True)\\nsummary: fail; threshold: 5 cells suppressed; \\noutcome: parents great_pret pretentious usual All\\nrecommend \\nnot_recom ok ok ok ok\\npriority ok ok ok ok\\nrecommend threshold; threshold; threshold; threshold; \\nspec_prior ok ok ok ok\\nvery_recom threshold; ok ok ok\\nAll ok ok ok ok\\noutput: [parents great_pret pretentious usual All\\nrecommend \\nnot_recom 1440.0 1440 1440 4320\\npriority 858.0 1484 1924 4266\\nspec_prior 2022.0 1264 758 4044\\nvery_recom NaN 132 196 328\\nAll 4320.0 4320 4318 12958]\\ntimestamp: 2025-03-06T19:39:46.961631\\ncomments: []\\nexception: \\n\\nuid: output_2\\nstatus: fail\\ntype: table\\nproperties: {\\'method\\': \\'crosstab\\'}\\nsdc: {\\'summary\\': {\\'suppressed\\': False, \\'negative\\': 0, \\'missing\\': 0, \\'threshold\\': 4, \\'p-ratio\\': 0, \\'nk-rule\\': 0, \\'all-values-are-same\\': 0}, \\'cells\\': {\\'negative\\': [], \\'missing\\': [], \\'threshold\\': [[2, 0], [2, 1], [2, 2], [4, 0]], \\'p-ratio\\': [], \\'nk-rule\\': [], \\'all-values-are-same\\': []}}\\ncommand: safe_table = acro.crosstab(df.recommend, df.parents)\\nsummary: fail; threshold: 4 cells may need suppressing; \\noutcome: parents great_pret pretentious usual\\nrecommend \\nnot_recom ok ok ok\\npriority ok ok ok\\nrecommend threshold; threshold; threshold; \\nspec_prior ok ok ok\\nvery_recom threshold; ok ok\\noutput: [parents great_pret pretentious usual\\nrecommend \\nnot_recom 1440 1440 1440\\npriority 858 1484 1924\\nrecommend 0 0 2\\nspec_prior 2022 1264 758\\nvery_recom 0 132 196]\\ntimestamp: 2025-03-06T19:39:46.980090\\ncomments: []\\nexception: \\n\\nuid: output_3\\nstatus: fail\\ntype: table\\nproperties: {\\'method\\': \\'crosstab\\'}\\nsdc: {\\'summary\\': {\\'suppressed\\': True, \\'negative\\': 0, \\'missing\\': 0, \\'threshold\\': 1, \\'p-ratio\\': 4, \\'nk-rule\\': 4, \\'all-values-are-same\\': 0}, \\'cells\\': {\\'negative\\': [], \\'missing\\': [], \\'threshold\\': [[2, 2]], \\'p-ratio\\': [[2, 0], [2, 1], [2, 2], [4, 0]], \\'nk-rule\\': [[2, 0], [2, 1], [2, 2], [4, 0]], \\'all-values-are-same\\': []}}\\ncommand: safe_table = acro.crosstab(\\nsummary: fail; threshold: 1 cells suppressed; p-ratio: 4 cells suppressed; nk-rule: 4 cells suppressed; \\noutcome: parents great_pret pretentious \\\\\\nrecommend \\nnot_recom ok ok \\npriority ok ok \\nrecommend p-ratio; nk-rule; p-ratio; nk-rule; \\nspec_prior ok ok \\nvery_recom p-ratio; nk-rule; ok \\n\\nparents usual \\nrecommend \\nnot_recom ok \\npriority ok \\nrecommend threshold; p-ratio; nk-rule; \\nspec_prior ok \\nvery_recom ok \\noutput: [parents great_pret pretentious usual\\nrecommend \\nnot_recom 1440.0 1440.0 1440.0\\npriority 858.0 1484.0 1924.0\\nrecommend NaN NaN NaN\\nspec_prior 2022.0 1264.0 758.0\\nvery_recom NaN 132.0 196.0]\\ntimestamp: 2025-03-06T19:39:47.019919\\ncomments: []\\nexception: \\n\\nuid: output_4\\nstatus: fail\\ntype: table\\nproperties: {\\'method\\': \\'crosstab\\'}\\nsdc: {\\'summary\\': {\\'suppressed\\': True, \\'negative\\': 0, \\'missing\\': 0, \\'threshold\\': 2, \\'p-ratio\\': 8, \\'nk-rule\\': 8, \\'all-values-are-same\\': 0}, \\'cells\\': {\\'negative\\': [], \\'missing\\': [], \\'threshold\\': [[2, 2], [2, 5]], \\'p-ratio\\': [[2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [4, 0], [4, 3]], \\'nk-rule\\': [[2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [4, 0], [4, 3]], \\'all-values-are-same\\': []}}\\ncommand: safe_table = acro.crosstab(\\nsummary: fail; threshold: 2 cells suppressed; p-ratio: 8 cells suppressed; nk-rule: 8 cells suppressed; \\noutcome: mode_aggfunc \\\\\\nparents great_pret pretentious \\nrecommend \\nnot_recom ok ok \\npriority ok ok \\nrecommend p-ratio; nk-rule; p-ratio; nk-rule; \\nspec_prior ok ok \\nvery_recom p-ratio; nk-rule; ok \\n\\n mean \\\\\\nparents usual great_pret \\nrecommend \\nnot_recom ok ok \\npriority ok ok \\nrecommend threshold; p-ratio; nk-rule; p-ratio; nk-rule; \\nspec_prior ok ok \\nvery_recom ok p-ratio; nk-rule; \\n\\n \\nparents pretentious usual \\nrecommend \\nnot_recom ok ok \\npriority ok ok \\nrecommend p-ratio; nk-rule; threshold; p-ratio; nk-rule; \\nspec_prior ok ok \\nvery_recom ok ok \\noutput: [ mode_aggfunc mean \\nparents great_pret pretentious usual great_pret pretentious usual\\nrecommend \\nnot_recom 2.0 1.0 1.0 3.125694 3.105556 3.074306\\npriority 1.0 1.0 1.0 2.665501 3.030323 3.116944\\nrecommend NaN NaN NaN NaN NaN NaN\\nspec_prior 3.0 3.0 3.0 3.353610 3.370253 3.393140\\nvery_recom NaN 1.0 1.0 NaN 2.204545 2.244898]\\ntimestamp: 2025-03-06T19:39:47.068066\\ncomments: []\\nexception: \\n\\nuid: output_5\\nstatus: pass\\ntype: table\\nproperties: {\\'method\\': \\'pivot_table\\'}\\nsdc: {\\'summary\\': {\\'suppressed\\': True, \\'negative\\': 0, \\'missing\\': 0, \\'threshold\\': 0, \\'p-ratio\\': 0, \\'nk-rule\\': 0, \\'all-values-are-same\\': 0}, \\'cells\\': {\\'negative\\': [], \\'missing\\': [], \\'threshold\\': [], \\'p-ratio\\': [], \\'nk-rule\\': [], \\'all-values-are-same\\': []}}\\ncommand: table = acro.pivot_table(\\nsummary: pass\\noutcome: mean std\\n children children\\nparents \\ngreat_pret ok ok\\npretentious ok ok\\nusual ok ok\\noutput: [ mean std\\n children children\\nparents \\ngreat_pret 3.140972 2.270396\\npretentious 3.129630 2.250436\\nusual 3.110648 2.213072]\\ntimestamp: 2025-03-06T19:39:47.105651\\ncomments: []\\nexception: \\n\\nuid: output_6\\nstatus: fail\\ntype: table\\nproperties: {\\'method\\': \\'pivot_table\\'}\\nsdc: {\\'summary\\': {\\'suppressed\\': True, \\'negative\\': 0, \\'missing\\': 0, \\'threshold\\': 5, \\'p-ratio\\': 5, \\'nk-rule\\': 5, \\'all-values-are-same\\': 0}, \\'cells\\': {\\'negative\\': [], \\'missing\\': [], \\'threshold\\': [[0, 2], [0, 4], [1, 2], [2, 2], [3, 2]], \\'p-ratio\\': [[0, 2], [0, 4], [1, 2], [2, 2], [3, 2]], \\'nk-rule\\': [[0, 2], [0, 4], [1, 2], [2, 2], [3, 2]], \\'all-values-are-same\\': []}}\\ncommand: safe_table = acro.pivot_table(\\nsummary: fail; threshold: 5 cells suppressed; p-ratio: 5 cells suppressed; nk-rule: 5 cells suppressed; \\noutcome: children \\\\\\nrecommend not_recom priority recommend spec_prior \\nparents \\ngreat_pret ok ok threshold; p-ratio; nk-rule; ok \\npretentious ok ok threshold; p-ratio; nk-rule; ok \\nusual ok ok threshold; p-ratio; nk-rule; ok \\nAll ok ok threshold; p-ratio; nk-rule; ok \\n\\n \\nrecommend very_recom All \\nparents \\ngreat_pret threshold; p-ratio; nk-rule; ok \\npretentious ok ok \\nusual ok ok \\nAll ok ok \\noutput: [ children \\nrecommend not_recom priority spec_prior very_recom All\\nparents \\ngreat_pret 3.125694 2.665501 3.353610 NaN 3.140972\\npretentious 3.105556 3.030323 3.370253 2.204545 3.129630\\nusual 3.074306 3.116944 3.393140 2.244898 3.111626\\nAll 3.101852 2.996015 3.366222 2.228659 3.127412]\\ntimestamp: 2025-03-06T19:39:47.231513\\ncomments: []\\nexception: \\n\\nuid: output_7\\nstatus: pass\\ntype: regression\\nproperties: {\\'method\\': \\'ols\\', \\'dof\\': 12958.0}\\nsdc: {}\\ncommand: results = acro.ols(y, x)\\nsummary: pass; dof=12958.0 >= 10\\noutcome: Empty DataFrame\\nColumns: []\\nIndex: []\\noutput: [ recommend R-squared: 0.001\\nDep. Variable: \\nModel: OLS Adj. R-squared: 0.001000\\nMethod: Least Squares F-statistic: 13.830000\\nDate: Thu, 06 Mar 2025 Prob (F-statistic): 0.000201\\nTime: 19:39:47 Log-Likelihood: -25121.000000\\nNo. Observations: 12960 AIC: 50250.000000\\nDf Residuals: 12958 BIC: 50260.000000\\nDf Model: 1 NaN NaN\\nCovariance Type: nonrobust NaN NaN, coef std err t P>|t| [0.025 0.975]\\nconst 2.2099 0.025 87.263 0.0 2.160 2.260\\nchildren 0.0245 0.007 3.718 0.0 0.012 0.037, 77090.215 Durbin-Watson: 2.883\\nOmnibus: \\nProb(Omnibus): 0.000 Jarque-Bera (JB): 1741.57\\nSkew: -0.486 Prob(JB): 0.00\\nKurtosis: 1.489 Cond. No. 6.90]\\ntimestamp: 2025-03-06T19:39:47.388052\\ncomments: []\\nexception: \\n\\nuid: output_8\\nstatus: pass\\ntype: regression\\nproperties: {\\'method\\': \\'olsr\\', \\'dof\\': 12958.0}\\nsdc: {}\\ncommand: results = acro.olsr(formula=\"recommend ~ children\", data=new_df)\\nsummary: pass; dof=12958.0 >= 10\\noutcome: Empty DataFrame\\nColumns: []\\nIndex: []\\noutput: [ recommend R-squared: 0.001\\nDep. Variable: \\nModel: OLS Adj. R-squared: 0.001000\\nMethod: Least Squares F-statistic: 13.830000\\nDate: Thu, 06 Mar 2025 Prob (F-statistic): 0.000201\\nTime: 19:39:47 Log-Likelihood: -25121.000000\\nNo. Observations: 12960 AIC: 50250.000000\\nDf Residuals: 12958 BIC: 50260.000000\\nDf Model: 1 NaN NaN\\nCovariance Type: nonrobust NaN NaN, coef std err t P>|t| [0.025 0.975]\\nIntercept 2.2099 0.025 87.263 0.0 2.160 2.260\\nchildren 0.0245 0.007 3.718 0.0 0.012 0.037, 77090.215 Durbin-Watson: 2.883\\nOmnibus: \\nProb(Omnibus): 0.000 Jarque-Bera (JB): 1741.57\\nSkew: -0.486 Prob(JB): 0.00\\nKurtosis: 1.489 Cond. No. 6.90]\\ntimestamp: 2025-03-06T19:39:47.414293\\ncomments: []\\nexception: \\n\\nuid: output_9\\nstatus: pass\\ntype: regression\\nproperties: {\\'method\\': \\'probit\\', \\'dof\\': 12958.0}\\nsdc: {}\\ncommand: results = acro.probit(y, x)\\nsummary: pass; dof=12958.0 >= 10\\noutcome: Empty DataFrame\\nColumns: []\\nIndex: []\\noutput: [ finance No. Observations: 12960\\nDep. Variable: \\nModel: Probit Df Residuals: 12958.000000\\nMethod: MLE Df Model: 1.000000\\nDate: Thu, 06 Mar 2025 Pseudo R-squ.: 0.000004\\nTime: 19:39:47 Log-Likelihood: -8983.200000\\nconverged: True LL-Null: -8983.200000\\nCovariance Type: nonrobust LLR p-value: 0.799200, coef std err z P>|z| [0.025 0.975]\\nconst -0.0039 0.019 -0.207 0.836 -0.041 0.033\\nchildren 0.0012 0.005 0.254 0.799 -0.008 0.011]\\ntimestamp: 2025-03-06T19:39:47.439598\\ncomments: []\\nexception: \\n\\nuid: output_10\\nstatus: pass\\ntype: regression\\nproperties: {\\'method\\': \\'logit\\', \\'dof\\': 12958.0}\\nsdc: {}\\ncommand: results = acro.logit(y, x)\\nsummary: pass; dof=12958.0 >= 10\\noutcome: Empty DataFrame\\nColumns: []\\nIndex: []\\noutput: [ finance No. Observations: 12960\\nDep. Variable: \\nModel: Logit Df Residuals: 12958.000000\\nMethod: MLE Df Model: 1.000000\\nDate: Thu, 06 Mar 2025 Pseudo R-squ.: 0.000004\\nTime: 19:39:47 Log-Likelihood: -8983.200000\\nconverged: True LL-Null: -8983.200000\\nCovariance Type: nonrobust LLR p-value: 0.799200, coef std err z P>|z| [0.025 0.975]\\nconst -0.0062 0.030 -0.207 0.836 -0.065 0.053\\nchildren 0.0020 0.008 0.254 0.799 -0.013 0.017]\\ntimestamp: 2025-03-06T19:39:47.457696\\ncomments: []\\nexception: \\n\\nuid: output_11\\nstatus: fail\\ntype: table\\nproperties: {\\'method\\': \\'surv_func\\'}\\nsdc: {\\'summary\\': {\\'suppressed\\': True, \\'negative\\': 0, \\'missing\\': 0, \\'threshold\\': 76, \\'p-ratio\\': 0, \\'nk-rule\\': 0, \\'all-values-are-same\\': 0}, \\'cells\\': {\\'negative\\': [], \\'missing\\': [], \\'threshold\\': [[1, 0], [1, 1], [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3], [4, 0], [4, 1], [4, 2], [4, 3], [5, 0], [5, 1], [5, 2], [5, 3], [6, 0], [6, 1], [6, 2], [6, 3], [7, 0], [7, 1], [7, 2], [7, 3], [8, 0], [8, 1], [8, 2], [8, 3], [9, 0], [9, 1], [9, 2], [9, 3], [10, 0], [10, 1], [10, 2], [10, 3], [11, 0], [11, 1], [11, 2], [11, 3], [12, 0], [12, 1], [12, 2], [12, 3], [13, 0], [13, 1], [13, 2], [13, 3], [14, 0], [14, 1], [14, 2], [14, 3], [15, 0], [15, 1], [15, 2], [15, 3], [16, 0], [16, 1], [16, 2], [16, 3], [17, 0], [17, 1], [17, 2], [17, 3], [18, 0], [18, 1], [18, 2], [18, 3], [19, 0], [19, 1], [19, 2], [19, 3]], \\'p-ratio\\': [], \\'nk-rule\\': [], \\'all-values-are-same\\': []}}\\ncommand: safe_table = acro.surv_func(data.futime, data.death, output=\"table\")\\nsummary: fail; threshold: 76 cells suppressed; \\noutcome: Surv_prob Surv_prob_SE num_at_risk num_events\\nTime \\n51 ok ok ok ok\\n69 threshold; threshold; threshold; threshold; \\n85 threshold; threshold; threshold; threshold; \\n91 threshold; threshold; threshold; threshold; \\n115 threshold; threshold; threshold; threshold; \\n372 threshold; threshold; threshold; threshold; \\n667 threshold; threshold; threshold; threshold; \\n874 threshold; threshold; threshold; threshold; \\n1039 threshold; threshold; threshold; threshold; \\n1046 threshold; threshold; threshold; threshold; \\n1281 threshold; threshold; threshold; threshold; \\n1286 threshold; threshold; threshold; threshold; \\n1326 threshold; threshold; threshold; threshold; \\n1355 threshold; threshold; threshold; threshold; \\n1626 threshold; threshold; threshold; threshold; \\n1903 threshold; threshold; threshold; threshold; \\n1914 threshold; threshold; threshold; threshold; \\n2776 threshold; threshold; threshold; threshold; \\n2851 threshold; threshold; threshold; threshold; \\n3309 threshold; threshold; threshold; threshold; \\noutput: [ Surv prob Surv prob SE num at risk num events\\nTime \\n51 0.95 0.048734 20.0 1.0\\n69 NaN NaN NaN NaN\\n85 NaN NaN NaN NaN\\n91 NaN NaN NaN NaN\\n115 NaN NaN NaN NaN\\n372 NaN NaN NaN NaN\\n667 NaN NaN NaN NaN\\n874 NaN NaN NaN NaN\\n1039 NaN NaN NaN NaN\\n1046 NaN NaN NaN NaN\\n1281 NaN NaN NaN NaN\\n1286 NaN NaN NaN NaN\\n1326 NaN NaN NaN NaN\\n1355 NaN NaN NaN NaN\\n1626 NaN NaN NaN NaN\\n1903 NaN NaN NaN NaN\\n1914 NaN NaN NaN NaN\\n2776 NaN NaN NaN NaN\\n2851 NaN NaN NaN NaN\\n3309 NaN NaN NaN NaN]\\ntimestamp: 2025-03-06T19:39:48.298262\\ncomments: []\\nexception: \\n\\nuid: output_12\\nstatus: fail\\ntype: survival plot\\nproperties: {\\'method\\': \\'surv_func\\'}\\nsdc: {\\'summary\\': {\\'suppressed\\': True, \\'negative\\': 0, \\'missing\\': 0, \\'threshold\\': 76, \\'p-ratio\\': 0, \\'nk-rule\\': 0, \\'all-values-are-same\\': 0}, \\'cells\\': {\\'negative\\': [], \\'missing\\': [], \\'threshold\\': [[1, 0], [1, 1], [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3], [4, 0], [4, 1], [4, 2], [4, 3], [5, 0], [5, 1], [5, 2], [5, 3], [6, 0], [6, 1], [6, 2], [6, 3], [7, 0], [7, 1], [7, 2], [7, 3], [8, 0], [8, 1], [8, 2], [8, 3], [9, 0], [9, 1], [9, 2], [9, 3], [10, 0], [10, 1], [10, 2], [10, 3], [11, 0], [11, 1], [11, 2], [11, 3], [12, 0], [12, 1], [12, 2], [12, 3], [13, 0], [13, 1], [13, 2], [13, 3], [14, 0], [14, 1], [14, 2], [14, 3], [15, 0], [15, 1], [15, 2], [15, 3], [16, 0], [16, 1], [16, 2], [16, 3], [17, 0], [17, 1], [17, 2], [17, 3], [18, 0], [18, 1], [18, 2], [18, 3], [19, 0], [19, 1], [19, 2], [19, 3]], \\'p-ratio\\': [], \\'nk-rule\\': [], \\'all-values-are-same\\': []}}\\ncommand: safe_plot = acro.surv_func(\\nsummary: fail; threshold: 76 cells suppressed; \\noutcome: Empty DataFrame\\nColumns: []\\nIndex: []\\noutput: [\\'acro_artifacts/kaplan-mier_0.png\\']\\ntimestamp: 2025-03-06T19:39:48.450221\\ncomments: []\\nexception: \\n\\n'" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "acro.print_outputs()" ] }, { "cell_type": "markdown", "id": "3136bc78", "metadata": {}, "source": [ "### 2: Remove some ACRO outputs before finalising \n", "This is an example of deleting some of the ACRO outputs. \n", "The name of the output that needs to be removed should be passed to the function remove_output. \n", "- Currently, all outputs names contain timestamp; that is the time when the output was created. \n", "- The output name can be taken from the outputs listed by the print_outputs function, \n", "- or by listing the results and choosing the specific output that needs to be removed" ] }, { "cell_type": "code", "execution_count": 26, "id": "e4ee985e", "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:records:remove(): output_0 removed\n" ] } ], "source": [ "acro.remove_output(\"output_0\")" ] }, { "cell_type": "markdown", "id": "df2a02e0", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### 3: Rename ACRO outputs before finalising\n", "This is an example of renaming the outputs to provide a more descriptive name. \n", "The timestamp associated with the output name will not get overwritten" ] }, { "cell_type": "code", "execution_count": 27, "id": "b9d0b9ac", "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:records:rename_output(): output_2 renamed to pivot_table\n" ] } ], "source": [ "acro.rename_output(\"output_2\", \"pivot_table\")" ] }, { "cell_type": "markdown", "id": "56d2b6a1", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### 4: Add a comment to output\n", "This is an example to add a comment to outputs. \n", "It can be used to provide a description or to pass additional information to the output checkers." ] }, { "cell_type": "code", "execution_count": 28, "id": "8e21f7b0", "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:records:a comment was added to output_1\n", "INFO:acro:records:a comment was added to output_1\n" ] } ], "source": [ "acro.add_comments(\"output_1\", \"Please let me have this data.\")\n", "acro.add_comments(\"output_1\", \"6 cells were suppressed in this table\")" ] }, { "cell_type": "markdown", "id": "8496fed4", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### 5: Add an unsupported output to the list of outputs\n", "This is an example to add an unsupported outputs (such as images) to the list of outputs" ] }, { "cell_type": "code", "execution_count": 29, "id": "1e8000a1", "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:records:add_custom(): output_13\n" ] } ], "source": [ "acro.custom_output(\n", " \"XandY.jpeg\", \"This output is an image showing the relationship between X and Y\"\n", ")" ] }, { "cell_type": "markdown", "id": "5a586694", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 6: (the big one) Finalise ACRO\n", "This is an example of the function _finalise()_ which the users must call at the end of each session. \n", "- It takes each output and saves it to a CSV file. \n", "- It also saves the SDC analysis for each output to a json file or Excel file \n", " (depending on the extension of the name of the file provided as an input to the function)" ] }, { "cell_type": "code", "execution_count": 30, "id": "f941aca2", "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:records:\n", "uid: output_1\n", "status: fail\n", "type: table\n", "properties: {'method': 'crosstab'}\n", "sdc: {'summary': {'suppressed': True, 'negative': 0, 'missing': 0, 'threshold': 5, 'p-ratio': 0, 'nk-rule': 0, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [[2, 0], [2, 1], [2, 2], [2, 3], [4, 0]], 'p-ratio': [], 'nk-rule': [], 'all-values-are-same': []}}\n", "command: safe_table = acro.crosstab(df.recommend, df.parents, margins=True)\n", "summary: fail; threshold: 5 cells suppressed; \n", "outcome: parents great_pret pretentious usual All\n", "recommend \n", "not_recom ok ok ok ok\n", "priority ok ok ok ok\n", "recommend threshold; threshold; threshold; threshold; \n", "spec_prior ok ok ok ok\n", "very_recom threshold; ok ok ok\n", "All ok ok ok ok\n", "output: [parents great_pret pretentious usual All\n", "recommend \n", "not_recom 1440.0 1440 1440 4320\n", "priority 858.0 1484 1924 4266\n", "spec_prior 2022.0 1264 758 4044\n", "very_recom NaN 132 196 328\n", "All 4320.0 4320 4318 12958]\n", "timestamp: 2025-03-06T19:39:46.961631\n", "comments: ['Please let me have this data.', '6 cells were suppressed in this table']\n", "exception: \n", "\n", "The status of the record above is: fail.\n", "Please explain why an exception should be granted.\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ " suppressed\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:records:\n", "uid: output_3\n", "status: fail\n", "type: table\n", "properties: {'method': 'crosstab'}\n", "sdc: {'summary': {'suppressed': True, 'negative': 0, 'missing': 0, 'threshold': 1, 'p-ratio': 4, 'nk-rule': 4, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [[2, 2]], 'p-ratio': [[2, 0], [2, 1], [2, 2], [4, 0]], 'nk-rule': [[2, 0], [2, 1], [2, 2], [4, 0]], 'all-values-are-same': []}}\n", "command: safe_table = acro.crosstab(\n", "summary: fail; threshold: 1 cells suppressed; p-ratio: 4 cells suppressed; nk-rule: 4 cells suppressed; \n", "outcome: parents great_pret pretentious \\\n", "recommend \n", "not_recom ok ok \n", "priority ok ok \n", "recommend p-ratio; nk-rule; p-ratio; nk-rule; \n", "spec_prior ok ok \n", "very_recom p-ratio; nk-rule; ok \n", "\n", "parents usual \n", "recommend \n", "not_recom ok \n", "priority ok \n", "recommend threshold; p-ratio; nk-rule; \n", "spec_prior ok \n", "very_recom ok \n", "output: [parents great_pret pretentious usual\n", "recommend \n", "not_recom 1440.0 1440.0 1440.0\n", "priority 858.0 1484.0 1924.0\n", "recommend NaN NaN NaN\n", "spec_prior 2022.0 1264.0 758.0\n", "very_recom NaN 132.0 196.0]\n", "timestamp: 2025-03-06T19:39:47.019919\n", "comments: []\n", "exception: \n", "\n", "The status of the record above is: fail.\n", "Please explain why an exception should be granted.\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ " exception requested\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:records:\n", "uid: output_4\n", "status: fail\n", "type: table\n", "properties: {'method': 'crosstab'}\n", "sdc: {'summary': {'suppressed': True, 'negative': 0, 'missing': 0, 'threshold': 2, 'p-ratio': 8, 'nk-rule': 8, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [[2, 2], [2, 5]], 'p-ratio': [[2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [4, 0], [4, 3]], 'nk-rule': [[2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [4, 0], [4, 3]], 'all-values-are-same': []}}\n", "command: safe_table = acro.crosstab(\n", "summary: fail; threshold: 2 cells suppressed; p-ratio: 8 cells suppressed; nk-rule: 8 cells suppressed; \n", "outcome: mode_aggfunc \\\n", "parents great_pret pretentious \n", "recommend \n", "not_recom ok ok \n", "priority ok ok \n", "recommend p-ratio; nk-rule; p-ratio; nk-rule; \n", "spec_prior ok ok \n", "very_recom p-ratio; nk-rule; ok \n", "\n", " mean \\\n", "parents usual great_pret \n", "recommend \n", "not_recom ok ok \n", "priority ok ok \n", "recommend threshold; p-ratio; nk-rule; p-ratio; nk-rule; \n", "spec_prior ok ok \n", "very_recom ok p-ratio; nk-rule; \n", "\n", " \n", "parents pretentious usual \n", "recommend \n", "not_recom ok ok \n", "priority ok ok \n", "recommend p-ratio; nk-rule; threshold; p-ratio; nk-rule; \n", "spec_prior ok ok \n", "very_recom ok ok \n", "output: [ mode_aggfunc mean \n", "parents great_pret pretentious usual great_pret pretentious usual\n", "recommend \n", "not_recom 2.0 1.0 1.0 3.125694 3.105556 3.074306\n", "priority 1.0 1.0 1.0 2.665501 3.030323 3.116944\n", "recommend NaN NaN NaN NaN NaN NaN\n", "spec_prior 3.0 3.0 3.0 3.353610 3.370253 3.393140\n", "very_recom NaN 1.0 1.0 NaN 2.204545 2.244898]\n", "timestamp: 2025-03-06T19:39:47.068066\n", "comments: []\n", "exception: \n", "\n", "The status of the record above is: fail.\n", "Please explain why an exception should be granted.\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ " exception requested\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:records:\n", "uid: output_6\n", "status: fail\n", "type: table\n", "properties: {'method': 'pivot_table'}\n", "sdc: {'summary': {'suppressed': True, 'negative': 0, 'missing': 0, 'threshold': 5, 'p-ratio': 5, 'nk-rule': 5, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [[0, 2], [0, 4], [1, 2], [2, 2], [3, 2]], 'p-ratio': [[0, 2], [0, 4], [1, 2], [2, 2], [3, 2]], 'nk-rule': [[0, 2], [0, 4], [1, 2], [2, 2], [3, 2]], 'all-values-are-same': []}}\n", "command: safe_table = acro.pivot_table(\n", "summary: fail; threshold: 5 cells suppressed; p-ratio: 5 cells suppressed; nk-rule: 5 cells suppressed; \n", "outcome: children \\\n", "recommend not_recom priority recommend spec_prior \n", "parents \n", "great_pret ok ok threshold; p-ratio; nk-rule; ok \n", "pretentious ok ok threshold; p-ratio; nk-rule; ok \n", "usual ok ok threshold; p-ratio; nk-rule; ok \n", "All ok ok threshold; p-ratio; nk-rule; ok \n", "\n", " \n", "recommend very_recom All \n", "parents \n", "great_pret threshold; p-ratio; nk-rule; ok \n", "pretentious ok ok \n", "usual ok ok \n", "All ok ok \n", "output: [ children \n", "recommend not_recom priority spec_prior very_recom All\n", "parents \n", "great_pret 3.125694 2.665501 3.353610 NaN 3.140972\n", "pretentious 3.105556 3.030323 3.370253 2.204545 3.129630\n", "usual 3.074306 3.116944 3.393140 2.244898 3.111626\n", "All 3.101852 2.996015 3.366222 2.228659 3.127412]\n", "timestamp: 2025-03-06T19:39:47.231513\n", "comments: []\n", "exception: \n", "\n", "The status of the record above is: fail.\n", "Please explain why an exception should be granted.\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ " some reason\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:records:\n", "uid: output_11\n", "status: fail\n", "type: table\n", "properties: {'method': 'surv_func'}\n", "sdc: {'summary': {'suppressed': True, 'negative': 0, 'missing': 0, 'threshold': 76, 'p-ratio': 0, 'nk-rule': 0, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [[1, 0], [1, 1], [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3], [4, 0], [4, 1], [4, 2], [4, 3], [5, 0], [5, 1], [5, 2], [5, 3], [6, 0], [6, 1], [6, 2], [6, 3], [7, 0], [7, 1], [7, 2], [7, 3], [8, 0], [8, 1], [8, 2], [8, 3], [9, 0], [9, 1], [9, 2], [9, 3], [10, 0], [10, 1], [10, 2], [10, 3], [11, 0], [11, 1], [11, 2], [11, 3], [12, 0], [12, 1], [12, 2], [12, 3], [13, 0], [13, 1], [13, 2], [13, 3], [14, 0], [14, 1], [14, 2], [14, 3], [15, 0], [15, 1], [15, 2], [15, 3], [16, 0], [16, 1], [16, 2], [16, 3], [17, 0], [17, 1], [17, 2], [17, 3], [18, 0], [18, 1], [18, 2], [18, 3], [19, 0], [19, 1], [19, 2], [19, 3]], 'p-ratio': [], 'nk-rule': [], 'all-values-are-same': []}}\n", "command: safe_table = acro.surv_func(data.futime, data.death, output=\"table\")\n", "summary: fail; threshold: 76 cells suppressed; \n", "outcome: Surv_prob Surv_prob_SE num_at_risk num_events\n", "Time \n", "51 ok ok ok ok\n", "69 threshold; threshold; threshold; threshold; \n", "85 threshold; threshold; threshold; threshold; \n", "91 threshold; threshold; threshold; threshold; \n", "115 threshold; threshold; threshold; threshold; \n", "372 threshold; threshold; threshold; threshold; \n", "667 threshold; threshold; threshold; threshold; \n", "874 threshold; threshold; threshold; threshold; \n", "1039 threshold; threshold; threshold; threshold; \n", "1046 threshold; threshold; threshold; threshold; \n", "1281 threshold; threshold; threshold; threshold; \n", "1286 threshold; threshold; threshold; threshold; \n", "1326 threshold; threshold; threshold; threshold; \n", "1355 threshold; threshold; threshold; threshold; \n", "1626 threshold; threshold; threshold; threshold; \n", "1903 threshold; threshold; threshold; threshold; \n", "1914 threshold; threshold; threshold; threshold; \n", "2776 threshold; threshold; threshold; threshold; \n", "2851 threshold; threshold; threshold; threshold; \n", "3309 threshold; threshold; threshold; threshold; \n", "output: [ Surv prob Surv prob SE num at risk num events\n", "Time \n", "51 0.95 0.048734 20.0 1.0\n", "69 NaN NaN NaN NaN\n", "85 NaN NaN NaN NaN\n", "91 NaN NaN NaN NaN\n", "115 NaN NaN NaN NaN\n", "372 NaN NaN NaN NaN\n", "667 NaN NaN NaN NaN\n", "874 NaN NaN NaN NaN\n", "1039 NaN NaN NaN NaN\n", "1046 NaN NaN NaN NaN\n", "1281 NaN NaN NaN NaN\n", "1286 NaN NaN NaN NaN\n", "1326 NaN NaN NaN NaN\n", "1355 NaN NaN NaN NaN\n", "1626 NaN NaN NaN NaN\n", "1903 NaN NaN NaN NaN\n", "1914 NaN NaN NaN NaN\n", "2776 NaN NaN NaN NaN\n", "2851 NaN NaN NaN NaN\n", "3309 NaN NaN NaN NaN]\n", "timestamp: 2025-03-06T19:39:48.298262\n", "comments: []\n", "exception: \n", "\n", "The status of the record above is: fail.\n", "Please explain why an exception should be granted.\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ " some other reason\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:records:\n", "uid: output_12\n", "status: fail\n", "type: survival plot\n", "properties: {'method': 'surv_func'}\n", "sdc: {'summary': {'suppressed': True, 'negative': 0, 'missing': 0, 'threshold': 76, 'p-ratio': 0, 'nk-rule': 0, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [[1, 0], [1, 1], [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3], [4, 0], [4, 1], [4, 2], [4, 3], [5, 0], [5, 1], [5, 2], [5, 3], [6, 0], [6, 1], [6, 2], [6, 3], [7, 0], [7, 1], [7, 2], [7, 3], [8, 0], [8, 1], [8, 2], [8, 3], [9, 0], [9, 1], [9, 2], [9, 3], [10, 0], [10, 1], [10, 2], [10, 3], [11, 0], [11, 1], [11, 2], [11, 3], [12, 0], [12, 1], [12, 2], [12, 3], [13, 0], [13, 1], [13, 2], [13, 3], [14, 0], [14, 1], [14, 2], [14, 3], [15, 0], [15, 1], [15, 2], [15, 3], [16, 0], [16, 1], [16, 2], [16, 3], [17, 0], [17, 1], [17, 2], [17, 3], [18, 0], [18, 1], [18, 2], [18, 3], [19, 0], [19, 1], [19, 2], [19, 3]], 'p-ratio': [], 'nk-rule': [], 'all-values-are-same': []}}\n", "command: safe_plot = acro.surv_func(\n", "summary: fail; threshold: 76 cells suppressed; \n", "outcome: Empty DataFrame\n", "Columns: []\n", "Index: []\n", "output: ['acro_artifacts/kaplan-mier_0.png']\n", "timestamp: 2025-03-06T19:39:48.450221\n", "comments: []\n", "exception: \n", "\n", "The status of the record above is: fail.\n", "Please explain why an exception should be granted.\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ " suppressed\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:records:\n", "uid: pivot_table\n", "status: fail\n", "type: table\n", "properties: {'method': 'crosstab'}\n", "sdc: {'summary': {'suppressed': False, 'negative': 0, 'missing': 0, 'threshold': 4, 'p-ratio': 0, 'nk-rule': 0, 'all-values-are-same': 0}, 'cells': {'negative': [], 'missing': [], 'threshold': [[2, 0], [2, 1], [2, 2], [4, 0]], 'p-ratio': [], 'nk-rule': [], 'all-values-are-same': []}}\n", "command: safe_table = acro.crosstab(df.recommend, df.parents)\n", "summary: fail; threshold: 4 cells may need suppressing; \n", "outcome: parents great_pret pretentious usual\n", "recommend \n", "not_recom ok ok ok\n", "priority ok ok ok\n", "recommend threshold; threshold; threshold; \n", "spec_prior ok ok ok\n", "very_recom threshold; ok ok\n", "output: [parents great_pret pretentious usual\n", "recommend \n", "not_recom 1440 1440 1440\n", "priority 858 1484 1924\n", "recommend 0 0 2\n", "spec_prior 2022 1264 758\n", "very_recom 0 132 196]\n", "timestamp: 2025-03-06T19:39:46.980090\n", "comments: []\n", "exception: \n", "\n", "The status of the record above is: fail.\n", "Please explain why an exception should be granted.\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ " a reason is provided\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:records:\n", "uid: output_13\n", "status: review\n", "type: custom\n", "properties: {}\n", "sdc: {}\n", "command: custom\n", "summary: review\n", "outcome: Empty DataFrame\n", "Columns: []\n", "Index: []\n", "output: ['XandY.jpeg']\n", "timestamp: 2025-03-06T19:39:48.518030\n", "comments: ['This output is an image showing the relationship between X and Y']\n", "exception: \n", "\n", "The status of the record above is: review.\n", "Please explain why an exception should be granted.\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ " image is not disclosive\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:records:outputs written to: NURSERY\n" ] } ], "source": [ "output = acro.finalise(\"NURSERY\", \"json\")" ] }, { "cell_type": "markdown", "id": "113d84ec", "metadata": {}, "source": [ "### 7: Add a directory of outputs to an acro object \n", "This is an example of adding a list of files (produced by the researcher without using ACRO) to an acro object and creates a results file for checking." ] }, { "cell_type": "code", "execution_count": 31, "id": "fdea993a", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:version: 0.4.8\n", "INFO:acro:config: {'safe_threshold': 10, 'safe_dof_threshold': 10, 'safe_nk_n': 2, 'safe_nk_k': 0.9, 'safe_pratio_p': 0.1, 'check_missing_values': False, 'survival_safe_threshold': 10, 'zeros_are_disclosive': True}\n", "INFO:acro:automatic suppression: False\n", "INFO:acro:records:add_custom(): output_0\n", "INFO:acro:records:rename_output(): output_0 renamed to crosstab.pkl\n", "INFO:acro:records:\n", "uid: crosstab.pkl\n", "status: review\n", "type: custom\n", "properties: {}\n", "sdc: {}\n", "command: custom\n", "summary: review\n", "outcome: Empty DataFrame\n", "Columns: []\n", "Index: []\n", "output: ['test_add_to_acro/crosstab.pkl']\n", "timestamp: 2025-03-06T19:41:22.128464\n", "comments: ['']\n", "exception: \n", "\n", "The status of the record above is: review.\n", "Please explain why an exception should be granted.\n", "\n" ] }, { "name": "stdin", "output_type": "stream", "text": [ " pickle file need some explanation \n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "INFO:acro:records:outputs written to: SDC_results\n" ] } ], "source": [ "import shutil\n", "\n", "table = pd.crosstab(df.recommend, df.parents)\n", "# save the output table to a file and add this file to a directory\n", "src_path = \"test_add_to_acro\"\n", "file_path = \"crosstab.pkl\"\n", "dest_path = \"SDC_results\"\n", "if not os.path.exists(src_path):\n", " table.to_pickle(file_path)\n", " os.mkdir(src_path)\n", " shutil.move(file_path, src_path, copy_function=shutil.copytree)\n", "\n", "# add the output to acro\n", "add_to_acro(src_path, dest_path)" ] } ], "metadata": { "celltoolbar": "Slideshow", "kernelspec": { "display_name": "testacro", "language": "python", "name": "testacro" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.0" } }, "nbformat": 4, "nbformat_minor": 5 }