Skip to content

Commit

Permalink
Third Question Update (#204)
Browse files Browse the repository at this point in the history
* 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
federicapicogna authored Dec 2, 2024
1 parent 20fffce commit d84aa71
Show file tree
Hide file tree
Showing 9 changed files with 388 additions and 302 deletions.
95 changes: 41 additions & 54 deletions R/fairness_selection.R
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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]}
Expand Down Expand Up @@ -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,
Expand All @@ -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"
Expand All @@ -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?")
Expand All @@ -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"
Expand Down
Loading

0 comments on commit d84aa71

Please sign in to comment.