-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* changes in the third question of the decision-making workflow * changed the third question of the workflow * Changes in the third question of the workflow * Update third and fourth question * Update of the third question * Update in the third question * Update in test * Update Letters * Grammar * Spacing * Commas and visualization * Spacing * Description of function * Order of function
- Loading branch information
1 parent
20fffce
commit d84aa71
Showing
9 changed files
with
388 additions
and
302 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,38 +49,26 @@ | |
#' second question of the decision-making workflow and can respond | ||
#' interactively by selecting the numerical value corresponding to their | ||
#' desired answer. Possible options are \code{NULL} (default), \code{1} (to | ||
#' indicate 'Correct Classification'), \code{2} (to indicate 'Incorrect | ||
#' Classification'), or \code{3} (to indicate 'Correct and Incorrect | ||
#' Classification'). | ||
#' indicate 'Correct classification'), \code{2} (to indicate 'Incorrect | ||
#' classification'), or \code{3} (to indicate 'Correct and incorrect | ||
#' classification'). | ||
#' @param q3 a character indicating the answer to the third question of the | ||
#' decision-making workflow ('Can the negative class be considered as | ||
#' everything not positive or is it well defined?'). If \code{NULL} (the | ||
#' default) the user is presented with the third question of the | ||
#' decision-making workflow and can respond interactively by selecting the | ||
#' numerical value corresponding to their desired answer. Possible options | ||
#' are \code{NULL} (default), \code{1} (to indicate 'Everything not | ||
#' positive'), or \code{2} (to indicate 'Well-defined'). To understand the | ||
#' concept of a negative class defined as Everything Not Positive, consider | ||
#' the example of evaluating customer satisfaction for a service, where | ||
#' customers can either be satisfied or dissatisfied. Dissatisfaction, | ||
#' however, can stem from various reasons (such as 'not satisfied due to | ||
#' shipping delays', 'not satisfied because the product or its features are | ||
#' malfunctioning', or 'not satisfied due to unhelpful customer service'). | ||
#' Despite the different reasons, they all fall under the category of 'not | ||
#' satisfied' and can be grouped together without further distinction. On the | ||
#' other hand, to understand the concept of a negative class as Well Defined, | ||
#' consider the example of classifying bank transactions as either fraudulent | ||
#' or legitimate. In this case, the negative class simply refers to all | ||
#' fraudulent transactions, without needing to analyze why a transaction is | ||
#' considered non-legitimate (i.e. fraudulent). | ||
#' decision-making workflow ('What is more important: a correct classification | ||
#' of the positive class, a correct classification of the negative class, or both?'). | ||
#' If \code{NULL} (the default) the user is presented with the third | ||
#' question of the decision-making workflow and can respond interactively by | ||
#' selecting the numerical value corresponding to their desired answer. | ||
#' Possible options are \code{NULL} (default), \code{1} (to indicate | ||
#' 'Correct classificvation of the positive class'), \code{2} (to indicate | ||
#' 'Correct classificvation of the negative class') or \code{3} (to indicate | ||
#' 'Both a correct classification of the positive and of the negative class'). | ||
#' @param q4 a character indicating the answer to the fourth question of the | ||
#' decision-making workflow ('What are the errors with the highest cost?'). | ||
#' If \code{NULL} (the default) the user is presented with the fourth | ||
#' question of the decision-making workflow and can respond interactively by | ||
#' selecting the numerical value corresponding to their desired answer. | ||
#' Possible options are \code{NULL} (default), \code{1} (to indicate 'False | ||
#' Positive'), \code{2} (to indicate 'False Negative'), or \code{3} (to | ||
#' indicate 'No preference'). | ||
#' Positive') or \code{2} (to indicate 'False Negative'). | ||
#' | ||
#' @details Several fairness measures can be used to assess the fairness of | ||
#' AI-predicted classifications. These include: | ||
|
@@ -119,7 +107,7 @@ | |
#' | ||
#' @return An object of class \code{jfaFairnessSelection} containing: | ||
#' | ||
#' \item{measure}{The abbreviation of the selected fairness measure.} | ||
#' \item{measure}{The abbreviation for the selected fairness measure's name.} | ||
#' \item{name}{The name of the selected fairness measure.} | ||
#' | ||
#' @author Federica Picogna, \email{[email protected]} | ||
|
@@ -148,8 +136,8 @@ | |
#' @keywords algorithm audit bias fairness workflow | ||
#' | ||
#' @examples | ||
#' # Workflow leading to accuracy parity | ||
#' fairness_selection(q1 = 1, q2 = 1, q3 = 2, q4 = 3) | ||
#' # Workflow leading to predictive rate parity | ||
#' fairness_selection(q1 = 1, q2 = 1, q3 = 1, q4 = 1) | ||
#' @export | ||
|
||
fairness_selection <- function(q1 = NULL, | ||
|
@@ -167,35 +155,27 @@ fairness_selection <- function(q1 = NULL, | |
q1_name <- "Yes" | ||
if (is.null(q2)) { | ||
stopifnot("Function must be run in an interactive environment" = interactive()) | ||
q2 <- utils::menu(choices = c("Correct Classification", "Incorrect Classification", "Correct and Incorrect Classification"), title = "(q2) In what type of classification are you interested?") | ||
q2 <- utils::menu(choices = c("Correct classification", "Incorrect classification", "Correct and incorrect classification"), title = "(q2) In what type of classification are you interested?") | ||
} else { | ||
stopifnot("Invalid input: The value of `q2` must be 1 (to indicate 'Correct Classification'), 2 (to indicate 'Incorrect Classification') or 3 (to indicate 'Correct and Incorrect Classification')" = q2 %in% c(1, 2, 3)) | ||
stopifnot("Invalid input: The value of `q2` must be 1 (to indicate 'Correct classification'), 2 (to indicate 'Incorrect classification') or 3 (to indicate 'Correct and incorrect classification')" = q2 %in% c(1, 2, 3)) | ||
} | ||
if (q2 == 1) { | ||
q2_name <- "Correct Classification" | ||
q2_name <- "Correct classification" | ||
if (is.null(q3)) { | ||
stopifnot("Function must be run in an interactive environment" = interactive()) | ||
q3 <- utils::menu(choices = c("Everything not positive", "Well-defined"), title = "(q3) Can the negative class be considered as everything not positive or is it well-defined?") | ||
q3 <- utils::menu(choices = c("Correct classification of the positive class", "Correct classification of the negative class", "Both a correct classification of the positive and of the negative class"), title = "(q3) What is more important: a correct classification of the positive class, a correct classification of the negative class, or both?") | ||
} else { | ||
stopifnot("Invalid input: The value of `q3` must be 1 (to indicate 'Everything not positive') or 2 (to indicate 'Well-defined')" = q3 %in% c(1, 2)) | ||
stopifnot("Invalid input: The value of `q3` must be 1 (to indicate 'Correct classification of the positive class'), 2 (to indicate 'Correct classification of the negative class') or 3 (to indicate 'Both a correct classification of the positive and of the negative class)" = q3 %in% c(1, 2, 3)) | ||
} | ||
if (is.null(q4)) { | ||
if (q3 == 1) { | ||
if (q3 == 1) { | ||
q3_name <- "Correct classification of the positive class" | ||
if (is.null(q4)) { | ||
choices <- c("False Positive", "False Negative") | ||
stopifnot("Function must be run in an interactive environment" = interactive()) | ||
q4 <- utils::menu(choices = choices, title = "(q4) What are the errors with the highest cost?") | ||
} else { | ||
choices <- c("False Positive", "False Negative", "No preference") | ||
} | ||
stopifnot("Function must be run in an interactive environment" = interactive()) | ||
q4 <- utils::menu(choices = choices, title = "(q4) What are the errors with the highest cost?") | ||
} else { | ||
if (q3 == 1) { | ||
stopifnot("Invalid input: The value of `q4` must be 1 (to indicate 'False Positive') or 2 (to indicate 'False Negative')" = q4 %in% c(1, 2)) | ||
} else { | ||
stopifnot("Invalid input: The value of `q4` must be 1 (to indicate 'False Positive'), 2 (to indicate 'False Negative'), or 3 (to indicate 'No preference')" = q4 %in% c(1, 2, 3)) | ||
} | ||
} | ||
if (q3 == 1) { | ||
q3_name <- "Everything Not Positive" | ||
if (q4 == 1) { | ||
name <- "Predictive Rate Parity" | ||
measure <- "prp" | ||
|
@@ -206,23 +186,30 @@ fairness_selection <- function(q1 = NULL, | |
q4_name <- "False Negative" | ||
} | ||
} else if (q3 == 2) { | ||
q3_name <- "Well-Defined" | ||
q3_name <- "Correct classification of the negative class" | ||
if (is.null(q4)) { | ||
choices <- c("False Positive", "False Negative") | ||
stopifnot("Function must be run in an interactive environment" = interactive()) | ||
q4 <- utils::menu(choices = choices, title = "(q4) What are the errors with the highest cost?") | ||
} else { | ||
stopifnot("Invalid input: The value of `q4` must be 1 (to indicate 'False Positive') or 2 (to indicate 'False Negative')" = q4 %in% c(1, 2)) | ||
} | ||
if (q4 == 1) { | ||
name <- "Specificity Parity" | ||
measure <- "sp" | ||
q4_name <- "False Positive" | ||
} else if (q4 == 2) { | ||
} else { | ||
name <- "Negative Predictive Rate Parity" | ||
measure <- "npvp" | ||
q4_name <- "False Negative" | ||
} else { | ||
name <- "Accuracy Parity" | ||
measure <- "ap" | ||
q4_name <- "No Preference" | ||
} | ||
} else if (q3 == 3) { | ||
q3_name <- "Correct classification of the positive class and of the negative class" | ||
name <- "Accuracy Parity" | ||
measure <- "ap" | ||
} | ||
} else if (q2 == 2) { | ||
q2_name <- "Incorrect Classification" | ||
q2_name <- "Incorrect classification" | ||
if (is.null(q4)) { | ||
stopifnot("Function must be run in an interactive environment" = interactive()) | ||
q4 <- utils::menu(choices = c("False Positive", "False Negative"), title = "(q4) What are the errors with the highest cost?") | ||
|
@@ -241,7 +228,7 @@ fairness_selection <- function(q1 = NULL, | |
} else if (q2 == 3) { | ||
name <- "Equalized Odds" | ||
measure <- "dp" | ||
q2_name <- "Correct and Incorrect Classification" | ||
q2_name <- "Correct and incorrect classification" | ||
} | ||
} else if (q1 == 2) { | ||
name <- "Disparate Impact" | ||
|
Oops, something went wrong.