【问题标题】:PsychoPy: "Conditional" but random selection from list across two dimensionsPsychoPy:“有条件”但从二维列表中随机选择
【发布时间】:2015-04-30 09:57:50
【问题描述】:

在我的实验中,我展示了在 2 个维度上不同的图像(人脸):人脸身份和情感

有 5 张面孔显示 5 种不同的情绪表达;总共制作 25 种独特的刺激物。这些只需要呈现一次(所以 25 次试验)。

在我呈现其中一张面孔后,下一张面孔必须仅在情感或身份上有所不同,而另一张则相同。

示例:

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

1:精神病能胜任这项任务吗?到目前为止,我主要与构建器合作,除了一些数据记录代码,但我很乐意在编码器方面获得更多经验。

我的直觉是,我需要在试验列表中添加两列,一列用于身份,另一列用于情感。然后以某种方式使用 getEarlierTrial 调用,但此时我几乎迷路了。

2:有人愿意为我指明正确的方向吗?

非常感谢。

【问题讨论】:

  • 好吧,任何事情都应该在编码器中成为可能,因为那时您已经拥有了成熟的编程语言。我认为你仍然需要提供更多关于你想要实现的细节。所有图片都必须使用吗?您对序列的结构还有哪些其他限制?通常最容易在开始时在列表中定义您想要的序列(使用您的约束);然后,您可以在实验过程中逐步完成。
  • 感谢您的回复亚历克斯。所有图片都必须使用。其中有 25 个; 5张脸,5种不同的情绪表达。没有其他我能想到的限制;它需要是随机的,但我展示的尺寸之一需要与之前的试验相同。以后我可能想防止同一张脸/情绪重复三次或更多次,但现在还不行。我对 Python 语言没有太多经验,但我总是可以使用 Matlab 对每个参与者的这些约束重新排序我的列表。
  • 关于多少张面孔、多少情绪、多少总试验和随机化的信息是需要在问题中而不是隐藏在评论中的关键信息。

标签: psychopy


【解决方案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 中的循环设置为固定顺序,而不是随机化,因为列表本身具有内置随机化功能。

【讨论】:

  • 谢谢迈克尔,这看起来很有帮助。我什至没有想到伪随机化;好决定。我会试一试,我会告诉你我继续!
  • 嗨,迈克尔。这似乎工作正常,但我不确定。当我通过print images 输出我的列表时,它只输出一个图像对。这对符合标准;即face_2_emotion_5,face_4_emotion_5,太好了!我试图将其写入 csv 文件,但没有运气。有没有办法从psychopy(1列,25行)中获取完整列表?
  • 我的错误,但新的错误。我不会删除上面的评论,但我认为一旦我解决了以下问题,它可能会起作用: 1. 我认为我应该使用random.shuffle(list) 而不是shuffle(list)(后者不起作用)。 2.不知怎的,我忘了复制for choice in choices:这一行。这么草率。我在shell中一步步解决这个问题,问题似乎出在faces.remove(face)emotions.remove(emotion)命令上。我得到的错误是:ValueError: list.remove(x): x not in list。但是,我确信我们已将其列入清单。
  • PsychoPy Builder 从 numpy.random 显式导入 shuffle(),因此可以在代码组件中直接按名称使用。
  • 这是发布未经测试的代码的问题!由于随机选择,发布的原始算法仍然存在不平衡。例如您可以运行六个连续的恒定面,这会从列表中耗尽该面号,从而导致 ValueError。我将修改答案以包括一些蛮力保护,以便算法不断重复,直到生成成功的列表。这在理论上存在创建无限循环的风险,但在实践中似乎在数百次迭代后达到了解决方案。
猜你喜欢
  • 1970-01-01
  • 2016-02-16
  • 2018-11-11
  • 1970-01-01
  • 2019-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多