## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ## ----------------------------------------------------------------------------- library(personnelSelectionUtility) ## ----------------------------------------------------------------------------- Rxx <- matrix(c( 1.00, .31, .03, .37, .31, 1.00, .13, .16, .03, .13, 1.00, .51, .37, .16, .51, 1.00 ), 4, 4, byrow = TRUE) validities <- c(.37, .35, .16, .23) ## ----------------------------------------------------------------------------- comp <- compensatory_selection( predictor_cor = Rxx, validities = validities, weights = rep(1, 4), selection_ratio = .20, n_applicants = 500, cost_per_applicant = 1000, sdy = 60000 ) comp ## ----------------------------------------------------------------------------- R <- rbind(cbind(Rxx, validities), c(validities, 1)) hurdle <- multiple_hurdle_selection_staged( stage_predictors = list(c(1, 3, 4), 2), stage_selection_ratios = c(.25, .80), R = R, n_sim = 5000, seed = 123, n_applicants = 500, cost_per_stage = c(100, 900), sdy = 60000 ) hurdle ## ----------------------------------------------------------------------------- comparison <- compare_selection_systems_staged( predictor_cor = Rxx, validities = validities, compensatory_weights = rep(1, 4), compensatory_selection_ratio = .20, stage_predictors = list(c(1, 3, 4), 2), stage_selection_ratios = c(.25, .80), n_sim = 5000, seed = 123, n_applicants = 500, compensatory_cost_per_applicant = 1000, hurdle_cost_per_stage = c(100, 900), sdy = 60000 ) comparison ## ----------------------------------------------------------------------------- c( expected_z_difference = comparison$expected_criterion_z_difference, net_utility_difference = comparison$net_utility_difference ) ## ----------------------------------------------------------------------------- sdy_values <- c(20000, 40000, 60000) hurdle_stage2_cost <- c(200, 500, 900) out <- expand.grid(sdy = sdy_values, interview_cost = hurdle_stage2_cost) out$net_utility_difference <- NA_real_ for (i in seq_len(nrow(out))) { cmp <- compare_selection_systems_staged( predictor_cor = Rxx, validities = validities, compensatory_selection_ratio = .20, stage_predictors = list(c(1, 3, 4), 2), stage_selection_ratios = c(.25, .80), n_sim = 3000, seed = 100 + i, n_applicants = 500, compensatory_cost_per_applicant = 1000, hurdle_cost_per_stage = c(100, out$interview_cost[i]), sdy = out$sdy[i] ) out$net_utility_difference[i] <- cmp$net_utility_difference } out ## ----------------------------------------------------------------------------- # First compute the expected standardised score among offered candidates: z_offered <- selected_mean_z(.20) # Adverse selection (correlated mode): top candidates are more likely to decline, # captured by a negative correlation between standardised quality and acceptance. offer_rejection_adjustment( expected_z_offered = z_offered, mode = "correlated", acceptance_rate = .70, rho_quality_acceptance = -0.20, n_offered = 100 ) ## ----------------------------------------------------------------------------- # adverse_impact_ratio() takes individual-level selection outcomes and group labels; # it computes the selection rate per group and the four-fifths ratio relative to # the group with the highest rate. selected <- c(1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0) group <- c(rep("Reference", 9), rep("Focal", 9)) adverse_impact_ratio(selected, group) ## ----------------------------------------------------------------------------- # pareto_frontier() is a general Pareto-membership indicator: given a matrix of # objectives (rows = alternatives, columns = objectives to maximise), it returns # a logical vector flagging the non-dominated alternatives. The validity-diversity # trade-off in selection systems is one application; below we evaluate six candidate # weighting schemes on composite validity and four-fifths fairness. candidates <- data.frame( scheme = c("CA only", "CA + interview", "Equal weights", "Validity weights", "Pareto-optimal #1", "Pareto-optimal #2"), validity = c(.51, .55, .50, .56, .53, .54), fairness = c(.62, .68, .73, .65, .76, .80) ) candidates$pareto <- pareto_frontier( objectives = candidates[, c("validity", "fairness")], maximize = TRUE ) candidates ## ----------------------------------------------------------------------------- # Two candidate selection systems evaluated on three attributes (task, # contextual, CWB avoidance), with values on a common 0-100 scale: values <- matrix(c( 80, 60, 90, 70, 75, 70 ), nrow = 2, byrow = TRUE, dimnames = list(c("System A", "System B"), c("task", "contextual", "cwb_avoidance"))) multiattribute_utility( values = values, weights = c(.50, .30, .20) ) ## ----------------------------------------------------------------------------- # The mean-variance risk-adjusted score subtracts a penalty proportional to the # variance of utility. Because monetary utilities are often in the millions, the # risk_aversion parameter is typically very small (e.g., 1e-6 to 1e-5). The # example below uses the compensatory net utility computed earlier. risk_adjusted_utility( expected_utility = comparison$compensatory$net_utility, utility_sd = abs(comparison$compensatory$net_utility) * .30, risk_aversion = 1e-6 )