from otree.api import *
doc = """
XAI Experiment with real estate agents
"""
conf_label = "Wie sicher sind Sie sich mit dieser Entscheidung?\nAngabe von 1 (unsicher) bis 5 (sicher)."
surp_label = "Wie überrascht sind Sie von der Vorhersage der KI?\nAngabe von 1 (nicht überrascht) bis 5 (überrascht)."
conf_choices = [[1, ""], [2, ""], [3, ""], [4, ""], [5, ""]]
price_label = "Ihre Preisschätzung in EUR/qm:"
likert_7_scale = [
[1, "Stimme überhaupt nicht zu"],
[2, ""], [3, ""], [4, ""], [5, ""], [6, ""],
[7, "Stimme voll zu"]
]
def creating_session(subsession):
for player in subsession.get_players():
import random
import pandas as pd
participant = player.participant
# shuffle of stages 1, 2, 3
my_indices = list(pd.read_csv("xai_experiment/immobilien_pred_prices.csv", index_col=0).index)
random.shuffle(my_indices)
participant.immoSampleOrderS1 = my_indices[:4]
participant.immoSampleOrderS2 = my_indices[4:12]
# shuffle of stage 4
stage_4_prop = [[0, 1], [0, 2], [0, 3], [1, 1], [1, 2], [1, 3]]
participant.outMarketProp = random.choice(stage_4_prop)
participant.inMarketProp = random.choice(stage_4_prop)
participant.treatment = random.choice(["none", "ai", "xai_local"])
# treat_nr = int(player.participant.id_in_session) % 3
# participant.treatment = ["none", "ai", "xai_local"][treat_nr] # "xai_global"
class C(BaseConstants):
NAME_IN_URL = 'xai_experiment'
PLAYERS_PER_GROUP = None
NUM_ROUNDS = 1
class Subsession(BaseSubsession):
pass
class Group(BaseGroup):
pass
class Player(BasePlayer):
# Ich möchte an dieser Studie teilnehmen
is_mobile = models.BooleanField()
consent = models.BooleanField(choices=["Ich möchte an der Studie teilnehmen."],
label="Durch das Ankreuzen des Kästchens erkläre ich mich mit der Teilnahme an der Studie einverstanden.")
#
#
# STAGE 1
#
#
priorLocation1 = models.FloatField()
priorBalcony1 = models.FloatField()
priorGreen1 = models.FloatField()
priorPrice1 = models.FloatField()
priorConfLocation1 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorConfBalcony1 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorConfGreen1 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorConfPrice1 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorLocation2 = models.FloatField()
priorBalcony2 = models.FloatField()
priorGreen2 = models.FloatField()
priorPrice2 = models.FloatField()
priorConfLocation2 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorConfBalcony2 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorConfGreen2 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorConfPrice2 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorLocation3 = models.FloatField()
priorBalcony3 = models.FloatField()
priorGreen3 = models.FloatField()
priorPrice3 = models.FloatField()
priorConfLocation3 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorConfBalcony3 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorConfGreen3 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorConfPrice3 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorLocation4 = models.FloatField()
priorBalcony4 = models.FloatField()
priorGreen4 = models.FloatField()
priorPrice4 = models.FloatField()
priorConfLocation4 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorConfBalcony4 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorConfGreen4 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorConfPrice4 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
priorImpLocation = models.IntegerField(
label="Wichtigkeit der Eigenschaft \nStadt (innerhalb der Kategorie \"A-Stadt\") für den Preis:",
min=0, max=100, initial=0)
priorImpBalcony = models.IntegerField(label="Wichtigkeit der Eigenschaft Balkon/Terasse für den Preis:",
min=0, max=100, initial=0)
priorImpGreen = models.IntegerField(
label="Wichtigkeit der Eigenschaft Anteil Grünenwähler im Stadtteil für den Preis:",
min=0, max=100, initial=0)
#
#
# STAGE 2
#
#
treatmentPrice1 = models.FloatField(label=price_label, min=0)
treatmentConfPrice1 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
treatmentSurprise1 = models.IntegerField(label=surp_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
treatmentPrice2 = models.FloatField(label=price_label, min=0)
treatmentConfPrice2 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
treatmentSurprise2 = models.IntegerField(label=surp_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
treatmentPrice3 = models.FloatField(label=price_label, min=0)
treatmentConfPrice3 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
treatmentSurprise3 = models.IntegerField(label=surp_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
treatmentPrice4 = models.FloatField(label=price_label, min=0)
treatmentConfPrice4 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
treatmentSurprise4 = models.IntegerField(label=surp_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
treatmentPrice5 = models.FloatField(label=price_label, min=0)
treatmentConfPrice5 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
treatmentSurprise5 = models.IntegerField(label=surp_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
treatmentPrice6 = models.FloatField(label=price_label, min=0)
treatmentConfPrice6 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
treatmentSurprise6 = models.IntegerField(label=surp_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
treatmentPrice7 = models.FloatField(label=price_label, min=0)
treatmentConfPrice7 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
treatmentSurprise7 = models.IntegerField(label=surp_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
treatmentPrice8 = models.FloatField(label=price_label, min=0)
treatmentConfPrice8 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
treatmentSurprise8 = models.IntegerField(label=surp_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
# ---> AI
aiTakeAdvice = models.IntegerField(
label='Ich beziehe den Rat der KI in meine Bewertung des Quadratmeterpreises ein.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
aiPercAccuracy = models.IntegerField(
label='Auf einer Skala von 0 bis 100%: Für wie präzise halten Sie die Preisprognosen der KI?',
choices=[[i, str(i) + '%'] for i in range(0, 101)])
aiCogTrustComp1 = models.IntegerField(
label='Die KI ist kompetent und effektiv bei der Vorhersage der angebotenen Quadratmeterpreises.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
aiCogTrustComp2 = models.IntegerField(
label='Die KI erfüllt Ihre Aufgabe, den angebotenen Quadratmeterpreis vorherzusagen, sehr gut.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
aiCogTrustComp3 = models.IntegerField(
label='Insgesamt ist die KI eine kompetente Hilfe für meine Bewertung des Quadratmeterpreises.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
aiCogTrustInteg1 = models.IntegerField(label='Die KI gibt unvoreingenommene Bewertungen ab.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7],
)
aiCogTrustInteg2 = models.IntegerField(label='Die KI ist ehrlich.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7],
)
aiCogTrustInteg3 = models.IntegerField(label='Ich halte diese KI für integer.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7],
)
aiEmoTrust1 = models.IntegerField(
label='Ich fühle mich sicher, wenn ich mich bei meiner Entscheidung auf die KI verlasse.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
aiEmoTrust2 = models.IntegerField(
label='Ich fühle mich wohl, wenn ich mich bei meiner Entscheidung auf die KI verlasse.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
aiEmoTrust3 = models.IntegerField(
label='Ich fühle mich zufrieden, wenn ich mich bei meiner Entscheidung auf die KI verlasse.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
# aiPerUsefulness1 = models.IntegerField(
# label='Die Verwendung dieser KI bei meiner Arbeit würde meine Produktivität erhöhen.',
# widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
# aiPerUsefulness2 = models.IntegerField(label='Die Verwendung dieser KI würde meine Effektivität erhöhen.',
# widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7],
# )
# aiPerUsefulness3 = models.IntegerField(label='Ich würde diese KI für meine Arbeit nützlich finden.',
# widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7],
# )
# ---> XAI
explTakeAdvice = models.IntegerField(
label='Ich beziehe die Erklärungen in meine Bewertung des Quadratmeterpreises ein.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
explPercAccuracy = models.IntegerField(
label='Auf einer Skala von 0 bis 100%: Für wie präzise halten Sie die Erklärungen der KI?',
choices=[[i, str(i) + '%'] for i in range(0, 101)])
explCogTrustComp1 = models.IntegerField(
label='Die Erklärungen sind kompetent und effektiv darin die Logik der KI zu vermitteln.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
explCogTrustComp2 = models.IntegerField(
label='Die Erklärungen erfüllen Ihre Aufgabe, die Logik der KI zu vermitteln, sehr gut.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
explCogTrustComp3 = models.IntegerField(
label='Insgesamt sind die Erklärungen eine kompetente Hilfe um die Logik der KI zu verstehen.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
explCogTrustInteg1 = models.IntegerField(label='Die Erklärungen sind unvoreingenommen.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7],
)
explCogTrustInteg2 = models.IntegerField(label='Die Erklärungen sind ehrlich.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7],
)
explCogTrustInteg3 = models.IntegerField(label='Ich halte die Erklärungen für integer.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7],
)
explEmoTrust1 = models.IntegerField(
label='Ich fühle mich sicher, wenn ich mich bei meiner Entscheidung auf die Erklärungen verlasse.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
explEmoTrust2 = models.IntegerField(
label='Ich fühle mich wohl, wenn ich mich bei meiner Entscheidung auf die Erklärungen verlasse.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
explEmoTrust3 = models.IntegerField(
label='Ich fühle mich zufrieden, wenn ich mich bei meiner Entscheidung auf die Erklärungen verlasse.',
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
# explPerUsefulness1 = models.IntegerField(
# label="Die Verwendung dieser Erklärungen bei meiner Arbeit würde meine Produktivität erhöhen.",
# widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
# explPerUsefulness2 = models.IntegerField(
# label="Die Verwendung dieser Erklärungen würde meine Effektivität erhöhen.",
# widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7],
# )
# explPerUsefulness3 = models.IntegerField(label="Ich würde diese Erklärungen für meine Arbeit nützlich finden.",
# widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7],
# )
#
#
# STAGE 3
#
#
postLocation1 = models.FloatField()
postBalcony1 = models.FloatField()
postGreen1 = models.FloatField()
postPrice1 = models.FloatField()
postConfLocation1 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postConfBalcony1 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postConfGreen1 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postConfPrice1 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postLocation2 = models.FloatField()
postBalcony2 = models.FloatField()
postGreen2 = models.FloatField()
postPrice2 = models.FloatField()
postConfLocation2 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postConfBalcony2 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postConfGreen2 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postConfPrice2 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postLocation3 = models.FloatField()
postBalcony3 = models.FloatField()
postGreen3 = models.FloatField()
postPrice3 = models.FloatField()
postConfLocation3 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postConfBalcony3 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postConfGreen3 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postConfPrice3 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postLocation4 = models.FloatField()
postBalcony4 = models.FloatField()
postGreen4 = models.FloatField()
postPrice4 = models.FloatField()
postConfLocation4 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postConfBalcony4 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postConfGreen4 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postConfPrice4 = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
postImpLocation = models.IntegerField(
label="Wichtigkeit der Eigenschaft \nStadt (innerhalb der Kategorie \"A-Stadt\") für den Preis:",
min=0, max=100, initial=0)
postImpBalcony = models.IntegerField(label="Wichtigkeit der Eigenschaft Balkon/Terasse für den Preis:",
min=0, max=100, initial=0)
postImpGreen = models.IntegerField(
label="Wichtigkeit der Eigenschaft Anteil Grünenwähler im Stadtteil für den Preis:",
min=0, max=100, initial=0)
#
#
# STAGE 4
#
#
inMarket_Price = models.FloatField(label=price_label, min=0)
inMarket_ConfPrice = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
outMarket_Price = models.FloatField(label=price_label, min=0)
outMarket_ConfPrice = models.IntegerField(label=conf_label, widget=widgets.RadioSelectHorizontal,
choices=[1, 2, 3, 4, 5])
#
#
# FINAL QUESTIONNAIRE
#
#
age = models.IntegerField(label="Wie alt sind Sie?", choices=range(16, 100))
gender = models.StringField(label="Was ist Ihr Geschlecht?", widget=widgets.RadioSelectHorizontal,
choices=["Weiblich", "Männlich", "Divers"])
degree = models.StringField(label="Was ist ihr höchster akademischer Abschluss?",
choices=["Hauptschulabschluss", "Realschulabschluss", "Abitur", "Bachelor", "Master",
"Doktor", "anderer Abschluss"])
experience_industry = models.IntegerField(
label="Wie viele Jahre Berufserfahrung in der Immobilienbranche besitzen Sie?",
choices=range(0, 100))
experience_task = models.IntegerField(label="Über wie viel "
"Erfahrung in der Bewertung von Wohnungen haben Sie?",
widget=widgets.RadioSelectHorizontal, choices=range(0, 11))
overconfidence1 = models.IntegerField(label="Ich denke, dass ich besser darin bin, Immobilienobjekte akkurat zu "
"bewerten als der durchschnittliche Immobilienunternehmer in Deutschland.",
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
overconfidence2 = models.IntegerField(label="Ich denke, dass ich schlauer bin als der durchschnittliche Deutsche.",
widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7])
risk_aversion = models.IntegerField(label="Im Allgemeinen, wie bereit sind Sie, Risiken einzugehen?",
widget=widgets.RadioSelectHorizontal, choices=range(0, 11))
ai_familiarity = models.IntegerField(label="Ich bin mit Vorhersagesoftware vertraut, die Informationen "
"bereitstellt, um menschliche Entscheidungen zu unterstützen.",
widget=widgets.RadioSelectHorizontal, choices=range(0, 11))
email = models.StringField(label="Ihre E-Mail Adresse:", blank=True)
# PAGES
class InstructionsPage(Page):
form_model = 'player'
form_fields = ['is_mobile', 'consent']
@staticmethod
def vars_for_template(player):
new_version = False
try:
if player.participant.label[0] in ["k", "x"]:
new_version = True
except:
pass
return dict(
new_version=new_version
)
class Stage1(Page):
form_model = "player"
form_fields = ["priorLocation1", "priorBalcony1", "priorGreen1", "priorPrice1",
"priorConfLocation1", "priorConfBalcony1", "priorConfGreen1", "priorConfPrice1",
"priorLocation2", "priorBalcony2", "priorGreen2", "priorPrice2",
"priorConfLocation2", "priorConfBalcony2", "priorConfGreen2", "priorConfPrice2",
"priorLocation3", "priorBalcony3", "priorGreen3", "priorPrice3",
"priorConfLocation3", "priorConfBalcony3", "priorConfGreen3", "priorConfPrice3",
"priorLocation4", "priorBalcony4", "priorGreen4", "priorPrice4",
"priorConfLocation4", "priorConfBalcony4", "priorConfGreen4", "priorConfPrice4",
"priorImpLocation", "priorImpBalcony", "priorImpGreen"]
@staticmethod
def vars_for_template(player):
import pandas as pd
# prepare houses dictionary (for each player individually because of random order)
houses = pd.read_csv("xai_experiment/immobilien_features.csv", index_col=0)[
['Frankfurt', "balcony", "Anteil Gruenenwaehler"]]
houses = houses.rename(columns={'Frankfurt': 'cit', 'balcony': 'bal', 'Anteil Gruenenwaehler': 'gre'})
houses["cit"] = ["Frankfurt am Main" if f == 1 else "Köln" for f in houses["cit"]]
houses["bal"] = ["Ja" if b == 1 else "Nein" for b in houses["bal"]]
houses["gre"] = ["Unterdurchschnittlich" if g == 1 else "Durchschnittlich" if g == 2 else "Überdurchschnittlich"
for g in houses["gre"]]
indices_to_show = player.participant.immoSampleOrderS1
houses_in_order = []
ord = 0
for i in indices_to_show:
ord += 1
focal_dic = houses[houses.index == i].to_dict('records')
focal_dic[0]["ind"] = i
focal_dic[0]["ord"] = ord
focal_dic[0]["confLocation"] = "priorConfLocation" + str(ord)
focal_dic[0]["confBalcony"] = "priorConfBalcony" + str(ord)
focal_dic[0]["confGreen"] = "priorConfGreen" + str(ord)
focal_dic[0]["confPrice"] = "priorConfPrice" + str(ord)
houses_in_order.append(focal_dic)
return dict(
houses_in_order=houses_in_order
)
@staticmethod
def js_vars(player):
import pandas as pd
# prepare price to be displayed for only fixed features
prices = pd.read_csv("xai_experiment/immobilien_cat_A_sim_prices.csv", index_col=0)
pred_price_fixed = round(sum(prices.pred_price) / len(prices) / 50) * 50
return dict(
pred_price_fixed=pred_price_fixed
)
@staticmethod
def error_message(player, values):
print('values is', values)
if values['priorImpLocation'] + values['priorImpBalcony'] + values['priorImpGreen'] != 100:
return f"Bitte überprüfen Sie Ihre Angaben zur Wichtigkeit der variablen Eigenschaften. Die Summe der " \
f"von Ihnen vergebenen Sterne muss 100 ergeben. Aktuell ergibt sie " \
f"{values['priorImpLocation']} + {values['priorImpBalcony']} + {values['priorImpGreen']} = " \
f"{values['priorImpLocation'] + values['priorImpBalcony'] + values['priorImpGreen']}."
class Stage2(Page):
form_model = "player"
@staticmethod
def get_form_fields(player):
form_fields = ["treatmentPrice1", "treatmentPrice2", "treatmentPrice3", "treatmentPrice4",
"treatmentPrice5", "treatmentPrice6", "treatmentPrice7", "treatmentPrice8",
"treatmentConfPrice1", "treatmentConfPrice2", "treatmentConfPrice3", "treatmentConfPrice4",
"treatmentConfPrice5", "treatmentConfPrice6", "treatmentConfPrice7", "treatmentConfPrice8"]
if player.participant.treatment != "none":
form_fields.extend(["treatmentSurprise1", "treatmentSurprise2", "treatmentSurprise3", "treatmentSurprise4",
"treatmentSurprise5", "treatmentSurprise6", "treatmentSurprise7", "treatmentSurprise8"])
return form_fields
@staticmethod
def vars_for_template(player):
import pandas as pd
# prepare houses dictionary (for each player individually because of random order)
houses = pd.read_csv("xai_experiment/immobilien_features.csv", index_col=0)[
['Frankfurt', "balcony", "Anteil Gruenenwaehler"]]
houses = houses.rename(columns={'Frankfurt': 'cit', 'balcony': 'bal', 'Anteil Gruenenwaehler': 'gre'})
houses["cit"] = ["Frankfurt am Main" if f == 1 else "Köln" for f in houses["cit"]]
houses["bal"] = ["Ja" if b == 1 else "Nein" for b in houses["bal"]]
houses["gre"] = ["Unterdurchschnittlich" if g == 1 else "Durchschnittlich" if g == 2 else "Überdurchschnittlich"
for g in houses["gre"]]
indices_to_show = player.participant.immoSampleOrderS2
houses_in_order = []
# prepare predicted prices for treatments ai, xai local, xai global
prices = pd.read_csv("xai_experiment/immobilien_pred_prices.csv", index_col=0)
# prepare SHAP val for treatments xai local
shap_val = pd.read_csv("xai_experiment/immobilien_shap.csv", index_col=0)
shap_val = shap_val[['Stadt', 'balcony', 'Anteil Gruenenwaehler']]
shap_val = shap_val.rename(columns={'Stadt': 'cit', 'balcony': 'bal', 'Anteil Gruenenwaehler': 'gre'})
shap_val = shap_val.applymap(
lambda x: "+" + '{:,}'.format(round(x / 50) * 50).replace(",", "X").replace(".", ",").replace("X",
".") + " EUR/qm"
if round(x / 50) * 50 > 0 else
'{:,}'.format(round(x / 50) * 50).replace(",", "X").replace(".", ",").replace("X", ".") + " EUR/qm")
ord = 0
for i in indices_to_show:
ord += 1
focal_dic = houses[houses.index == i].to_dict('records')
focal_dic[0]["pred_price"] = '{:,}'.format(round(prices[prices.index == i]["predicted"].item() / 50) * 50) \
.replace(",", "X").replace(".", ",").replace("X", ".") + " EUR/qm"
focal_dic[0]["shap"] = shap_val[shap_val.index == i].to_dict('records')
focal_dic[0]["ind"] = i
focal_dic[0]["ord"] = ord
focal_dic[0]["Price"] = "treatmentPrice" + str(ord)
focal_dic[0]["ConfPrice"] = "treatmentConfPrice" + str(ord)
focal_dic[0]["Surprise"] = "treatmentSurprise" + str(ord)
houses_in_order.append(focal_dic)
# prepare price to be displayed for only fixed features
prices = pd.read_csv("xai_experiment/immobilien_cat_A_sim_prices.csv", index_col=0)
pred_price_fixed = '{:,}'.format(round(sum(prices.pred_price) / len(prices) / 50) * 50) \
.replace(",", "X").replace(".", ",").replace("X", ".") + " EUR/qm"
return dict(
avg_price=pred_price_fixed,
houses_in_order=houses_in_order
)
@staticmethod
def js_vars(player):
import pandas as pd
# prepare price to be displayed for only fixed features
prices = pd.read_csv("xai_experiment/immobilien_cat_A_sim_prices.csv", index_col=0)
pred_price_fixed = '{:,}'.format(round(sum(prices.pred_price) / len(prices) / 50) * 50) \
.replace(",", "X").replace(".", ",").replace("X", ".") + " EUR/qm"
return dict(
pred_price_fixed=pred_price_fixed
)
class Stage2Questions(Page):
form_model = "player"
@staticmethod
def is_displayed(player):
return not player.participant.treatment == "none"
@staticmethod
def get_form_fields(player):
form_fields = []
if player.participant.treatment != "none":
form_fields = ["aiTakeAdvice", "aiPercAccuracy",
"aiCogTrustComp1", "aiCogTrustComp2", "aiCogTrustComp3",
"aiCogTrustInteg1", "aiCogTrustInteg2", "aiCogTrustInteg3",
"aiEmoTrust1", "aiEmoTrust2", "aiEmoTrust3"] # "aiPerUsefulness1", "aiPerUsefulness2", "aiPerUsefulness3"
if player.participant.treatment in ["xai_local", "xai_global"]:
form_fields.extend(["explTakeAdvice", "explPercAccuracy",
"explCogTrustComp1", "explCogTrustComp2", "explCogTrustComp3",
"explCogTrustInteg1", "explCogTrustInteg2", "explCogTrustInteg3",
"explEmoTrust1", "explEmoTrust2", "explEmoTrust3"]) # "explPerUsefulness1", "explPerUsefulness2", "explPerUsefulness3"
return form_fields
class Stage3(Page):
form_model = "player"
form_fields = ["postLocation1", "postBalcony1", "postGreen1", "postPrice1",
"postConfLocation1", "postConfBalcony1", "postConfGreen1", "postConfPrice1",
"postLocation2", "postBalcony2", "postGreen2", "postPrice2",
"postConfLocation2", "postConfBalcony2", "postConfGreen2", "postConfPrice2",
"postLocation3", "postBalcony3", "postGreen3", "postPrice3",
"postConfLocation3", "postConfBalcony3", "postConfGreen3", "postConfPrice3",
"postLocation4", "postBalcony4", "postGreen4", "postPrice4",
"postConfLocation4", "postConfBalcony4", "postConfGreen4", "postConfPrice4",
"postImpLocation", "postImpBalcony", "postImpGreen"]
@staticmethod
def vars_for_template(player):
import pandas as pd
# prepare houses dictionary (for each player individually because of random order)
houses = pd.read_csv("xai_experiment/immobilien_features.csv", index_col=0)[
['Frankfurt', "balcony", "Anteil Gruenenwaehler"]]
houses = houses.rename(columns={'Frankfurt': 'cit', 'balcony': 'bal', 'Anteil Gruenenwaehler': 'gre'})
houses["cit"] = ["Frankfurt am Main" if f == 1 else "Köln" for f in houses["cit"]]
houses["bal"] = ["Ja" if b == 1 else "Nein" for b in houses["bal"]]
houses["gre"] = ["Unterdurchschnittlich" if g == 1 else "Durchschnittlich" if g == 2 else "Überdurchschnittlich"
for g in houses["gre"]]
indices_to_show = player.participant.immoSampleOrderS1
houses_in_order = []
ord = 0
for i in indices_to_show:
ord += 1
focal_dic = houses[houses.index == i].to_dict('records')
focal_dic[0]["ind"] = i
focal_dic[0]["ord"] = ord
focal_dic[0]["confLocation"] = "postConfLocation" + str(ord)
focal_dic[0]["confBalcony"] = "postConfBalcony" + str(ord)
focal_dic[0]["confGreen"] = "postConfGreen" + str(ord)
focal_dic[0]["confPrice"] = "postConfPrice" + str(ord)
houses_in_order.append(focal_dic)
return dict(
houses_in_order=houses_in_order
)
@staticmethod
def js_vars(player):
import pandas as pd
# prepare price to be displayed for only fixed features
prices = pd.read_csv("xai_experiment/immobilien_cat_A_sim_prices.csv", index_col=0)
pred_price_fixed = round(sum(prices.pred_price) / len(prices) / 50) * 50
return dict(
pred_price_fixed=pred_price_fixed
)
@staticmethod
def error_message(player, values):
print('values is', values)
if values['postImpLocation'] + values['postImpBalcony'] + values['postImpGreen'] != 100:
return f"Bitte überprüfen Sie Ihre Angaben zur Wichtigkeit der variablen Eigenschaften. Die Summe der" \
f"von Ihnen vergebenen Sterne muss 100 ergeben. Aktuell ergibt sie " \
f"{values['postImpLocation']} + {values['postImpBalcony']} + {values['postImpGreen']} = " \
f"{values['postImpLocation'] + values['postImpBalcony'] + values['postImpGreen']}."
class Stage4(Page):
form_model = "player"
form_fields = ["inMarket_Price", "inMarket_ConfPrice", "outMarket_Price", "outMarket_ConfPrice"]
@staticmethod
def vars_for_template(player):
balconyDict = {0: "Nein", 1: "Ja"}
greenDict = {1: "Unterdurchschnittlich", 2: "Durchschnittlich", 3: "Überdurchschnittlich"}
return dict(
immo_val={
"outMarket": {
"Balcony": balconyDict[player.participant.outMarketProp[0]],
"Green": greenDict[player.participant.outMarketProp[1]],
},
"inMarket": {
"Balcony": balconyDict[player.participant.inMarketProp[0]],
"Green": greenDict[player.participant.inMarketProp[1]],
}
}
)
class LastPage(Page):
form_model = "player"
form_fields = ["age", "gender", "degree", "experience_industry", "experience_task", "overconfidence1",
"overconfidence2", "risk_aversion", "ai_familiarity", "email"]
@staticmethod
def vars_for_template(player):
new_version = False
try:
if player.participant.label[0] in ["k", "x"]:
new_version = True
except:
pass
return dict(
new_version=new_version
)
class ThankYouPage(Page):
pass
page_sequence = [InstructionsPage, Stage1, Stage2, Stage2Questions, Stage3, Stage4, LastPage, ThankYouPage] #