diff --git a/bn_other_user_model/user_model.bif b/bn_other_user_model/user_model.bif new file mode 100644 index 0000000000000000000000000000000000000000..79daa7f3893c814a65ca7b186ade276a025ba4c1 --- /dev/null +++ b/bn_other_user_model/user_model.bif @@ -0,0 +1,103 @@ +network persona_model_4 { +} + +%VARIABLES DEFINITION +variable reactivity { + type discrete [3] {slow, medium, fast}; +} +variable memory { + type discrete[3] {low, medium, high}; +} +variable attention { + type discrete[3] {low, medium, high}; +} +variable robot_assistance { + type discrete [ 5 ] { lev_0, lev_1, lev_2, lev_3, lev_4 }; +} +variable attempt { + type discrete [ 4 ] { att_1, att_2, att_3, att_4 }; +} +variable game_state { + type discrete [ 3 ] { beg, mid, end }; +} +variable robot_feedback { + type discrete [ 2 ] { yes, no }; +} +variable user_action { + type discrete [ 3 ] { correct, wrong, timeout }; +} + +%INDIVIDUAL PROBABILITIES DEFINITION +probability ( robot_assistance ) { + table 0.2, 0.2, 0.2, 0.2, 0.2; +} +probability ( game_state ) { + table 0.34, 0.33, 0.33; +} +probability ( attempt ) { + table 0.25, 0.25, 0.25, 0.25; +} +probability ( user_action ) { + table 0.33, 0.33, 0.34; +} +#CPDS 4 #SPECIFICALLY FOR THE GIVEN PATIENT +probability ( reactivity ) { + table 0.34, 0.33, 0.33; +} +#CPDS 3 #SPECIFICALLY FOR THE GIVEN PATIENT +probability ( memory ) { + table 0.33, 0.33, 0.34; +} +#CPDS 1 #SPECIFICALLY FOR THE GIVEN PATIENT +probability ( attention ) { + table 0.33, 0.33, 0.34; +} +probability ( robot_feedback ) { + table 0.5, 0.5; +} +probability ( reactivity | attention ) { + (low) 0.5, 0.4, 0.1; + (medium) 0.3, 0.5, 0.2; + (high) 0.1, 0.2, 0.7; +} +#CPDS 7 +probability (user_action | memory, reactivity) { +(low, slow) 0.2, 0.5, 0.3; +(low, medium) 0.3, 0.5, 0.2; +(low, fast) 0.4, 0.5, 0.1; +(medium, slow) 0.5, 0.3, 0.2; +(medium, medium) 0.55, 0.35, 0.1; +(medium, fast) 0.6, 0.4, 0.0; +(high, slow) 0.5, 0.4, 0.1; +(high, medium) 0.6, 0.3, 0.1; +(high, fast) 0.8, 0.2, 0.0; +} +#CPDS 5 +probability (robot_feedback | user_action) { + (correct) 0.5, 0.5; + (wrong) 0.5, 0.5; + (timeout) 0.5, 0.5; +} +#CPDS 6 +probability (robot_assistance | user_action) { + (correct) 0.05 0.1 0.15 0.3 0.4; + (wrong) 0.4 0.2 0.2 0.1 0.1; + (timeout) 0.4 0.2 0.2 0.1 0.1; +} +#CPDS 2 +probability (game_state | user_action) { + (correct) 0.2, 0.4, 0.4; + (wrong) 0.4, 0.4, 0.2; + (timeout) 0.6, 0.3, 0.1; +} +#CPDS 0 +probability (attempt | user_action) { + (correct) 0.1, 0.2, 0.3, 0.4; + (wrong) 0.7, 0.2, 0.1, 0.0; + (timeout) 0.6, 0.3, 0.1, 0.0; +} +#CPDS 5 +probability (robot_assistance | robot_feedback) { + (yes) 0.5 0.3 0.1 0.1 0.0; + (no) 0.0 0.1 0.1 0.3 0.5; +} \ No newline at end of file diff --git a/bn_persona_model/__pycache__/utilities.cpython-36.pyc b/bn_persona_model/__pycache__/utilities.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ae85612e5c19ba5c07e4ca739b2c68190e8318e Binary files /dev/null and b/bn_persona_model/__pycache__/utilities.cpython-36.pyc differ diff --git a/bn_persona_model/epoch_40_persona_memory_0_persona_attention_0_persona_reactivity_1.jpg b/bn_persona_model/epoch_40_persona_memory_0_persona_attention_0_persona_reactivity_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4c9fdf873c80b27013014591b19e2021082e9630 Binary files /dev/null and b/bn_persona_model/epoch_40_persona_memory_0_persona_attention_0_persona_reactivity_1.jpg differ diff --git a/bn_persona_model/epoch_40_real_user_memory_2_real_user_attention_2_real_user_reactivity_2.jpg b/bn_persona_model/epoch_40_real_user_memory_2_real_user_attention_2_real_user_reactivity_2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cca81e83638a9a36f47e44498794f59114f21370 Binary files /dev/null and b/bn_persona_model/epoch_40_real_user_memory_2_real_user_attention_2_real_user_reactivity_2.jpg differ diff --git a/bn_persona_model/persona_model.bif b/bn_persona_model/persona_model.bif new file mode 100644 index 0000000000000000000000000000000000000000..ef8062593b35916b8470d1079aefc607ab6c6d08 --- /dev/null +++ b/bn_persona_model/persona_model.bif @@ -0,0 +1,103 @@ +network persona_model { +} + +%VARIABLES DEFINITION +variable reactivity { + type discrete [3] {slow, medium, fast}; +} +variable memory { + type discrete[3] {low, medium, high}; +} +variable attention { + type discrete[3] {low, medium, high}; +} +variable robot_assistance { + type discrete [ 5 ] { lev_0, lev_1, lev_2, lev_3, lev_4 }; +} +variable attempt { + type discrete [ 4 ] { att_1, att_2, att_3, att_4 }; +} +variable game_state { + type discrete [ 3 ] { beg, mid, end }; +} +variable robot_feedback { + type discrete [ 2 ] { yes, no }; +} +variable user_action { + type discrete [ 3 ] { correct, wrong, timeout }; +} + +%INDIVIDUAL PROBABILITIES DEFINITION +probability ( robot_assistance ) { + table 0.2, 0.2, 0.2, 0.2, 0.2; +} +probability ( game_state ) { + table 0.34, 0.33, 0.33; +} +probability ( attempt ) { + table 0.25, 0.25, 0.25, 0.25; +} +probability ( user_action ) { + table 0.33, 0.33, 0.34; +} +#CPDS 4 #SPECIFICALLY FOR THE GIVEN PATIENT +probability ( reactivity ) { + table 0.34, 0.33, 0.33; +} +#CPDS 3 #SPECIFICALLY FOR THE GIVEN PATIENT +probability ( memory ) { + table 0.33, 0.33, 0.34; +} +#CPDS 1 #SPECIFICALLY FOR THE GIVEN PATIENT +probability ( attention ) { + table 0.33, 0.33, 0.34; +} +probability ( robot_feedback ) { + table 0.5, 0.5; +} +probability ( reactivity | attention ) { + (low) 0.7, 0.2, 0.1; + (medium) 0.2, 0.5, 0.3; + (high) 0.1, 0.2, 0.7; +} +#CPDS 7 +probability (user_action | memory, reactivity) { +(low, slow) 0.2, 0.5, 0.3; +(low, medium) 0.3, 0.5, 0.2; +(low, fast) 0.4, 0.5, 0.1; +(medium, slow) 0.5, 0.3, 0.2; +(medium, medium) 0.55, 0.35, 0.1; +(medium, fast) 0.6, 0.4, 0.0; +(high, slow) 0.5, 0.4, 0.1; +(high, medium) 0.6, 0.3, 0.1; +(high, fast) 0.8, 0.2, 0.0; +} +#CPDS 5 +probability (robot_feedback | user_action) { + (correct) 0.8, 0.2; + (wrong) 0.5, 0.5; + (timeout) 0.2, 0.8; +} +#CPDS 6 +probability (robot_assistance | user_action) { + (correct) 0.05 0.1 0.15 0.3 0.4; + (wrong) 0.4 0.3 0.2 0.05 0.05; + (timeout) 0.4 0.4 0.1 0.05 0.05; +} +#CPDS 2 +probability (game_state | user_action) { + (correct) 0.2, 0.4, 0.4; + (wrong) 0.4, 0.4, 0.2; + (timeout) 0.6, 0.3, 0.1; +} +#CPDS 0 +probability (attempt | user_action) { + (correct) 0.1, 0.2, 0.3, 0.4; + (wrong) 0.5, 0.3, 0.15, 0.05; + (timeout) 0.4, 0.3, 0.2, 0.1; +} +#CPDS 5 +probability (robot_assistance | robot_feedback) { + (yes) 0.5 0.3 0.1 0.1 0.0; + (no) 0.0 0.1 0.1 0.3 0.5; +} \ No newline at end of file diff --git a/bn_persona_model/utilities.py b/bn_persona_model/utilities.py new file mode 100644 index 0000000000000000000000000000000000000000..e44dbec0cb9b5afe5f7e6a0b6f10751aa021e71d --- /dev/null +++ b/bn_persona_model/utilities.py @@ -0,0 +1,90 @@ +import random +import bn_functions + + +def get_dynamic_variables(variables_name, variables_value): + if len(variables_name)!=len(variables_value): + assert "The variables name numbers is different from the variables value" + else: + dynamic_variables = {variables_name[i]:variables_value[i] for i in range(len(variables_name))} + return dynamic_variables + + + + +def compute_next_state(user_action, task_evolution, attempt_counter, correct_move_counter, + wrong_move_counter, timeout_counter + ): + ''' + The function computes given the current state and action of the user, the next state + Args: + user_action: 0,1,2 + task_evolution: beg, mid, end + correct_move_counter: + attempt_counter: + wrong_move_counter: + timeout_counter: + Return: + the counters updated according to the user_action + ''' + if user_action == 0: + attempt_counter = 0 + task_evolution += 1 + correct_move_counter += 1 + # if the user made a wrong move and still did not reach the maximum number of attempts + elif user_action == 1 and attempt_counter < 3: + attempt_counter += 1 + wrong_move_counter += 1 + # if the user did not move any token and still did not reach the maximum number of attempts + elif user_action == 2 and attempt_counter < 3: + attempt_counter += 1 + timeout_counter += 1 + # the robot or therapist makes the correct move on the patient's behalf + else: + attempt_counter = 0 + task_evolution += 1 + correct_move_counter += 1 + + return task_evolution, attempt_counter, correct_move_counter, wrong_move_counter, timeout_counter + +def get_user_action_prob(user_bn_model, robot_assistance_action, robot_feedback_action, + attempt_counter, game_state_counter, user_memory, user_attention, user_reactivity): + user_actions_prob = bn_functions.get_inference_from_state(user_bn_model, + variables=['user_action'], + evidence={'robot_assistance': robot_assistance_action, + 'attempt': attempt_counter, + 'game_state': game_state_counter, + 'robot_feedback': robot_feedback_action, + 'memory': user_memory, + 'attention': user_attention, + 'reactivity': user_reactivity}) + return user_actions_prob + + +def get_stochatic_action(actions_prob): + ''' + Select one of the actions according to the actions_prob + Args: + actions_prob: the probability of the Persona based on the BN to make a correct move, wrong move, timeout + Return: + the id of the selected action + N.B: + ''' + action_id = None + correct_action_from_BN = actions_prob[0] + wrong_action_from_BN = actions_prob[1] + timeout_action_from_BN = actions_prob[2] + + rnd_val = random.uniform(0,1) + #if user_prob is lower than the correct action prob then is the correct one + if rnd_val<=correct_action_from_BN: + action_id = 0 + #if rnd is larger than the correct action prob and lower than wrong + # action prob then is the wrong one + elif rnd_val>correct_action_from_BN \ + and rnd_val<(correct_action_from_BN+wrong_action_from_BN): + action_id = 1 + #timeout + else: + action_id = 2 + return action_id diff --git a/bn_robot_model/__pycache__/utilities.cpython-36.pyc b/bn_robot_model/__pycache__/utilities.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..28581fb5fa7c725dab25c9a4c7b5ca743e6f6c3a Binary files /dev/null and b/bn_robot_model/__pycache__/utilities.cpython-36.pyc differ diff --git a/bn_robot_model/robot_model.bif b/bn_robot_model/robot_model.bif new file mode 100644 index 0000000000000000000000000000000000000000..76917a26a15b9a33c7ca0e812cb77c0ef26e53bd --- /dev/null +++ b/bn_robot_model/robot_model.bif @@ -0,0 +1,147 @@ +network robot_model { +} + +%VARIABLES DEFINITION +variable reactivity { + type discrete [3] {slow, medium, fast}; +} +variable memory { + type discrete[3] {low, medium, high}; +} + +variable robot_assistance_feedback { + type discrete [ 10 ] { lev_0_no, lev_1_no, lev_2_no, lev_3_no, lev_4_no, + lev_0_yes, lev_1_yes, lev_2_yes, lev_3_yes, lev_4_yes + }; +} +variable attempt { + type discrete [ 4 ] { att_1, att_2, att_3, att_4 }; +} +variable game_state { + type discrete [ 3 ] { beg, mid, end }; +} + +variable user_capability { + type discrete [ 3 ] { very_mild, mild, severe }; +} + +%INDIVIDUAL PROBABILITIES DEFINITION +probability ( robot_assistance_feedback ) { + table 0.1, 0.1, 0.1, 0.1, 0.1, + 0.1, 0.1, 0.1, 0.1, 0.1; +} +probability ( game_state ) { + table 0.34, 0.33, 0.33; +} +probability ( attempt ) { + table 0.25, 0.25, 0.25, 0.25; +} +probability ( user_capability ) { + table 0.33, 0.33, 0.34; +} +#CPDS 4 #SPECIFICALLY FOR THE GIVEN PATIENT +probability ( reactivity ) { + table 0.34, 0.33, 0.33; +} +#CPDS 3 #SPECIFICALLY FOR THE GIVEN PATIENT +probability ( memory ) { + table 0.33, 0.33, 0.34; +} + + +#Conditional Probabilities + +#CPDS X (very_mild, mild, severe) +probability (user_capability | memory, reactivity) { +(low, slow) 0.1, 0.2, 0.7; +(medium, slow) 0.2, 0.6, 0.2; +(high, slow) 0.7, 0.2, 0.1; + +(low, medium) 0.1, 0.3, 0.6; +(medium, medium) 0.3, 0.6, 0.1; +(high, medium) 0.1, 0.4, 0.5; + +(low, fast) 0.3, 0.2, 0.5; +(medium, fast) 0.7, 0.2, 0.1; +(high, fast) 0.8, 0.1, 0.1; + +} +#CPDS X +probability (robot_assistance_feedback | user_capability, game_state, attempt) { + (very_mild, beg, att_1) 0.25, 0.25, 0.0, 0.0, 0.0, + 0.25, 0.25, 0.0, 0.0, 0.0; + (mild, beg, att_1) 0.0, 0.05, 0.15, 0.15, 0.15, + 0.0, 0.05, 0.15, 0.15, 0.15; + (severe, beg, att_1) 0.0, 0.0, 0.25, 0.15, 0.1, + 0.0, 0.0, 0.25, 0.15, 0.1; + (very_mild, mid, att_1) 0.3, 0.2, 0.0, 0.0, 0.0, + 0.3, 0.2, 0.0, 0.0, 0.0; + (mild, mid, att_1) 0.0, 0.1, 0.2, 0.1, 0.1, + 0.0, 0.1, 0.2, 0.1, 0.1; + (severe, mid, att_1) 0.0, 0.0, 0.3, 0.1, 0.1, + 0.0, 0.0, 0.3, 0.1, 0.1; + (very_mild, end, att_1) 0.45, 0.05, 0.0, 0.0, 0.0, + 0.45, 0.05, 0.0, 0.0, 0.0; + (mild, end, att_1) 0.0, 0.15, 0.2, 0.1, 0.05, + 0.0, 0.15, 0.2, 0.1, 0.05; + (severe, end, att_1) 0.0, 0.1, 0.2, 0.15, 0.05, + 0.0, 0.1, 0.2, 0.15, 0.05; + + (very_mild, beg, att_2) 0.30, 0.20, 0.0, 0.0, 0.0, + 0.30, 0.20, 0.0, 0.0, 0.0; + (mild, beg, att_2) 0.0, 0.15, 0.2, 0.1, 0.05, + 0.0, 0.15, 0.2, 0.1, 0.05; + (severe, beg, att_2) 0.0, 0.05, 0.25, 0.1, 0.1, + 0.0, 0.05, 0.25, 0.1, 0.1; + (very_mild, mid, att_2) 0.4, 0.1, 0.0, 0.0, 0.0, + 0.4, 0.1, 0.0, 0.0, 0.0; + (mild, mid, att_2) 0.0, 0.2, 0.2, 0.1, 0.0, + 0.0, 0.2, 0.2, 0.1, 0.0; + (severe, mid, att_2) 0.0, 0.0, 0.2, 0.2, 0.1, + 0.0, 0.0, 0.2, 0.2, 0.1; + (very_mild, end, att_2) 0.4, 0.1, 0.0, 0.0, 0.0, + 0.45, 0.05, 0.0, 0.0, 0.0; + (mild, end, att_2) 0.0, 0.2, 0.15, 0.15, 0.0, + 0.0, 0.2, 0.15, 0.15, 0.0; + (severe, end, att_2) 0.0, 0.05, 0.2, 0.2, 0.05, + 0.0, 0.05, 0.2, 0.2, 0.05; + + (very_mild, beg, att_3) 0.40, 0.10, 0.0, 0.0, 0.0, + 0.40, 0.10, 0.0, 0.0, 0.0; + (mild, beg, att_3) 0.0, 0.10, 0.25, 0.1, 0.05, + 0.0, 0.10, 0.25, 0.1, 0.05; + (severe, beg, att_3) 0.0, 0.05, 0.2, 0.2, 0.05, + 0.0, 0.05, 0.2, 0.2, 0.05; + (very_mild, mid, att_3) 0.3, 0.1, 0.1, 0.0, 0.0, + 0.3, 0.1, 0.1, 0.0, 0.0; + (mild, mid, att_3) 0.0, 0.2, 0.1, 0.1, 0.1, + 0.0, 0.2, 0.1, 0.1, 0.1; + (severe, mid, att_3) 0.0, 0.1, 0.1, 0.15, 0.15, + 0.0, 0.1, 0.1, 0.15, 0.15; + (very_mild, end, att_3) 0.45, 0.05, 0.0, 0.0, 0.0, + 0.45, 0.05, 0.0, 0.0, 0.0; + (mild, end, att_3) 0.0, 0.15, 0.15, 0.2, 0.0, + 0.0, 0.15, 0.15, 0.2, 0.0; + (severe, end, att_3) 0.0, 0.1, 0.1, 0.2, 0.1, + 0.0, 0.1, 0.1, 0.2, 0.1; + + (very_mild, beg, att_4) 0.40, 0.10, 0.0, 0.0, 0.0, + 0.40, 0.10, 0.0, 0.0, 0.0; + (mild, beg, att_4) 0.0, 0.10, 0.25, 0.1, 0.05, + 0.0, 0.10, 0.25, 0.1, 0.05; + (severe, beg, att_4) 0.0, 0.05, 0.2, 0.2, 0.05, + 0.0, 0.05, 0.2, 0.2, 0.05; + (very_mild, mid, att_4) 0.3, 0.1, 0.1, 0.0, 0.0, + 0.3, 0.1, 0.1, 0.0, 0.0; + (mild, mid, att_4) 0.0, 0.2, 0.1, 0.1, 0.1, + 0.0, 0.2, 0.1, 0.1, 0.1; + (severe, mid, att_4) 0.0, 0.1, 0.1, 0.15, 0.15, + 0.0, 0.1, 0.1, 0.15, 0.15; + (very_mild, end, att_4) 0.45, 0.05, 0.0, 0.0, 0.0, + 0.45, 0.05, 0.0, 0.0, 0.0; + (mild, end, att_4) 0.0, 0.15, 0.15, 0.2, 0.0, + 0.0, 0.15, 0.15, 0.2, 0.0; + (severe, end, att_4) 0.0, 0.1, 0.1, 0.2, 0.1, + 0.0, 0.1, 0.1, 0.2, 0.1; + +} diff --git a/bn_robot_model/utilities.py b/bn_robot_model/utilities.py new file mode 100644 index 0000000000000000000000000000000000000000..56fcb0520c10548941d0c8b3867d639f2d6f152f --- /dev/null +++ b/bn_robot_model/utilities.py @@ -0,0 +1,78 @@ +import random +import bn_functions + + +def get_dynamic_variables(evidence_variables_name, evidence_variables_value): + ''' + This func returns a dict of the form name:value and it defines the "evidences" + that will be used to query the BN + Args: + :evidence_variables_name: the name of the variable + :evidence_variables_value: the value of the given variable + Return: + a dict of the form name:value + ''' + if len(evidence_variables_name)!=len(evidence_variables_value): + assert "The variables name numbers is different from the variables value" + else: + dynamic_variables = {evidence_variables_name[i]:evidence_variables_value[i] for i in range(len(evidence_variables_name))} + return dynamic_variables + +def infer_prob(user_bn_model, variable_to_infer, evidence_vars_name, evidence_vars_value): + ''' + Given the model, the variable to infer, and the evidences returns the distribution prob for that variable + Args: + user_bn_model: + variable_to_infer: + evidence_vars_name: + evidence_vars_value: + Returns: + the probability distribution for varibale_to_infer + ''' + evidence = get_dynamic_variables(evidence_vars_name, evidence_vars_value) + dist_prob = bn_functions.get_inference_from_state(user_bn_model, + variables=variable_to_infer, + evidence=evidence) + return dist_prob + +def get_stochastic_action(actions_distr_prob): + ''' + Select one of the actions according to the actions_prob + Args: + actions_prob: the probability of the Persona based on the BN to make a correct move, wrong move, timeout + Return: + the id of the selected action + N.B: + ''' + def compute_distance(values, target): + ''' + Return the index of the most closest value in values to target + Args: + target: the target value + values: a list of values from 0 to 1 + Return: + return the index of the value closer to target + ''' + min_dist = 1 + index = 0 + for i in range(len(values)): + if abs(target-values[i])<min_dist: + min_dist = abs(target-values[i]) + index = i + return index + + actions_distr_prob_scaled = [0]*len(actions_distr_prob) + accum = 0 + for i in range(len(actions_distr_prob)): + accum += actions_distr_prob[i] + actions_distr_prob_scaled[i] = accum + + rnd_val = random.uniform(0, 1) + action_id = compute_distance(actions_distr_prob_scaled, rnd_val) + + return action_id + + +actions_prob_distr = [0.32, 0.105, 0.035, 0.035, 0.005, 0.36, 0.065, 0.035, 0.035, 0.005] +action_index = get_stochastic_action(actions_prob_distr) +print(action_index) \ No newline at end of file