本ページでは,jsPsychを用いた認知課題の作成をRstudioで行う方法について解説をします。以下では,簡単なストループ課題を作ってみて,jsPsychでの課題作成方法を学びます。ストループ課題を作る準備ストループ課題に限りませんが,認知課題をプログラミングする場合に,いきなりそのままプログラムを書くのは避けたほうが良いです。私が認知課題を作る時にやっている普段やっていることを整理すると以下のような感じになります。課題の情報を整理する課題の設計図を作る教示と課題のメインブロックを最もシンプルな形で作る課題のメインブロックに機能を追加をするメインブロック以外のブロックを追加していく1~5にまっすぐ進むわけでなく,試行錯誤しつつ,行きつ戻りつしながら進みます。初学者にとって大切に思うのは,1と2の課題の情報を整理して紙などに課題の設計図を書いてみること,いきなり実際に行う課題を作ろうとするのではなくメインブロックを一番シンプルな形(例えば,ストループ課題の場合は,文字を画面に出すことです)で作ることです。その後で,徐々に機能を追加していきます。完成形を作ろうとしなくても良いです。課題の情報を整理するまずストループ課題の情報を整理します。ストループ課題は,以下のように文字の意味と文字の色が同じだったり違ったりすることで,意味と色の情報が干渉しあうストループ効果を調べる課題です。典型的には,以下の左のように意味と色が一致な刺激や右のように不一致な刺激を呈示し,意味ではなく色に関して反応するように求めます。その時の反応時間を計測して,一致条件よりも不一致条件の方が反応時間が長い場合にストループ効果が示されたとします(不一致条件では,色の判断に意味の情報が干渉するので遅くなる)。4つの刺激を使って,一致条件と不一致条件を作って,キーボードのボタン押しによって,反応時間を測定することにしましょう。課題の設計図を作るそれではストループ課題の設計図を作ってみましょう!私はなにかプログラムを書くときは,必ず全体像を紙に書き出してから作業を始めます。がむしゃらにトライアンドエラーを繰り返すのも大切ですが,まずは自分が作ろうとしているものの全体像を紙に書き出します。スライドで清書したものです。紙などに書き出す習慣をつけましょう)。左側の図にあるように,開始メッセージ(画面に「ようこそ!」みたいなのを出す),フルスクリーンにする(ブラウザの一部で実験課題をすると集中できないのでフルスクリーンで実施します),課題の教示(課題について説明する文書です),課題のメインの部分(ストループ刺激を呈示して,反応を取得する。これを刺激の数だけ繰り返す),終了メッセージ(課題終了のメッセージです。今回は正答率などのフィードバックもすることにします)の順番になります。ここで大切なのは,実験課題は全体で1つというよりは,いくつかのブロックから構成されているとうことです。全体をいきなり作るのは結構たいへんですが,一部のブロックだけ作るなら頑張れるかもしれません。やって小さなブロックをいくつか作って,それをLEGOブロックみたいに組み合わせることで全体を作っていきます。いう小さなブロックに分けて作っていくやり方を意識するようにしてみてください。図の左側のように刺激の組み合わせも書き出します。赤・緑・黄・青の4種類があるので,色4種と文字4種で16通りがあります。1,6,11,16が一致条件,それ以外は不一致条件ですね。上の図のような順番で刺激を呈示すると,参加者は予想できてしまいますので,刺激呈示する際には,ランダム化して呈示します。紙に書き出すとか古臭いと思うかもしれませんが,こういう地味な作業をすることが漏れのない設計に繋がります。実験課題などのプログラミングだけでなく,理論やモデルの理解の際にもこういう習慣を身に着けておくと良いです。教示と課題のメインブロックを最もシンプルな形で作るさて,設計図を見るといくつかあるブロックの中で一番メインのプロックは刺激呈示をして反応を取得するブロックです。これを最もシンプルな形で作るとすれば,反応の取得はおいておいて,まずは刺激を呈示するブロックを作ることになります。いうことで,以下では,早速,教示と課題のメインブロックの刺激呈示部分を作ることとにします。教示も作るかというと,教示は一般的には簡単につくれることが多いのと,教示は参加者向けのものではありますが,上記の設計図と同じ働きをして,課題の全体像を意識することにつながります。教示を呈示する早速,教示を作ってみましょう。以下のような内容を画面に呈示して,説明をします(<>内はその前の単語の色を指定しています)。以下のような色のついた単語を見ていただきます。青<赤色>単語の意味は無視して,それぞれの単語の「色」を以下のキーボードのキーを押して回答してください。左手の人差し指と中指でdとf,右手の人差し指と中指でjとkを押してください。Markdownファイルを新規に作成して,以下の内容を打ち込みます(基本的にこちらと同じです)。author名はご自身の名前に変更ください。教示は,以下のように,“html-keyboard-response”を使って呈示します。stimulusってところで呈示する内容を指定します。post_trial_gapは,教示出してから次に移行する間の時間です。ここでは,1000msに設定します。教示の説明部分は,pで挟まれた文章がありますが,これは,文字の大きさを変えたり,左揃えにする際に必要になります。spanで挟まれた文章は,文字の色を変えることができます。教示の設定を書く,instructionができたら,timelineを作って,instructionにpushします。最後に,jsPsych.init()で,課題をtimelineにそって走らせましょう。{jsPsych.data.displayData();}を追加しています。これを追加しておくと,課題の終了時に呈示した刺激や反応などが表示されますので,便利です。ここまでできたら,「Knit」を押して,教示を出してみましょう。基本の教示ブロックが完成しました。ストループ刺激を呈示するさて,次はメインのブロックです。メインのブロックでは,ストループ刺激(色のついた文字)を呈示し,その反応を取得します。反応取得までいくとごちゃごちゃしますので,まずは刺激を順番通りに呈示するだけにします(ランダム化しない)。段階を踏むのは遠回りに思えるかもしれませんが,いきなり色々と入れ込むとわけわからなくなるので,やめておきましょう。以下のように,stimuliの中に16個のストループ刺激(stimulus)を用意します。styleで色やフォントサイズの指定をしています(最初のstimulusは赤色の60ポイントの「赤」という文字ですね)。上の課題の設計図のところで作成したように,刺激を順番に指定します。これで,stimuliには,16個の色と文字の異なる刺激が準備できました。variablesの詳細は,こちらを参照ください)。教示をhtml-keyborad-responseで呈示しましたが,それは1回だけでした。jsPsychでは,instructionや以下のstroopといったオブジェクトの中にもtimelineを作ることができます(なんだかよくわからないと思いますが,stroopの中に16個の刺激を呈示するtimelineを持つことができて,これができるとコードがすっきりします)。={の後ろにtimeline:[{}]を作ります。promptを指定します。timeline:[{}]の後ろに,timeline_variablesで先程作ったstimuliを指定します。jsPsych.timelineVariable(‘stimulus’)と指定します。このように,timeline_variablesに16個のストループ刺激が入ったstimuliを指定したので,timeline:[{}]のstimulusをstimuliのstimulusを使って変更しつつ16回呈示します。分かりにくいですが,呈示したい刺激のリストを作って,それをtimeline_variablesに入れます。すると,jsPsych.timelineVariable()を使って,その前のtimeline内の内容を変更することができます(今回の場合は,stimulusを施行ごとに変更しています)。これを上手く使うと,シンプルかつ柔軟に課題を作ることができます。これで,作成したリストの順番でストループ刺激が呈示されるかと思います。演習課題1今回は漢字で刺激を呈示しましたが,「赤」ではなく,「あか」のようにひらがなで刺激を呈示してみましょう。デバッグについてさて,ここまで上手く作れたでしょうか?なかなか動かなくて困った人もいるかもしれません。RmdファイルからHTMLは作れるけど,ちゃんと動作しないことも多いです。その時に,以下の方法でバグを探すと良いです。上手く動作しないときは,タイトルと作者だけ表示されることが多いですが,その上手く動いていないHTMLファイルをブラウザ(Chrome)で開きます。右クリックをしてメニューをだして,Inspectをクリックします。すると以下の右側のような画面がでてくるので,そのConsoleあたりをみるとエラーが出ています。エラーをみると,コードのどこに問題があるか確認できます。これにしたがって,コードを修正していくと,ちゃんと走るかと思います。課題のメインブロックに機能を追加をするメインブロックの刺激呈示はできましたが,いくつかやり残したことがあります。ここでは,提示する刺激のランダム化と反応の取得をします。trueを入れればできます(ランダム化の詳細は,こちらを参照ください)。true};ただ,実際の課題は,刺激リストを数回繰り返すことも多いかと思います。その場合は,sampleを使います。sampleでは,以下のような方法があります。variablesから特定の数ランダムにサンプルする(数はsizeで指定する)。同じアイテムが何度も選ばれることがある。variablesから特定の数ランダムにサンプルする(数はsizeで指定する)。それぞれのアイテムが1回だけ選ばれる。variablesのアイテムがランダムに特定の回数サンプルされる(繰り返しの数はsizeで指定する)。今回の場合は,ストループ刺激のリストをランダムに2回(リストを2周する)呈示するので,fixed-repetitonsが適していますね。2}を追加しましょう。これで,simuliリストのアイテムを2回ランダムに呈示します。今回作成しているストループ課題では,キーボードのタイピングで反応を取得します(d,f,j,k)。Script内で処理する際に文字よりも数字のコードのほうが便利です。そこで,キーボードのそれぞれ割り振られたコード使います。それぞれのキーボードにどういうコードが割り振られているかは,https://keycode.info/で簡単に確認できます。今回使う,d,f,j,kの場合は,以下のようになります。70この情報も踏まえて,stimuliのリストに手を加えます。先程は,stimulusのみを書いていましたが,その後の正誤判定のためや解析で使えるように,dataにno(項目番号),stim_type(一致か不一致か),correct_key_press(正答のキーボードのキーのコード)を以下のように追加します。}];そして,以下のようにstroopブロックに追加をしていきます。[“d”,“f”,“j”,“k”]をおいて,stroopブロックで使う選択肢を指定する。刺激呈示or反応後にすぐに次の刺激がでてくるとまずいのでpost_trial_gapでブランクをいれます。500;}として,ランダムになるようにします(Math.random()は0~1の間の値をランダムにとるので,最小500ms,最大2000msになります)。以下が設定できたら,一度走らせてみましょう!それでうまくいっていれば,キーボードで反応をすると,最後にその選択が記録されます。2}};さて,その後の解析なども含めて,反応の正誤判定をしておくと便利です。stimuliのリストのアイテムの正答反応を意味するcorrect_key_pressと実際の反応が記録されdataに保存されたdata.key_pressとが一致していれば,その試行の反応は正答です。それをif文を使って表現すると以下になります。基本的にはcorrectは0としておいて,もしアイテムの正答反応と反応が一致したら,correctを1にして,dataに保存します。function()を使います。jsPsych.timelineVariable(‘data’)も指定します。すると以下のようになります。2}};走らせてみて,最後に表示される結果から,ちゃんと正答した時にcorrectが1になっていますか?それができていれば,メインブロック部分は完成です。演習課題2上記では繰り返しが2回でしたが,繰り返しが3回のストループ課題を作ってみましょう。メインブロック以外のブロックを追加していくさて,メインブロックは完成したので,残りのブロックを追加していきます。課題が始まった時に表示されるウェルカムメッセージとフルスクリーンで実施するための教示などのブロックを追加して,最後に終了の教示(今回はデブリーフィングとして,結果のフィードバックをする)を表示します。最初にウェウカムメッセージとして以下のwelcomブロックを追加します。"<p>キーボードのキーをどれか押して,開始してください</p>"};timelineにもwelcomを追加します。[];timeline.push(welcome);timeline.push(instructions);timeline.push(stroop);さらに,認知課題をブラウザで実行する場合は,全画面表示で行う必要がありますので(気が散るので),そのブロックを追加します。全画面に関しては,jsPsychのプラグインにjspsych-fullscreen.jsというものがあるので,それを活用できます。jspsych-fullscreen.jsは英語表記なので,日本語化したものを作成しています。jspsych-fullscreen_jp.jsをクリックして,ダウンロードして解凍したjspsych-fullscreen_jp.jsをjsPsychのpluginsフォルダ内に置いてください。その上で課題のRmdの最初の方に,tags$script(src=‘jspsych-6.1.0/plugins/jspsych-fullscreen_jp.js’)を追加ください。library(htmltools)tagList(tags$script(src='jspsych-6.1.0/jspsych.js'),tags$script(src='jspsych-6.1.0/plugins/jspsych-html-keyboard-response.js'),tags$script(src='jspsych-6.1.0/plugins/jspsych-fullscreen_jp.js'))最後に,timelineのwelcomeの次にfullscreenのブロックをプッシュします。これで,ウェルカムメッセージが表示されて,全画面表示ができるようになっていると思います。デブリーフィングいよいよ最後です。最後に,終了時の教示(今回は結果のフィードバックをする)のブロックを追加します。html-keyboard-responseを使って画面を表示しますが,stimulusにて,dataから結果を引っ張ってきて,一致試行と不一致試行の平均反応時間を計算しています。ややこしそうですが,dataからfilterで絞り込みをかけて,countなどで数えるという単純な作業をしているだけになります。その計算結果をいれこんだ文章をつくって表示しています。"<p>あなたの正答率は,<strong>"+accuracy+"%</strong>でした。"ms</strong>でした。"ms</strong>でした。"<p>キーボードのキーをどれか押すと画面に結果の記録が表示されます。ブラウザを閉じて終了してください。ご参加ありがとうございました。}};上記のdebriefブロックができたら,timelineにdebriefをpushします。