Psychopy | 第4期:实验数据的收集与处理

  • 1 相关概念的简单引入
  • 2 被试信息录入
  • 3 反应时记录
  • 4 正确率记录
  • 5 完整代码展示
  • 6 系列课程的总结



Hello,
这里是行上行下,我是喵君姐姐~

最近在家实在无聊,所以只好安安心心学习啦。你最近在家干什么呢?

今天,继续邀请阿槑给你带来Psychopy系列教程,带来实验数据的收集与处理,希望你会继续喜欢并且一直支持哟~

1 相关概念的简单引入

在前几期,我们已经学习了Psychopy入门、数据类型与运算符、条件与循环、flanker范式的完整编程。

但是,在心理学实验中,除了要在屏幕上呈现想要的刺激,我们还希望计算机能够帮助我们收集被试基本信息、反应时以及正确率等指标。

那么如何达到这一目的呢?

2 被试信息录入

对于被试信息,我们将使用 psychopy 中的 gui 来进行收集,所谓 gui ,就是一个被试可以在其中填写信息的对话框,如图:

在导入 gui 后,我们使用 gui 中的 DlgFromDict 来进行功能的实现:

from psychopy import core, gui #导入
info = {'observer':'01_xxx','gender':['m','f'],'age':18}
dlg = gui.DlgFromDict(info, title='flanker', order=['observer','gender','age']) #设置gui
if dlg.OK: #单击 OK 后的操作      pass #占位符
else:      core.quit()

可以看到,我们先定义了一个字典来储存需要填写信息的标题以及对应的默认内容,之后我们使用 DlgFromDict 将字典导入 gui 并设置 gui 的标题(title)以及内容顺序(order)。

最后用一个 if 函数来控制 OK 按键使其继续后面的操作,或者 Cancel 按键退出整个程序。因为这里的退出需要使用 core,因此同样需要在开头进行导入。

下一步,我们需要确定一下我们最终记录的数据文档的输出路径及文件名。

首先,我们在程序所在路径,也就是我们程序脚本所在的位置建立一个 data 文件夹用于存放数据。

之后,我们先以字符串的形式定义文件名,为了防止文件重复,将会通过 time 获取当前系统时间并添加到文件名中。

import time
date = time.strftime("_20%y_%m_%d_%H%M", time.localtime()) #获取当前时间
file = 'data/'+info['observer']+'_'+info['gender']+'_'+str(info['age'])+date #文档名(含路径)

这里的 ‘%y’ , ‘%m’, ‘%d’, ‘%H%M’ 被称为占位符。所谓占位符,可以理解为先占据一个位置,以便之后添加需要填进去的内容。当需要填入的内容过长或需要进行实时获取时,我们常用占位符来暂时补齐位置。

不同性质的内容需要不同的占位符,常见的占位符包括 ‘%s’ 字符串,’%d’ 整数,’%f’ 浮点数。

当我们获得了文件名以后,使用 with open…as… 进行相应的文档操作。

with open("%s.csv"%(file),'a') as D: #写入表头      D.write('flanker'+','+'center'+','+'RT'+','+'accuracy'+'\n')

简要分析如下:

一般来讲,实验过程中所输出的数据均写入 csv 文档中,csv 文档可以使用 excel 打开并比我们平时用的 xls 要更加简单。在 csv 文档中,不同单元格之间仅仅以逗号作为分隔符来进行分隔。

该段代码的输出效果如下:

除了所介绍的这种简便的方法,对于文件夹、文档的操作还可以使用 python 中的 os 来进行操作,但是 os 对于含有中文的路径不是特别友好,因此这里将不再介绍。

当我们准备好文档后,就可以使用 with open…as… 不断地对文档内容进行写入,只需要与表头相对应即可。

对于我们的例子 flanker 范式来说,我们所要收集的是被试的每次反应的反应时以及正确与否。

3 反应时记录

在 psychopy 的 Window 中,flip() 方法正好含有该方法运行时距离整个程序开始时的时间,因此我们只需要找到反应屏的 flip() 时间与前一个屏的 flip() 时间做差,就可以得到被试的反应时间。

from psychopy import event
for frame in range(fix_times): #注视点呈现      fix.draw()      time0 = Win.flip()      print(time0)            while True:      [s.draw() for s in stims] #刺激呈现      time1 = Win.flip()      if len(event.getKeys(['left','right'])) > 0: break    RT = time1 - time0 #计算反应时

4 正确率记录

我们要获得正确率,记录每一次被试的反应时否正确即可,我们默认正确记为1,错误或未反应记为0。

from psychopy import event
b=0 #设置变量 b 的起始值用于后面控制呈现中止
while True: #呈现刺激      [s.draw() for s in stims]      time1 = Win.flip()                for key in event.getKeys(): #收集按键          if key in ['left', 'right']:              RT = round((time1-time0)*1000) #计算反应时              b=1              break #跳出收集按键的 for 循环      if b==1:          b=0 #b设置回默认          break #跳出呈现的 while 循环        if (stims[2].flipHoriz==True and key=='right') or\(stims[2].flipHoriz==False and key=='left'): #判断按键是否正确      acc=1
else:      acc=0

我们把单纯的监测按键加上了判断,这里的判断方法为判断中间的箭头 stims[2] 是否进行了翻转,如果发生了翻转那么呈现出来的是 →,则被试反应为 ‘right’ 时为正确反应,反之亦然。

同时设置变量 b 以控制跳出呈现屏。

到此,我们获得了每个试次的被试反应时以及其判断正确与否的情况,我们下面只需要将其输出到文档即可,同样可用with open。

with open("%s.csv"%(file),'a') as D:      D.write(trial[0]+','+trial[1]+','+str(RT)+','+str(acc)+'\n')

如此,我们完整的 flanker 范式也就完成了,其输出效果如下:

5 完整代码展示

最后我们附上完整代码:

# -*- coding: utf-8 -*-
"""
The demo of flanker
@author: A Mei
"""
from psychopy import visual, event, gui, core
import time, random    #导入#设置gui
info = {'observer':'01_xxx','gender':['m','f'],'age':18}
dlg = gui.DlgFromDict(info, title='flanker', order=['observer','gender','age'])
if dlg.OK:        pass
else:        core.quit()    #设置数据文档
date = time.strftime("_20%y_%m_%d_%H%M", time.localtime())  #设置文件
file = 'data/'+info['observer']+'_'+info['gender']+'_'+str(info['age'])+date
with open("%s.csv"%(file),'a') as D:        D.write('flanker'+','+'center'+','+'RT'+','+'accuracy'+'\n') #设置窗口、注视点、结束语
Win = visual.Window((1024,768), color=(128,128,128), fullscr=False, units='pix',colorSpace='rgb255')
fix = visual.TextStim(Win, text='+', color='black', height=50,bold=True)
endPrompt = visual.TextStim(Win, text='实验结束,谢谢!', color='black', height=60)    #设置各部分呈现时间
Rate = 60
Dura = 1000/Rate
fix_Dura = 300
blank_Dura = 500
fix_times = int(round(fix_Dura/Dura))
blank_times = int(round(blank_Dura/Dura))    #设置自变量
var = []
for flanker in ['left', 'right']:     for center in ['same','diff']:            var.append([flanker, center])
random.shuffle(var)    #设置刺激位置
sites = []
for site in range(5):        sites.append((-100+50*site,0))    #开始循环
a = 0
b = 0
for trial in var:        a+=1        #设置是否翻转    stims = []        for stim in range(5):                        if (trial[0] == 'left' and trial[1] == 'diff' and stim == 2) or\(trial[0] == 'right' and trial[1] == 'diff' and stim != 2) or\(trial[0] == 'right' and trial[1] == 'same'):                Horiz = True            else:                Horiz = False            #定义箭头                arr = visual.TextStim(Win, text='←', color='black', height=50, pos=(-200+100*stim,0),flipHoriz=Horiz, bold=True)            stims.append(arr)        #呈现注视点    for frame in range(fix_times):            fix.draw()            time0 = Win.flip()        #呈现刺激并收集反应时            while True:            [s.draw() for s in stims]            time1 = Win.flip() for key in event.getKeys():                if key in ['left', 'right']:                    RT = round((time1-time0)*1000)                    b=1                    break            if b==1:                b=0                break        #判断被试反应是否正确        if (stims[2].flipHoriz==True and key=='right') or\(stims[2].flipHoriz==False and key=='left'):                acc=1        else:            acc=0        #呈现空屏            for frame in range(blank_times):            Win.flip()        #写入数据        with open("%s.csv"%(file),'a') as D:         D.write(trial[0]+','+trial[1]+','+str(RT)+','+str(acc)+'\n')        #呈现结束语        if a==len(var):            while True:                endPrompt.draw()                Win.flip()                if len(event.getKeys()) > 0: break            Win.close()

到现在,我们的 psychopy 系列就要告一段落了。虽然相较于 builder(类似e-prime),coder 更为繁琐,难度也略大。但是其精确性与自由性是 builder 无法比拟的。

当然,本系列只是以实现想要的功能为目的,因此并没有介绍特别多的方法。同时,如果想要比较熟练地进行 psychopy 程序的编写,大量的练习是必不可少的。

因此,感兴趣的同学可以以本系列为入门,在掌握本系列所介绍的基础知识前提下掌握更多 python,psychopy 的方法,从而可以更好地应对不同的实验范式要求。

6 系列课程的总结

至此,我们已经学习了Psychopy入门、数据类型与运算符、条件与循环、flanker范式的完整编程、实验数据的收集与处理。

基本学完了 Python 在 Psychopy 中需要用到的大多数知识,虽然难度不是很大,但是比较繁杂,建议通过练习以熟悉这些基本的语句和方法。

PS:本文首发于微信公众平台行上行下,微信后台回复关键词“psychopy第4期”即可获得所述的资料及代码啦!

作者:阿槑

排版:喵君姐姐

参考文献:

Eriksen, B. A., & Eriksen, C. W. (1974). Effects of noise letters upon the identification of a target letter in a nonsearch task. Perception & Psychophysics, 16(1), 143-149.

Psychopy | 第4期:实验数据的收集与处理相关推荐

  1. 《统计学》学习笔记之数据的收集

    鄙人学习笔记 文章目录 数据的收集 数据的来源 调查数据 数据的误差 数据的收集 数据的来源 数据的间接来源 如果与研究内容有关的原信息已经存在,我们只是对这些原信息重新加工.整理,使之成为我们进行统 ...

  2. ai伪造论文实验数据_5篇有关AI培训数据的基本论文

    ai伪造论文实验数据 Many data scientists claim that around 80% of their time is spent on data preprocessing, ...

  3. Psychopy | 第2期:从Stroop看条件与循环

    Psychopy | 第2期:从Stroop看条件与循环 1 相关概念的简单引入 2 条件分支结构的介绍 3 两种循环结构的介绍 4 Stroop代码详细讲解 5 系列课程的总结 Hello, 这里是 ...

  4. 统计学(第七版)第二章 数据的收集

    2.1数据的来源 (1)数据的直接来源:调查数据和实验数据 (2)数据的间接来源 2.2 调查方法 (1)概率抽样:也称随机抽样,是指遵循随机的原则进行的抽样,总体中的每个单位都有一定的机会被选入样本 ...

  5. 精艺熔炼,笃行致远——美和易思34期大数据技术师资项目成功举行

    近日,"精艺熔炼•笃行致远"--2019年美和易思第34期大数据师资项目训练在公司总部成功举行,来自云南.重庆.贵州.广西.山东.河北.陕西.安徽.湖南.湖北等全国各地区的18所美 ...

  6. R语言统计学DOE实验设计:用平衡不完全区组设计(BIBD)分析纸飞机飞行时间实验数据...

    全文链接:http://tecdat.cn/?p=31010 平衡不完全区组设计(BIBD)是一个很好的研究实验设计,可以从统计的角度看各种所需的特征(点击文末"阅读原文"获取完整 ...

  7. python 物理实验_基于Python和梯度下降算法的物理实验数据一元线性拟合方法

    基于 Python 和梯度下降算法的物理实验数据一元线性拟 合方法 关毅铬 ; 程敏熙 [期刊名称] < <物理通报> > [年 ( 卷 ), 期] 2019(000)010 ...

  8. matlab物理实验数据处理,利用Matlab对物理实验数据进行处理

    利用Matlab对物理实验数据进行处理 李凌云;王海军;韩之乃 [期刊名称]<南京晓庄学院学报> [年(卷),期]2005(021)005 [摘要]本文以热电偶的定标实验.二极管伏安特性实 ...

  9. c语言一元线性回归方程程序,C语言编程对实验数据进行一元线性回归处理

    1997年第3期 云南化工 55 计算机应用 C语言编程对实验数据进行一元线性回归处理 杨继红 尹家元 沈 勇 (云南大学化学系 昆明650091) 摘 要 用目前最有发展前景的C语言编程处理分析实验 ...

最新文章

  1. 【GDKOI2016Day1T1-魔卡少女】【拆位】线段树维护区间内所有连续子区间的异或和...
  2. python代码图片头像_Python帮你微信头像任意添加装饰别再@微信官方了
  3. Windows XP Ghost系统安装
  4. 我的编程成长之路——python初体验
  5. 超级详细的教程 一步步教你Vue项目中使用axios如何进行参数拼接
  6. java 线程强制停止线程_java多线程之停止线程
  7. 16年的大数据经验,为了搞定数字化转型,我和老板做了个赌注
  8. bagging算法_Bagging与随机森林算法及其变种
  9. 微信小程序微商城(一):https框架搭建并实现导航功能
  10. 计算机组成原理课程设计(附完整项目)
  11. linux在文件夹压缩,在linux下如何将文件夹压缩成.tgz文件
  12. 生活娱乐 360安全卫士和QQ大战
  13. python3识别图中的文字_Python3调用百度AI识别图片中的文字功能示例【测试可用】...
  14. 在职场遇到一个总是说话带刺的同事怎么相处?
  15. 满足于一种廉价的幸福?
  16. python time模块以秒计时保留两位小数,格式化时间戳
  17. 【超详细】如何从数据库取出数据,动态填充html
  18. 神经网络系统理论与实践,神经网络系统理论基础
  19. The cycles per degree
  20. 图片英文翻译成中文转换器-中文翻译英文软件

热门文章

  1. Git 详解及常用命令
  2. U盘目录穿越获取车机SHELL(内含模拟环境可上手实践)
  3. Redis学习之路(八)封装Redis工具类
  4. win7旗舰版64位降32位的方法步骤
  5. 支持向量机分类示例python_分类算法-支持向量机 SVM
  6. Nordic nRF5 SDK 学习笔记之七, 功耗评估及电源优化
  7. 错误:Parameter 0 of method sqlSessionFactory in MyBatisConfig required a bean of type ‘javax.sql.DataS
  8. 2020全国大学生数学建模C题
  9. 转载 用来自己学习的
  10. 计算图的Node centrality