Skip to content

Mener des expériences comportementales en ligne dans Potato

Un guide pour les études de psychologie, de sciences cognitives et de psycholinguistique : conditions, contrebalancement, essais chronométrés, exclusions, Prolific et SONA, et données d'essais.

Dans Potato, une expérience comportementale en ligne est une configuration YAML qui liste les pages de la session dans l'ordre, affecte chaque participant à une condition et enregistre chaque essai avec son chronométrage. Depuis Potato 2.12.0, la configuration couvre les conditions inter-sujets, les listes et ordres de blocs en carré latin, les essais chronométrés avec temps de réaction, la lecture auto-rythmée, les exclusions et le retour vers Prolific ou SONA, et une timeline jsPsych peut s'exécuter comme une page de la session.

Ce guide s'adresse aux chercheurs en psychologie, en sciences cognitives et en psycholinguistique qui construiraient sinon l'étude dans jsPsych, PsychoPy, Gorilla, Ibex ou Qualtrics. Il reprend leur vocabulaire :

  • Un essai est une présentation d'un stimulus et la réponse qu'il reçoit. Dans Potato, un essai correspond généralement à un item d'un fichier de données.
  • Un facteur inter-sujets attribue un seul niveau à chaque participant. Un facteur intra-sujets montre tous les niveaux à chaque participant, généralement dans un ordre contrebalancé.
  • Le temps de réaction (TR) va de l'apparition du stimulus à la réponse.
  • Une exclusion met fin à la session pour un participant qui ne remplit pas les critères d'inclusion, et un code de complétion indique à la plateforme de recrutement que le participant a terminé.

Comparatif des outils d'expérimentation comportementale situe Potato par rapport aux autres outils, et Venir de jsPsych fait correspondre les concepts de jsPsych aux clés de configuration.

Les parties d'une étude et la clé Potato de chacune

Partie de l'étudePotatoPage
Consentement, consignes, données sociodémographiques, débriefingPages de phase dans phases.orderFlux de travail multi-phases
Facteurs inter-sujetsconditionsDéroulement de l'expérience
Listes de stimuli dans un plan en carré latinUn facteur list avec batch_assignment.group_by_conditionDéroulement de l'expérience
Ordre des blocsphases.counterbalance, aléatoire ou en carré latin de WilliamsDéroulement de l'expérience
Ordre des questions d'un questionnairerandomize_questionsDéroulement de l'expérience
Critères d'inclusionexit_when sur une page de sélectionDéroulement de l'expérience
Jugements rapides avec TRtrial_timingEssais chronométrés
Lecture auto-rythmée, labyrinthetrial_timing.presentationLecture auto-rythmée et labyrinthe
Tâches qui exigent du code d'essaiUne page type: jspsychPhases d'exécution
Dépistage du casqueUne page type: headphone_checkPhases d'exécution
Un jeu ou une tâche sur un autre serveur (oTree, Empirica)Une page type: externalPhases d'exécution
Questionnaires validésinstrument: sur une page de questionnaireInstruments de questionnaire
Tests de compétencecloze, un test de type LexTALETexte à trous, Tests de vocabulaire
Contrôles d'attentionattention_checksContrôle de la qualité
Élicitation incitativeprice_list, bdm, belief_elicitation et incentivesPaiements incitatifs

Affecter les participants aux conditions

conditions attribue à chaque participant une cellule du plan la première fois que le serveur le voit, et le participant la conserve. L'affectation est balanced par défaut, ce qui envoie chaque arrivant vers la cellule qui compte le moins de participants. balance_on: completed ne compte que les participants ayant terminé sans être exclus ; un abandon est donc remplacé par l'arrivant suivant, et les cellules restent équilibrées.

Pour un plan dans lequel chaque item existe en plusieurs versions et chaque participant voit une version de chaque item, faites de la liste un facteur et donnez à chaque niveau son propre fichier de données. Le participant ne voit alors que les items de sa liste :

yaml
conditions:
  factors:
    list: [list_a, list_b]
  balance_on: completed
 
assignment_strategy: batch
batch_assignment:
  auto_assign_annotators: true
  group_by_condition: list
  groups:
    - {name: list_a, data_file: data/list_a.jsonl}
    - {name: list_b, data_file: data/list_b.jsonl}

Les identifiants d'items doivent être uniques d'un fichier à l'autre ; les deux versions d'un même item ont donc besoin d'identifiants différents, par exemple s1_a et s1_b. Une expérience Ibex ou PCIbex s'importe exactement dans cette organisation (Venir d'Ibex).

Choisir comment les essais s'exécutent

Potato offre deux façons d'exécuter les essais, et le choix dépend de ce que l'essai doit faire.

Les essais chronométrés sur des items (trial_timing) conviennent aux tâches où chaque essai montre un stimulus issu d'un fichier de données et reçoit une seule réponse : décision lexicale, jugements d'acceptabilité ou de plausibilité avec un délai, catégorisation rapide d'images. Chaque essai reçoit une croix de fixation, une durée de stimulus, un délai et des touches associées aux étiquettes, et le TR est mesuré à partir de l'image d'animation sur laquelle le stimulus a été dessiné. L'apparition est connue à l'image près, soit environ 17 ms à 60 Hz. La lecture auto-rythmée et la tâche du labyrinthe utilisent le même mécanisme, avec un temps de lecture par région.

Une page jsPsych convient aux tâches qui exigent du code à chaque essai : dessin sur canvas, masques synchronisés sur une image, audio programmé avec Web Audio, trajectoires de souris, boucles et branchements à l'intérieur d'un bloc, ou plein écran maintenu d'un essai à l'autre. La page exécute jsPsych 8.3.0 seul, et la timeline lit les conditions du participant dans potato.conditions.

Les TR mesurés dans le navigateur comportent une latence due aux claviers et aux écrans qui varie d'une machine à l'autre, couramment de 5 à 30 ms. Comparez les TR au sein des participants, ou modélisez-les avec un terme participant.

Sélectionner les participants

Un questionnaire de sélection est une page prestudy dotée d'un exit_when. Quand sa règle est vérifiée, le participant est envoyé à la fin de la session, et, si une plateforme de recrutement est configurée, il reçoit le résultat d'exclusion de la plateforme au lieu du code de complétion. Previous ne le ramène pas en arrière.

Les études d'écoute peuvent ajouter un test de casque, noté par le serveur ; un participant ne peut donc pas le réussir en modifiant ce qu'envoie le navigateur. Les études en langue seconde peuvent ajouter un test de closure ou un test de vocabulaire de type LexTALE. Potato n'inclut pas les listes d'items de LexTALE ; fournissez-les donc selon les conditions de leurs auteurs. Le score de vocabulaire est calculé à l'export ; sélectionner sur ce score revient donc à inviter les participants qui remplissent le critère à une seconde étude.

Les contrôles d'attention à l'intérieur de la tâche sont un mécanisme distinct (Contrôle de la qualité). Un essai chronométré qui expire sur un contrôle d'attention est enregistré comme un dépassement de délai et n'est pas noté comme un échec, car une tâche rapide produit aussi des dépassements de délai chez des participants attentifs.

Recruter par Prolific ou SONA

Pour Prolific, lisez l'identifiant du participant dans l'URL de l'étude et donnez à Potato un code de complétion et un code d'exclusion :

yaml
login:
  type: url_direct
  url_argument: PROLIFIC_PID
 
crowdsourcing:
  provider: prolific
  prolific:
    completion:
      code: "C1ABCDEF"          # finished
      failed_code: "C1SCREEN"   # screened out

Pour un vivier de participants SONA, crowdsourcing.provider: sona accorde les crédits de cours depuis le serveur quand un participant termine ; le participant n'a donc pas à suivre un lien de retour vers SONA. Mener une étude en crowdsourcing couvre les deux plateformes, CloudResearch Connect et les autres fournisseurs.

Une étude complète

La configuration ci-dessous exécute une étude de jugements d'acceptabilité recrutée sur Prolific. Chaque participant est affecté à l'une de deux listes de stimuli, donne son consentement, répond à un questionnaire de sélection sur la langue maternelle qui met fin à la session pour les locuteurs non natifs, juge chaque phrase de sa liste avec un délai de quatre secondes, et termine par un questionnaire de profil dont la zone de commentaire vient en dernier.

yaml
annotation_task_name: Acceptability judgments
task_dir: .
output_annotation_dir: annotation_output/
data_files:
  - data/list_a.jsonl
item_properties:
  id_key: id
  text_key: text
user_config:
  allow_all_users: true
  users: []
login:
  type: url_direct
  url_argument: PROLIFIC_PID
 
conditions:
  factors:
    list: [list_a, list_b]
  balance_on: completed
 
assignment_strategy: batch
batch_assignment:
  auto_assign_annotators: true
  group_by_condition: list
  groups:
    - {name: list_a, data_file: data/list_a.jsonl}
    - {name: list_b, data_file: data/list_b.jsonl}
 
phases:
  order: [consent, screener, annotation, background]
  consent:
    type: consent
    file: surveys/consent.json
  screener:
    type: prestudy
    file: surveys/screener.json
    exit_when:
      show_when:
        - {schema: native_english, operator: equals, value: "No"}
      message: This study is for native speakers of English. Thank you for your time.
  background:
    type: poststudy
    file: surveys/background.json
    randomize_questions:
      pin_last: [comments]
 
trial_timing:
  enabled: true
  fixation_ms: 500
  trial_duration_ms: 4000
  iti_ms: 500
  response:
    schema: judgment
    keys: {f: acceptable, j: unacceptable}
 
annotation_schemes:
  - annotation_type: radio
    name: judgment
    description: Is this sentence acceptable in English?
    labels: [acceptable, unacceptable]
    label_requirement:
      required: true
 
crowdsourcing:
  provider: prolific
  prolific:
    completion:
      code: "C1ABCDEF"
      failed_code: "C1SCREEN"

Chaque fichier de questionnaire est une liste JSON de questions, chacune avec annotation_type, name et description. La question du questionnaire de sélection s'appelle native_english, pour que exit_when puisse la tester :

json
[{"annotation_type": "radio", "name": "native_english",
  "description": "Is English your native language?",
  "labels": ["Yes", "No"], "label_requirement": {"required": true}}]

Les fichiers d'items contiennent une phrase par ligne, avec les éventuelles colonnes du plan conservées pour l'analyse :

json
{"id": "s1_a", "text": "Which book did you read before filing?", "condition": "gap"}

Cette configuration passe python -m potato.validate_cli config.yaml --strict sous Potato 2.12.0. Lancez-la avec potato start config.yaml, et testez-la en mode débogage ou avec des participants simulés avant de la publier.

Récupérer les données

bash
python -m potato.export --config config.yaml --format csv --output ./export/

L'export CSV écrit les jugements, plus trois tables pour le plan :

  • participants.csv, une ligne par participant, avec ses conditions, ses ordres de blocs et de questions, les pages sautées et une éventuelle exclusion ;
  • trials.csv, une ligne par essai chronométré, avec le TR, le résultat (response ou timeout), ce que le navigateur a produit par rapport à ce qui était configuré, et les vérifications du serveur ;
  • regions.csv, une ligne par région, pour la lecture auto-rythmée et le labyrinthe.

--format runtime écrit les exécutions et les essais des pages jsPsych, des tests de casque et des tâches externes. --format psych_ds écrit un jeu de données Psych-DS, et --format data_package enveloppe l'export CSV dans un Frictionless Data Package avec un Table Schema par fichier.

Ce que Potato ne fait pas

  • Oculométrie et enregistrement par webcam. L'extension WebGazer de jsPsych n'est pas fournie, car elle a besoin de 'unsafe-eval', que la Content-Security-Policy de la page jsPsych n'autorise pas.
  • Essais chronométrés sur téléphones et tablettes. Ces appareils reçoivent l'interface tactile de Potato, qui n'exécute pas trial_timing. Une page jsPsych fonctionne sur tout appareil pris en charge par jsPsych.
  • Plein écran d'un item à l'autre. Chaque item est un chargement de page, et les navigateurs quittent le plein écran quand la page change. Une page jsPsych maintient le plein écran pendant toute sa timeline.
  • Le backend de stockage MySQL pour les données du plan. MySQL n'enregistre ni le déroulement ni les enregistrements d'essais ; utilisez donc le stockage par défaut pour ces études.

Pour aller plus loin