PsychoPy: условный, но случайный выбор из списка в двух измерениях

В своем эксперименте я представляю изображения (лица), которые различаются по двум параметрам: идентичность лица и эмоции.

Есть 5 лиц, отображающих 5 различных эмоциональных выражений; всего сделать 25 уникальных стимулов. Их нужно предъявить только один раз (то есть 25 испытаний).

После того, как я представлю одно из лиц, следующее лицо должно отличаться только по эмоциям ИЛИ идентичности, но таким же по другому.

Пример:

Face 1, emotion 1 -> face 3, emotion 1 -> face 3, emotion 4 -> ... etc.

1: Психопия справится с этой задачей? До сих пор я в основном работал с компоновщиком, за исключением некоторого кода регистрации данных, но я был бы рад получить больше опыта работы с кодером.

Я подозреваю, что мне нужно будет добавить две колонки в список испытаний, одну для личности и одну для эмоций. Затем каким-то образом используйте вызов getEarlierTrial, но в этот момент я почти теряюсь.

2: Может ли кто-нибудь указать мне правильное направление, пожалуйста?

Спасибо заранее.


person Cesco Willemse    schedule 30.04.2015    source источник
comment
Ну, все должно быть возможно в кодере, потому что тогда у вас есть полноценный язык программирования. Я думаю, вам все равно придется предоставить более подробную информацию о том, чего вы хотели бы достичь. Обязательно ли использовать все изображения? Какие еще ограничения у вас есть на структуру последовательности? Часто проще всего определить желаемую последовательность в списке в начале (используя ваши ограничения); затем вы можете просто пройти через него во время эксперимента.   -  person Axel Kohler    schedule 30.04.2015
comment
Спасибо за ответ Алекс. Все картинки должны быть использованы. Их 25; 5 лиц с 5 различными эмоциональными выражениями. Я не мог придумать никаких других ограничений; оно должно быть случайным, НО одно из измерений того, что я представляю, должно быть таким же, как и в предыдущем испытании. Я мог бы захотеть предотвратить три или более повторения одного и того же лица/эмоции позже, но не сейчас. У меня нет большого опыта работы с языком Python, но я всегда могу использовать Matlab, чтобы переупорядочить свой список с этими ограничениями для каждого участника.   -  person Cesco Willemse    schedule 30.04.2015
comment
Информация о том, сколько лиц, сколько эмоций, сколько всего испытаний и рандомизация — это ключевая информация, которая должна быть в вопросе, а не скрыта в комментарии.   -  person Michael MacAskill    schedule 01.05.2015


Ответы (1)


Это трудно реализовать в обычном режиме работы Builder, который заключается в управлении испытаниями из фиксированного списка условий. Хотя порядок строк может быть рандомизированным для субъектов, пары значений в столбцах остаются постоянными.

Стандартный ответ на это — это то, на что вы ссылаетесь в своем комментарии выше: в коде перетасовывайте файл условий в начале каждого эксперимента, чтобы каждый субъект, по сути, проводил испытания, управляемые уникальным файлом условий.

Вы, кажется, рады сделать это в Matlab. Это будет работать нормально, так как это можно сделать еще до запуска PsychoPy. Но его также можно очень легко реализовать в коде Python. Таким образом, вы могли бы делать все в PsychoPy, и в этом случае не нужно было бы отказываться от Builder. Вы просто вставляете компонент кода с некоторым кодом для запуска в начале эксперимента, который настраивает файл условий.

Вам нужно будет создать три списка, а не два, т. е. вам также нужен список псевдослучайных вариантов, чтобы чередовать сохранение лица или эмоций от испытания к испытанию: если вы сделаете это полностью случайным образом, вы выйдете из равновесия, и исчерпать один из атрибутов раньше другого.

from numpy.random import shuffle

# make a list of 25 dictionaries of unique face/emotion pairs:
pairsList = []
for face in ['1', '2', '3', '4', '5']:
    for emotion in ['1', '2', '3', '4', '5']:
        pairsList.append({'faceNum': face, 'emotionNum': emotion})
shuffle(pairsList)

# a list of whether to alternate between preserving face or emotion across trials:
attributes = ['faceNum', 'emotionNum'] * 12 # length 24
shuffle(attributes) 

# need to create an initial selection before cycling though the 
# next 24 randomised but balanced choices:
pair = pairsList.pop()
currentFace = pair['faceNum']
currentEmotion = pair['emotionNum']
images = ['face_' + currentFace + '_emotion_' + currentEmotion + '.jpg']

for attribute in attributes:
    if attribute == 'faceNum':
        selection = currentFace
    else:
        selection = currentEmotion

    # find another pair with the same selected attribute:
    for pair in pairsList:

        if pair[attribute] == selection:
            # store the combination for this trial:
            currentFace = pair['faceNum']
            currentEmotion = pair['emotionNum']
            images.append('face_' + currentFace + '_emotion_' + currentEmotion + '.jpg')

            # remove this combination so it can't be used again
            pairsList.remove(pair)

images.reverse()
print(images)

Затем просто запишите список images в файл .csv с одним столбцом, чтобы использовать его в качестве файла условий.

Не забудьте установить цикл в Builder в фиксированном порядке, а не в случайном порядке, так как сам список имеет встроенную рандомизацию.

person Michael MacAskill    schedule 30.04.2015
comment
Спасибо, Михаил, очень полезно. Я даже не думал о псевдорандомизации; хороший звонок. Я попробую и дам вам знать, что я получаю! - person Cesco Willemse; 01.05.2015
comment
Привет, Майкл. Кажется, это работает нормально, но я не уверен. Когда я вывожу свой список через print images, он выводит только одну пару изображений. Эта пара соответствует критериям; то есть face_2_emotion_5, face_4_emotion_5, так что это здорово! Я пытался записать его в файл csv, но безуспешно. Есть ли способ получить полный список из психотипа (1 столбец, 25 строк)? - person Cesco Willemse; 04.05.2015
comment
Моя плохая, но новая ошибка. Я пока не буду удалять комментарий выше, но я думаю, что это может сработать, когда я решу следующую проблему: 1. Я считаю, что мне следует использовать random.shuffle(list), а не shuffle(list) (последнее не работает). 2. Как-то забыл скопировать строку for choice in choices:. Так небрежно. Я шаг за шагом устраняю эту неполадку в оболочке, и проблема, похоже, в командах faces.remove(face) и emotions.remove(emotion). Я получаю сообщение об ошибке: ValueError: list.remove(x): x not in list. Тем не менее, я уверен, что мы включили его в список. - person Cesco Willemse; 04.05.2015
comment
PsychoPy Builder явно импортирует shuffle() из numpy.random, поэтому он доступен непосредственно по имени в компонентах кода. - person Michael MacAskill; 05.05.2015
comment
Это проблема с публикацией непроверенного кода! Первоначальный опубликованный алгоритм все еще подвержен дисбалансу из-за случайного выбора. например у вас может быть серия из шести последовательных постоянных граней, что приведет к исчерпанию этого номера грани из списка, что приведет к ошибке ValueError. Я изменю ответ, включив некоторую защиту от грубой силы, чтобы алгоритм просто продолжал повторяться до тех пор, пока не будет сгенерирован успешный список. Это имеет теоретический риск создания бесконечного цикла, но на практике кажется, что решение достигается после нескольких сотен итераций. - person Michael MacAskill; 05.05.2015
comment
Великолепно! Этот код создает список из 25 изображений. Это занимает несколько попыток (200-1500), но для меня это не проблема. Однако список по-прежнему содержит дубликаты (полный пример слишком длинный, чтобы публиковать его в комментарии). Я полагаю, что мне нужна дополнительная строка удаления. (что-то вроде list.remove([face, emotion]?) или цикл, проверяющий, присутствует ли уже последний вывод в images -> pass. Я на правильном пути здесь? (Я очень ценю вашу помощь до сих пор. Вы не только решаете мои текущие проблемы, но и то, что я также многому узнаю от вас о Python). - person Cesco Willemse; 05.05.2015
comment
О! Нет, это не так просто. Код не включает никакой защиты от многократного выбора одной и той же пары эмоций/лиц. Я полностью пропустил включение этого ограничения, которое, конечно, присуще вопросу. Алгоритм необходимо полностью пересмотреть, так как в настоящее время списки лиц и эмоций независимы, тогда как на самом деле нам нужно выбирать из пар из них, чтобы избежать дублирования. Я немного подумаю и пересмотрю. - person Michael MacAskill; 06.05.2015
comment
Хорошо, теперь алгоритм полностью переработан, а ответ изменен. На самом деле теперь это намного проще и работает детерминировано за одну итерацию, поэтому теперь нет необходимости в обработке ошибок и подходе грубой силы. Теперь вы должны получить 25 уникальных комбинаций, удовлетворяющих вашему критерию чередования. Если это работает для вас, отметьте ответ как принятый в качестве руководства для будущих читателей. - person Michael MacAskill; 06.05.2015