A robot that asks people questions: order effects, uncertainty and trust#

All data in this notebook are simulated from illustrative populations; no human-subject data are used.

  1. Do people’s answers depend on the order of the robot’s questions? (QQ test, model comparison)

  2. A human-model ensemble gives the robot a predicted answer and its uncertainty.

  3. ask_or_act turns that into a decision: ask the person, or act.

  4. Trust as a qubit: how successes and failures move a person’s trust, on the Bloch sphere.

# Use the installed package, or the source tree when running from a clone
try:
    import quantum_mind
except ImportError:
    import sys, pathlib; sys.path.insert(0, str(pathlib.Path.cwd().parent / 'src')); import quantum_mind
print('quantum_mind', quantum_mind.__version__)
quantum_mind 3.1.0

1. Question order#

import numpy as np
from quantum_mind.applications.robotics import HRI_DOMAINS, domain_models
from quantum_mind.families.order_effects import qq_test

domain = 'object_clarification'
print('A:', HRI_DOMAINS[domain]['A']); print('B:', HRI_DOMAINS[domain]['B'])
people = domain_models(domain)['QL']                       # simulated quantum-like population
rng = np.random.default_rng(0)
counts = people.sample(None, 300, rng)                     # 300 people per question order
print(counts)
print('QQ test (q, z, p):', qq_test(counts))
A: Is it the red cup?
B: Is it the cup on the left?
{'AB': array([135,   0,  29, 136]), 'BA': array([190,  31,   0,  79])}
QQ test (q, z, p): (-0.006666666666666668, -0.2721823288728273, 0.7854818286090124)

2. Human-model ensemble#

from quantum_mind.applications.robotics import HumanModelEnsemble
from quantum_mind.families.order_effects import QuantumOrderModel4D, BayesOrderModel, AnchoringOrderModel

ens = HumanModelEnsemble([QuantumOrderModel4D, BayesOrderModel, AnchoringOrderModel]).update(counts, rng=rng)
for s in ens.summary():
    print('%-22s weight %.3f  BIC %.1f' % (s['model'], s['weight'], s['bic']))
p, unc = ens.predict('AB')
print('predicted answers (A first: yy, yn, ny, nn):', p.round(3))
print('uncertainty:', {k: round(v, 4) for k, v in unc.items()})
QuantumOrderModel4D    weight 0.960  BIC 1129.0
BayesOrderModel        weight 0.040  BIC 1135.3
AnchoringOrderModel    weight 0.000  BIC 1147.8
predicted answers (A first: yy, yn, ny, nn): [0.492 0.006 0.099 0.403]
uncertainty: {'entropy_bits': 1.4084, 'model_disagreement_bits': 0.0007, 'total_bits': 1.409}

3. Ask or act?#

from quantum_mind.applications.robotics import ask_or_act

p_confirm = p[0] + p[1]
for error_cost in (1.5, 3.0):
    print('error cost %.1f ->' % error_cost, ask_or_act(p_confirm, unc, ask_cost=1.0, error_cost=error_cost))
error cost 1.5 -> {'action': 'act', 'expected_cost_act': 0.7529014098927672, 'reason': 'expected error cost 0.75 <= asking cost 1.00'}
error cost 3.0 -> {'action': 'ask', 'expected_cost_act': 1.5058028197855344, 'reason': 'expected error cost 1.51 > asking cost 1.00'}

4. Trust on the Bloch sphere#

The open-system belief model treats trust as a qubit: |0⟩ (north pole) means “I trust the robot”. Successes rotate the belief towards |0⟩, failures away from it, and dephasing shrinks the vector.

from quantum_mind.applications.robotics import TRUST_EVENTS, TRUST_MODELS
from quantum_mind.families.dynamics import final_yes, question_effect
from quantum_mind.viz import belief_trajectory, animate_bloch

model = TRUST_MODELS['open_system']
traj = belief_trajectory(model, TRUST_EVENTS, steps=10)
print('P(trust) at the end, from the sphere: %.4f; from the model: %.4f'
      % ((1 + traj.vectors[-1, 0, 2]) / 2, final_yes(model, TRUST_EVENTS, (5,))))
print('effect of also asking about trust midway: %.3f' % question_effect(model, TRUST_EVENTS, 5, 2))
animate_bloch(traj, title='Trust belief (simulated person)')
P(trust) at the end, from the sphere: 0.7247; from the model: 0.7247
effect of also asking about trust midway: -0.076