最初の実験を作ってみよう―サイモン効果 ======================================================================= 実験の手続きを決めよう ------------------------------- この章では、最初の実験としてサイモン効果の実験を作ってみましょう。サイモン効果について詳しい解説は認知心理学の教科書などを参考にしていただくとして、ここでは実験の手続きを説明します。 .. _fig-simon-effect: .. figure:: fig03/simon-effect.png :width: 80% サイモン効果の実験概要。実験参加者は刺激の色に対応するキーを出来るだけ速く正確に押すように求められます。スクリーン上の刺激の位置と反応するキーの位置関係が反応の速さや正確さに及ぼす影響を検討します。 :numref:`fig-simon-effect` をご覧ください。実験参加者に与えられた課題は、PCのスクリーン上に提示された刺激の色に応じて、PCのキーボードのキーを指定された指で押すことです。参加者はスクリーン中央の十字(固視点)に視線を向けて、刺激が出現するのを待ちます。刺激は赤色または緑色の円で、固視点の右側または左側のどちらかに出現します。参加者は刺激の色が赤色であれば左手の人差し指でxのキー、緑色であれば右手人差し指で / (スラッシュ)のキーを出来るだけ速く、間違わないように押さないといけません。左側に赤色の刺激が出現した場合と右側に緑色の刺激が出現した場合には刺激と反応する指が同じ側になりますが、それ以外の場合は刺激が出現した側と反対側の指で反応しないといけません。刺激が提示される位置と反応する指の関係が反応の速さや正確さにどのように影響するかを確認しようというわけです。 さて、実際に実験を作成するためには、 :numref:`fig-simon-effect` の内容よりもっと詳細に手続きを決定する必要があります。 :numref:`fig-simon-effect-procedure` は刺激提示スクリーンの時間的な変化を図示したものですが、このように書いてみると :numref:`fig-simon-effect` の内容ではx1からx5の値が決まっていないことがわかります。何かの文献に基づいて実験を作成しているのであれば文献に書かれている手続きを熟読して値を決めることになるでしょう。この章では、あまり内容を高度にし過ぎないためにあらかじめ以下のように値を決めることにします。 - x1 固視点の大きさは縦横50pix。 - x2 試行が始まってから刺激が出現するまでの時間は1.0秒。 - x3 固視点の中心から刺激の中心までの距離は400pix。 - x4刺激の直径は100pix。 - x5 刺激の位置(2か所)と色(2種類)の組み合わせで合計4種類の刺激に対して25試行ずつ、合計100試行。 .. _fig-simon-effect-procedure: .. figure:: fig03/simon-effect-procedure.png :width: 80% サイモン効果実験の手続き。実際に実験を作成するためにはx1からx5の値を決定する必要があります。 なお、刺激はスクリーン中央からある程度離れていた方がよいので、解像度1920×1080などの解像度が高いモニターを使用している場合は、x3の値を大きくした方がよいです(例えば800pix)。同様に、解像度が高いモニターでは刺激の直径(x4)が100pixでは小さすぎて見えにくいかもしれません。この辺りの数値は各自の実行環境に応じて変更してください。以下の解説では、x3は400pix、x4は100pixであるとします。 実験を作成する前にもうひとつ確認して置きたいのは、この実験において「試行毎に変化する値」は何かという点です。 :numref:`fig-simon-effect` から明らかなように、刺激の色(赤or緑)と刺激の位置(右or左)は試行毎に変化します。刺激の色が変化するという事は、それに対応して正解となるキー(x or /)も変化することに注意しましょう。 さて、それではいよいよ実験の作成を始めましょう。なお、今回作成する実験のpsyexpファイル名は、第3章の実験ということでexp03.psyexpとすることにします。 視覚刺激を配置しよう --------------------------------- 第2章では視覚刺激の大きさや位置、色の指定などについて学んだのですから、まずは刺激の作成から始めましょう。まず、刺激の円はPolygonコンポーネントで頂点の数を大きくすることで表示できます。小さい円であれば頂点が20ほどあれば十分ですが、大きな円を提示する場合は40や80といった値にする必要があるでしょう( :numref:`fig-drawing-circle` )。頂点数を大きくしすぎるとPCが行う表示処理の負担が大きくなるため、むやみに大きな値にするのはお勧めできません。刺激の位置と色は試行毎に変化しますが、まだその方法は解説していませんのでひとまず[400, 0]の位置に赤色で表示することにしましょう。Polygonコンポーネントをひとつルーチンに配置し、以下のように設定してください。 - **名前** にstimulusと入力する。 - **頂点数** に40と入力する。 - Fill colorにred、Line colorにNoneと入力する。 - **サイズ [w, h] $** に[100, 100]と入力する。 - **位置 [x, y] $** に[400, 0]と入力する。 - 実験設定ダイアログを開いて **単位** をpixにしておく。 .. _fig-drawing-circle: .. figure:: fig03/drawing-circle.png :width: 60% polygonコンポーネントの **頂点数** を増やすと円が描けます。 続いて固視点ですが、十字を表示するにはTextコンポーネントを用いて「+」を一文字だけ表示するのが最も簡単です。しかし、Textコンポーネントの場合 **文字の高さ $** に50pixを指定しても表示される十字のサイズはスクリーン上で縦横50pixにはなりません。文字は上下左右に余白があるのですから当然です。より正確に刺激の大きさを指定するためには、Polygonコンポーネントで長方形を二つ重ねて描くなどの工夫が必要です。ここでは幅5pix、高さ50pixの長方形と幅5pix、高さ50pixの長方形を重ねて十字を描くことにしましょう。新たにPolygonコンポーネントを2つルーチンに配置し、以下のように設定してください。 - **名前** にそれぞれcross1、cross2と入力する。 - **サイズ [w, h] $** に[5, 50]と入力する。 - cross2の **回転角度 $** に90と入力する。 続いて提示時間の設定について考えましょう。試行開始時には固視点のみがスクリーン上に提示されていて、試行開始1.0秒後に刺激が提示されるのですから、固視点(cross1およびcross2)の **開始** は「時刻 (秒)」で0.0、刺激(stimulus)の **開始** は「時刻 (秒)」で1.0にすればよいでしょう。固視点、刺激ともにキーが押されるまでずっと提示されるのですから、 **終了** はどちらも空白にしておきましょう。 さて、ここまでの作業を終えると、ルーチンペインには :numref:`fig-put-stim-cross` 上のように3つのPolygonコンポーネントが並んでいるはずです。コンポーネントの順番はこの通りでなくても構いません。そして実験を実行すると :numref:`fig-put-stim-cross` 下のようにスクリーンに刺激が提示されることを確認してください。ここまでの記述で分からないことがあったら第2章を復習してください。ここまで確認できればいよいよキーボードを用いて実験参加者の反応を検出する方法を学びましょう。 .. _fig-put-stim-cross: .. figure:: fig03/put-stim-cross.png :width: 80% 視覚刺激用のPolygonコンポーネントの配置と実行確認。 チェックリスト - 試行中にキー押しが有効となる時間帯を指定できる。 - Textコンポーネントを用いて十字をスクリーン上に提示することが出来る。 - Polygonコンポーネントを用いて十字をスクリーン上に提示することが出来る。 キーボードで反応を検出しよう -------------------------------------------- Builderからキーボードを利用するには、コンポーネントペインのResponseというカテゴリに含まれるKeyboardコンポーネントをルーチンペインに配置します。Keyboardコンポーネントのアイコンは :numref:`fig-keyboard-properties` 左に示してあります。PolygonやTextコンポーネントを配置する時と同じように、コンポーネントペインのKeyboardコンポーネントのアイコンをクリックしましょう。すると :numref:`fig-keyboard-properties` のKeyboardコンポーネントのプロパティ設定ダイアログが開きます。 .. _fig-keyboard-properties: .. figure:: fig03/keyboard-properties.png :width: 80% Keyboardコンポーネントのプロパティ設定ダイアログ。上半分はPolygonコンポーネントなどと同一です。 上半分の **名前** 、 **開始** や **終了** は、第2章で扱ったコンポーネントと同様に、名前をつけたりコンポーネントが有効となる時間を指定したりするために使用します。視覚刺激の場合、「有効となる時間」はスクリーン上に表示されている時間に対応しましたが、Keyboardコンポーネントの場合はキー押し反応を受け付ける時間に対応します。例えば今回の実験の場合、刺激がスクリーン上に出現する前に押されたキーは無視するべきですから、試行開始1.0秒経過するまでKeyboardコンポーネントは無効にするべきです。また、今回は参加者が反応するまで待ち続けますが、実験によっては3秒以内に反応できなかったら強制的に次の試行に移るといったこともあるでしょう。 **開始** と **終了** を適切に設定することによってこういった実験を実現することが出来ます。 続いて **Routineを終了** ですが、この項目にチェックが入っていれば、キーが押されると同時に他のコンポーネントがまだ有効であっても強制的にルーチンを終了します。今回はこの機能を利用して「参加者がキーを押すまで刺激を提示し続ける」という動作を実現します。仮に「30秒間スクリーンを注視し、刺激が無作為な時間間隔で複数回スクリーン上に出現する度に出来るだけ速くキーを押す」といった実験の場合はキーが押されてもルーチンを中断してはいけません。このような実験の場合は **Routineを終了** のチェックを外しておきます。 さらに続いて **検出するキー $** ですが、ここにはBuilderがキー押しを監視するキーの名前を列挙します。 :numref:`fig-keyboard-properties` に示すように初期状態では'y', 'n', 'left', 'right', 'space'と入力されています。これは順番にアルファベットのYキー、Nキー、カーソルキーの「←」キー、「→」キー、スペースキーを表すキー名です。必ず半角文字で入力すること、キー名の前後にシングルクォーテーションまたはダブルクォーテーション記号を入力すること、キー名の間はカンマで区切ることが重要なポイントです。ここに書かれたキー以外が押された場合は、Keyboardコンポーネントが有効な時間帯であっても無視されます。参加者が反応に使用するキーのみを書くことによって、参加者が誤って無効なキーを押してしまってルーチンが終了してしまうことを防ぐことができます。心理学実験ではあまり無いことだと思いますが、すべてのキーを有効する必要がある場合は **検出するキー $** を空白にしてください。 問題は自分が使いたいキーのキー名を何と書けばよいのかですが、一般的な日本語キーボードであれば :numref:`tbl-ja-key-names` に示すキー名が使えるはずです。日本語キーボードではShiftキーを押しながら1キーを押すと ! 記号を入力できますが、PsychoPyは ! というキーが押されたとは判断せず、あくまでShiftと1キーが押されたと判断しますので注意してください。 もうひとつ注意しないといけない点は、キーボードによっては特殊キーの左右を区別しないなどのクセがある点です。例えば :numref:`tbl-ja-key-names` では左シフトキーと右シフトキーにそれぞれlshift、rshiftという名前が割り当てられていますが、使用しているキーボードが左右どちらのキーを押してもlshiftというキー名を返すように作られている場合があります。自分が使用する予定のキーボードがどのようなキー名を返すのか確認したい、Windows用キーボードのWindowsキーやMac用キーボードのCommandキーがどのような名前を返すのか確認したいといった場合は、キー名を表示させるBuilderの「実験」を作成すると便利です。作成にはずっと先の章で取り上げる予定のテクニックが必要になりますので、ここでは扱わず :ref:`topic-how-to-confirm-key-name` に記しておきました。 .. _tbl-ja-key-names: .. csv-table:: 一般的な日本語キーボードで使用できるキー名。 :header: "キー名", "対応するキー", "キー名", "対応するキー" **f1**, F1, **minus**, \- **f2**, F2, **asciicircum**, ^ **f3**, F3, **backslash**, \\ **f4**, F4, **bracketleft**, [ **f5**, F5, **bracketright**, ] **f6**, F6, **semicolon**, ; **f7**, F7, **colon**, : **f8**, F8, **comma**, "," **f9**, F9, **period**, . **f10**, F10, **slash**, / **f11**, F11, **at**, @ **f12**, F12, **return**, Enterキー **num_0**, 0 (テンキー), **1**, 1 **num_1**, 1 (テンキー), **2**, 2 **num_2**, 2 (テンキー), **3**, 3 **num_3**, 3 (テンキー), **4**, 4 **num_4**, 4 (テンキー), **5**, 5 **num_5**, 5 (テンキー), **6**, 6 **num_6**, 6 (テンキー), **7**, 7 **num_7**, 7 (テンキー), **8**, 8 **num_8**, 8 (テンキー), **9**, 9 **num_9**, 9 (テンキー), **0**, 0 **num_add**, \+ (テンキー), **a**, A **num_subtract**, \- (テンキー), **b**, B **num_multiply**, \* (テンキー), **c**, C **num_divide**, / (テンキー), **d**, D **num_decimal**, . (テンキー), **e**, E **left**, ←, **f**, F **down**, ↓, **g**, G **right**, →, **h**, H **up**, ↑, **i**, I **escape**, ESCキー, **j**, J **pageup**, PageUpキー, **k**, K **pagedown**, PageDownキー, **l**, L **end**, Endキー, **m**, M **home**, Homeキー, **n**, N **delete**, Delキー, **o**, O **insert**, Insキー, **p**, P **backspace**, バックスペースキー, **q**, Q **tab**, タブキー, **r**, R **lshift**, 左シフトキー, **s**, S **rshift**, 右シフトキー, **t**, T **lctrl**, 左Ctrlキー, **u**, U **rctrl**, 右Ctrlキー, **v**, V **lalt**, 左Altキー, **w**, W **ralt**, 右Altキー, **x**, X , , **y**, Y , , **z**, Z 説明も長くなってきましたので、その他の項目は後で解説することにして、まずは動作を確認してみましょう。Keyboardコンポーネントのプロパティ設定ダイアログで以下のように設定してください。 - **開始** を「時刻 (秒)」にして1.0と入力する。 - **終了** を空白にする。 - **Routineを終了** にチェックが入っていることを確認する。 - **検出するキー $** に 'x', 'slash' と入力する。 - その他の項目は初期設定のままにする。 .. _fig-keyboard-settings: .. figure:: fig03/keyboard-settings.png :width: 80% Keyboardコンポーネントの設定例。 これらの設定が済めばKeyboardコンポーネントのプロパティ設定ダイアログとルーチンペインは :numref:`fig-keyboard-settings` のようになるはずです。これで、xまたは / キーが押されたことを検出してルーチンを終了させることが出来るようになりました。以下のことを必ず確認しておいてください。 - 刺激(赤い円)が出現した後にxキーまたは / キーを押すと刺激提示が終了すること。 - 刺激(赤い円)が出現する前にxキーまたは / キーを押しても刺激提示が終了しないこと。 - xキー、 / キー、ESCキー以外のキーを押しても効果がないこと(ただしWindowsキーなどOSにより特殊な役割を持つキーは除く)。 キー押しが検出出来たら次はそれをファイルに記録する方法をマスターしたいところですが、それはひとまず置いておいて、次節では刺激の位置や色を変更しながら試行を繰り返す方法を学びます。 チェックリスト - ルーチン実行中にキー押しが有効となる時間帯を指定できる。 - キーが押されると直ちにルーチンを中断するように設定することが出来る。 - 有効とするキーを指定できる。 - すべてのキーを有効にするように設定することが出来る。 条件ファイルを作成しよう ------------------------------------------- 今までは「実験」と言いつつただ静止画像が一回スクリーンに表示されて終了するだけでしたが、本節からいよいよ実験らしくなってきます。Builderでは、条件ファイルと呼ばれるファイルから試行毎の刺激の色や反応に使用出来るキーなどの値を読み込んで設定する機能があります。この機能を用いることによって、今までは不可能だった「刺激の色や位置を変えながら試行を繰り返す」ことが可能になります。条件ファイルの作成方法は何通りかあるのですが、ここではExcelを用いた方法を解説します。第1章で述べたとおり、Excelをお持ちでない方はLibreOffice Calcを代わりに用いることが出来ます。実はBuilderにはExcelやCalcなしでも条件ファイルを作成する機能があるのですが、条件ファイルの保存形式が特殊なので本書ではお勧めしません。この機能については :ref:`builtin-condition-editor` をご覧ください。 では、条件ファイルの作成を始めましょう。Builderを一旦離れてExcelを起動してください。Builderで利用できる条件ファイルをExcelで作成するには、Excelのシートの各列に刺激の色や位置等のパラメータを割り当てて、実験で使用するパラメータの組み合わせを1条件1行で列挙します。 :numref:`fig-edit-conditions-file` を参考にしながら具体的に手順を追っていきましょう。 .. _fig-edit-conditions-file: .. figure:: fig03/edit-conditions-file.png :width: 80% 条件ファイルの作成。 今回の実験では試行毎に刺激の「色」と「位置」が変化します。このように変化していくものそれぞれにExcelの列を割り当てていきます。例えば「色」を1列目、「位置」を2列目に割り当てるとしましょう。このように、条件ファイルを通じて変化させていく値をパラメータと呼びます。この用語は以後頻出しますので覚えておいてください。続いて決めないといけないのは、それぞれのパラメータの「名前」です。人にものを頼む時には「コレをアレに載せといてよ」と言っても通じるかも知れませんが、コンピュータに作業を頼むときには「コレ」や「アレ」を曖昧さなしに示す必要があります。そこで用いられるのが名前です。「刺激の色」と言った時に「刺激」とは具体的にどのコンポーネントを指しているのか、「値を設定する」と言った時に「値」とはどこに記されているものか、といったことをコンピュータにもわかるように示すために、私たちがコンピュータに指示を出す時には、操作や参照の対象となるものすべてに固有の名前をつけなければいけません。「固有の」と断りましたように、異なるものに同じ名前を割り当ててはいけません。第2章でPolygonコンポーネントを複数配置した時に、一つ目のPolygonコンポーネントの **名前** の初期値が「polygon」、二つ目のPolygonコンポーネントの **名前** の初期値が「polygon_2」になっていたのに気付かれた方がおられると思いますが、これはBuilderが二つのPolygonコンポーネントを明瞭に **名前** で区別できるように自動的に異なる名前を割り振ってくれた結果なのです。 Builderで使用できる名前は、「Pythonの変数として使用できる名前」のうち、PsyhcoPyやBuilderでまだ使用されていないものに限られます。具体的には以下の条件を満たす必要があります。 - 1文字目が英文字(A-Z、a-z)であること。アンダーバー( \_ ) も使用できるがアンダーバーから始まる名前は避けた方がよい。英文字の大文字と小文字は区別される。 - 2文字目以降が英文字(A-Z、a-z)またはアンダーバー( \_ )であること。英文字の大文字と小文字は区別される。 - Pythonの正常な動作のために確保されているキーワード(if, else, while, for, from, globalなど)やPsychoPyのモジュール名(core, data, visual, eventなど)、Builderの予約語(expInfo, expName, buttonsなど)は使用できない。以後、記述の簡略化のために両者を合わせて「予約語」と呼ぶ。 一番目と二番目の条件を満たすのはそれほど難しくありませんが、最後の「予約語を使用してはいけない」という条件は厄介です。予約語はPythonやBuilderが正常に動作するようにすでに使用している名前のことであり、かなりの数の名前が予約済みなので覚えるのはあまり現実的ではありません。予約語を避けるのに有効なのが、英小文字から始まる接頭語+アンダーバーという名前を用いるという方法です。例えば自分で決める名前すべて先頭にmy\_ を付けたり、刺激にはs\_、反応にはr\_を付けたりするといったルールを決めておけば、ほぼ確実に予約語を避けることが出来ます。PsychoPy 1.82の時点でこのルールに抵触するキーワード及び予約語はhas_key、key_resp、raw_inputの3つしかありません。Builderを起動中であれば :ref:`topic-test-reserved-names` で述べる方法を用いてBuilderで使用できる名前を判別することが出来ます。また、PsychoPy 1.82.02で定義されている予約語の一覧を付録に付けておきましたので、そちらも参考にしてください。 本題に戻りましょう。今回は刺激の色と位置を変化させる必要がありますので、二つの名前を自分で決める必要があります。上記の名前に使える文字列の制限に加えて、作成中のルーチンペインにすでに配置済みのコンポーネントの **名前** と重複しないように名前を決める必要があります。ここでは色に対応する名前として stim_color、位置に対応する名前としてstim_xposという名前を使うことにしましょう。Excelの1行目にこれらの名前を入力してください。 名前を決めたら、次はそれぞれのパラメータの値を列挙していきます。値はBuilderが理解できるものでなければいけません。例えば「赤」とか「緑」とか日本語で入力してもBuilderは理解できませんので、第2章で覚えたようにredやgreenとか#FF0000、#00AA00などと書かねばなりません。ややこしいことに$[1, 0, 0]などの表記は$を付けずに[1, 0, 0]と書かないといけないのですが、その理由は本章の :ref:`section-modify-stimuli-using-conditionsfile` で説明します。刺激の位置も「右」、「左」ではなく刺激の **位置[x, y] $** にそのまま記入できる値を書く必要があります。 これらの注意点を念頭に置いて、まず刺激の色を入力しましょう。刺激の色は赤または緑ですから、stim_colorにはredとgreenを挙げる必要があります。これらの値を、stim_colorと入力したセルの下へ、空白セルを間に挟まずに並べていきます。続いて刺激の位置ですが、今回の実験では位置のY座標は変化しないのでX座標の値だけを列挙することにしましょう。固視点から刺激への距離を400pixに決めているのですから、左は-400、右は400です。stim_colorと同じようにstim_xposの列に-400、400を縦に並べればよいのですが、今回の実験では「赤」の刺激が「右」と「左」、「緑」の刺激が「右」と「左」で合計4通りの条件があることに注意しなければいけません。条件ファイルでは1行が一つの実験条件に対応しますので、これら4通りの条件がすべて列挙されなければいけません。どうすればよいかというと、stim_colorの列をred, red, green, greenといった具合にredとgreenが2回ずつ出現するように書き換えて、stim_xposに-400、400、-400、400と書けばよいのです( :numref:`fig-writing-conditions` 左)。これですべての条件が挙げられたことになります。この並べ方はBuilderで実験を作成する際には非常に頻繁に用いますのでよく覚えておいてください。なお、「赤色の時は必ず右に、緑色の時は必ず左に刺激が出現する」という実験の場合には2通りしか組み合わせがありませんので、 :numref:`fig-writing-conditions` 右のようにredと400、greenと-400がそれぞれ同一の行に並ぶように書きます。 .. _fig-writing-conditions: .. figure:: fig03/writing-conditions.png :width: 80% パラメータの組み合わせを全て提示するか、特定の組み合わせだけを提示するかによって条件ファイルの書き方が異なります。 今回の実験のパラメータには、刺激の位置と色の他にも「正解となる反応」がありますが、まずは実際に刺激が次々と提示される様子を確認することにしましょう。他のセルに不必要な値が入力されていないのを確認してから、作成したシートをExcelの「ブック(\*.xlsx)」形式で保存してください。以後、この形式で保存されたファイルをxlsxファイルと呼びます。保存するファイル名は、第3章の実験用の条件ファイルという事でexp03_cnd.xlsxとしておきます。LibreOffice Calcを使っている場合は標準ではxlsxファイルとして保存されませんので保存ダイアログの「ファイルの種類」からxlsx形式を選択することを忘れないようにしてください( :numref:`fig-save-conditions-file` )。 これで条件ファイルの準備が出来ました。Builderに戻ってこの条件ファイルを読み込むように実験を拡張しましょう。 .. _fig-save-conditions-file: .. figure:: fig03/save-conditions-file.png :width: 70% 条件ファイルをExcelのブック(\*.xlsx)形式で保存します。Excelの場合は標準でxlsxファイルとして保存されますが、LibreOffice Calcの場合は[ファイルの種類]からxlsx形式を選択する必要があります。 チェックリスト - ExcelまたはLibreOffice Calcを用いて、実験に用いるパラメータを列挙した条件ファイルを作成することが出来る。 - 実験のパラメータを表現するためにPsychoPyで使用できる名前を決めることが出来る。 繰り返しを設定しよう ------------------------------- Excelは一旦終了して、Builderに戻ってください。一度Builderを終了してしまった人はexp03.psyexpを開きましょう。開いたら、ルーチンペインの下のフローペインを見てください。 :numref:`fig-insert-loop` の左上のように、左から右に矢印が描かれていて、矢印の上にtrialと書かれた四角いアイコンが描かれています。フローペインは実験の流れ(フロー)を示しており、左から右へ向かって実験が進行します。trialと描かれた四角はルーチンを示しており、trialルーチンは実験を作成すると自動的に作成されるルーチンです。ここまでの作業で「ルーチンにコンポーネントを配置する」という作業を何度も繰り返しましたが、これらの作業はいずれもtrialルーチンに対して行っていたのです。 .. _fig-insert-loop: .. figure:: fig03/insert-loop.png :width: 80% 繰り返しの設定。 さて、このtrialルーチンを繰り返し実行するためには、フローにループを挿入する必要があります。ループを挿入するには、フローペインの左端の「ループを挿入」を左クリックします。クリックした後にフロー上にマウスカーソルを動かすと、ループの始点または終点を挿入できる点にカーソルが重なった時にその場所に黒い円が表示されます( :numref:`fig-insert-loop` 左下)。黒い円が表示されている時にその位置をクリックすると、始点または終点として指定することが出来ます。通常は始点と終点の二カ所を指定する必要がありますが、今回はルーチンが一つしかなくて始点が決まると終点は自動的に決まってしまうため、一カ所をクリックするだけで始点と終点が確定します。 ループの始点と終点が確定すると、ループの設定ダイアログが表示されます。ここではループの名前や種類、ループ回数、条件ファイルなどを指定します。名前はコンポーネントの名前と同様に、Builder上での表示をわかりやすくするためなどに使えます。問題は **Loopの種類** ですが、本書では指定できる種類の内sequential、random、fullRandomの三種類を解説します。 :numref:`fig-loop-types` はexp03_cnd.xlsxで指定した4条件の条件ファイルをsequential、random、fullRandomで繰り返した場合の実行例を示しています。ループ回数を指定する **繰り返し回数 $** には3が入力されていると仮定しています。sequentialでは、条件ファイルに書かれた条件が、そのままの順番で2行目(1行目はパラメータ名)から実行されます。最後の行まで進むとまた2行目に戻って繰り返し、 **繰り返し回数 $** で指定された回数の繰り返しが終了すると終了します。randomとfullRandomでは無作為に順番が並べ替えられますが、randomでは「条件ファイルに書かれた条件を無作為に並び替えて実行する」という作業を **繰り返し回数 $** 回繰り返します。従って、それぞれのループでは条件ファイルに書かれた条件が必ず1回ずつ実行されます。 :numref:`fig-loop-types` のrandomの例で1回目、2回目、3回目の繰り返しの全てにおいて条件ファイルに書かれた4つの条件が1回ずつ実行されていることを確認してください。これに対して、fullRandomでは全試行を終えた時点で条件ファイルに書かれた条件がそれぞれ **繰り返し回数 $** 回繰り返されます。 :numref:`fig-loop-types` のrandomとfullRandomをよく見比べてその違いを理解してください。一般論として、randomでは同一条件の試行が続くことはあまりありません(n回目の繰り返しの最後の試行とn+1回目の繰り返しの最初の試行が一致した場合のみ)が、fullRandomでは同一条件の試行が続くことがしばしばあります。これらのループタイプを使い分けることがBuilderを使いこなすコツです。 .. _fig-loop-types: .. figure:: fig03/loop-types.png :width: 70% 3種類のループタイプの違い。 **乱数のシード $** は、繰り返し順序の無作為にするための処理を操作するための項目です。 **乱数のシード $** を空白にしておくと、PsychoPyが実験を実行する度に異なる繰り返し順序を決定してくれます。しかし、例えば498202という整数を指定しておくと、この値を変更しない限り、一見無作為な並び替えに見えますが毎回必ず同じ順序の繰り返しが行われます。この整数のことを乱数のシードと呼びます。シードを実験者が自分で指定してその記録をとっておけば、以前行った実験と全く同一の繰り返し順序を再開できます。研究の目的によってはこのような再現性が必要になるかも知れませんので、各自の判断で選択してください。なお、乱数のシードについてもう少し詳しく知りたい方は :ref:`topic-random-seed` をご覧ください。 **繰り返し条件** には、条件ファイル名を入力します。右の「選択…」というボタンを押すと通常のアプリケーションのようなファイル選択ダイアログが出現して、目的の条件ファイルを選択すると **繰り返し条件** にファイル名が入力することが出来ます。特に難しい操作ではないと思いますが、ひとつだけ注意してほしい事があります。 **繰り返し条件** を入力する前に少なくとも一度、実験(psyexpファイル)を保存してください。Builderはpsyexpファイルが保存された場所を基準に条件ファイルを探しますので、一度もpsyexpファイルが保存されていない状態で条件ファイルを指定してしまうと、入力結果がおかしくなってしまう場合があります。この章を読みながら作業している方はすでにexp03.psyexpという名前で実験を一度保存しているはずですので問題は生じませんが、今後自分で実験を作成する時には気を付けてください。 あと **試行を繰り返す** というチェックボックスと **使用する行 $** という項目がありますが、 **試行を繰り返す** については次章で解説します。 **使用する行 $** については :ref:`topic-select-condition-rows` をご覧ください。 さて、解説はこのくらいにして実験の作成を進めましょう。今回の実験ではloop TypeにfullRandomを用いることにして、 **繰り返し回数 $** には25を入力しましょう。 **乱数のシード $** は空白で良いでしょう。条件ファイルに4つの条件が定義されているので、それぞれを25回ずつ繰り返すと25×4=100試行となり、最初の計画と一致します。そして **繰り返し条件** の項目の右端の「選択…」ボタンを押して条件ファイル(exp03_cnd.xlsx)を選択してください。正常に読み込むことが出来れば、 :numref:`fig-confirm-loop-conditions` 左のように **繰り返し条件** の上に条件ファイルの概要が表示されます。 :numref:`fig-confirm-loop-conditions` では「2パラメータ, 4条件」と書かれていますが、「4条件」が条件ファイルの行数(先頭行を除く)、「2パラメータ」が列数に対応しています。次の行に[stim_color, stim_xpos]と書かれているのは条件ファイル先頭行に入力したパラメータ名です。パラメータ名の順番はBuilderが扱いやすいように自動的に並べ替えるので、パラメータ名に過不足がないことだけを確認してください。exp03_cnd.xlsxで定義したパラメータ名と一致していることが確認できたら、ダイアログのOKをクリックしてダイアログを閉じましょう。すると :numref:`fig-confirm-loop-conditions` 右のようにフローペインにループ(左側へ戻る矢印)が表示されます。ループの矢印上にtrialsと書かれた白い四角が表示されていますが、これはループのプロパティ設定ダイアログの **名前** で設定したループの名前を示しています。 .. _fig-confirm-loop-conditions: .. figure:: fig03/confirm-loop-conditions.png :width: 90% **繰り返し条件** に条件ファイルを指定すると、条件ファイルの概要が表示されます。概要が表示されない場合は条件ファイルの読み込みに失敗していますので条件ファイルの内容を確認しましょう。 一度設定したループを再設定したい場合は、ループの名前が書かれた白い四角にマウスカーソルを重ねて左ボタンをダブルクリックしてください。削除したい場合は、同じくマウスカーソルを重ねた状態で右クリックをしてください。「削除」という項目だけがあるメニューが表示されるので、「削除」を選択しましょう( :numref:`fig-remove-loop` )。 .. _fig-remove-loop: .. figure:: fig03/remove-loop.png :width: 60% ループの再設定と削除 さて、これでいよいよ赤や緑の刺激が左右に表示されるようになりました、と言いたいところですが、まだもう一つ作業が残っています。この節の作業によって、Builderは条件ファイルから条件を読み取って、パラメータを変化させながらルーチンを繰り返し実行できるようになりました。しかし、肝心のルーチンが条件ファイルから読み取られたパラメータを利用できるようになっていません。次の節では、読み取ったパラメータを利用する方法を解説します。 チェックリスト - フローペインでループの挿入を開始できる。 - ループを挿入する際、フローペインの矢印上に表示される黒い円の意味を説明できる。 - ループのプロパティ設定ダイアログで条件ファイルを指定し、表示された条件ファイルの概要が適切か確認できる。 - **Loopの種類** のsequential、random、fullRandomの違いを説明できる。 - **繰り返し回数 $** の値、条件ファイルに含まれる条件数、ルーチンが繰り返される回数の関係を説明できる。 - **乱数のシード $** に値を設定するとどのような効果が得られるか説明できる。 - 条件ファイルを **繰り返し条件** に指定する前にpsyexpファイルを保存すべき理由を説明できる。 .. _section-modify-stimuli-using-conditionsfile: パラメータを利用して刺激を変化させよう ---------------------------------------------------- 手始めに、条件ファイルから読み取ったパラメータを使って刺激の位置を左右に変化させてみましょう。ルーチンペインに戻って、stimulusのプロパティ設定ダイアログを開いてください。 **位置 [x, y] $** の欄には[400, 0]と入力されているはずですが、これを[stim_xpos, 0]に書き換えてください。そして、入力欄の右側にある「更新しない」と書かれたプルダウンメニューをクリックして「繰り返し毎に更新」を選択しましょう( :numref:`fig-set-every-repeat` )。 .. _fig-set-every-repeat: .. figure:: fig03/set-every-repeat.png :width: 60% 条件ファイルからパラメータを読み込んで自動的にプロパティを更新します。「繰り返し毎に更新」を選択し忘れるミスは非常によくあるので忘れないようにしてください。 このようにプロパティ設定ダイアログの項目に、条件ファイル先頭行のパラメータ名を書くと、Builderが実験を実行する時にパラメータの値を自動的に更新してくれます。今回の実験の場合は、先ほど設定した繰り返しによってこのルーチンが実行されるたびに、条件ファイルで定義された条件が無作為化された順序で代入されます。初期値の「更新しない」は文字通り「実験を通じて変化しない」という意味ですので、「更新しない」のままにしておくと代入が行われず「stim_xposなんて値は知らないよ」というエラーが生じて実験が停止します( :numref:`fig-error-variable-not-defined` )。このエラーメッセージはあまり原因を適切に反映していなくてわかりづらいので気を付けてください。「更新しない」のままにするという失敗は、Builder初心者はもちろん、ある程度慣れてきたユーザーでも時々犯しがちですので注意しましょう。 :numref:`fig-set-every-repeat` の変更が終わったら、実験を実行して刺激の位置が左右に変化することを確認してください。これでようやく実験らしくなってきました。そして、ぜひ一度「更新しない」に戻してエラーが発生することも体験しておいてください。 .. _fig-error-variable-not-defined: .. figure:: fig03/error-variable-not-defined.png :width: 70% 条件ファイルからパラメータを読み込むつもりなのに「更新しない」のまま実行してしまった時に表示されるエラー。 続いて刺激の色も条件に応じて更新するようにしましょう。基本的には位置の更新と同じなのですが、ここにも一つ注意しないといけない点があります。今まで敢えて説明していなかったのですが、プロパティ設定ダイアログの項目には$が最後についているものとついていないものがあることに皆さんは気付いておられるでしょうか。例えば **位置 [x, y] $** や **回転角度 $** には$が付いていますし、 **塗りつぶしの色** やT **文字列** には$が付いていません。この$記号は、難しい言い方をしますと「入力した値が文字列として評価されるか($なし)、Pythonの式として評価されるか($あり)」を表しています。 具体的な例を挙げましょう。Textコンポーネントの **文字列** に Targetと入力されているとします。これは画面上にTargetという文字列を表示したいということでしょうか。それとも、条件ファイルにTargetという名前のパラメータが定義されていて、そのパラメータの値を代入したいということでしょうか。条件ファイルという便利なものを導入した代償に、「各コンポーネントのプロパティに文字列が入力されている場合、それはデータとしての文字列なのか、パラメータの名前なのか」を区別する方法を考えなければいけなくなってしまいました。ここで登場するのが$です。Builderでは、プロパティに入力された値に$が含まれていなければ、その値は文字列であるとみなされます( :numref:`fig-variable-name-or-string` )。従って、先ほど挙げた「 **文字列** にTargetと入力されている」例ではTargetという文字列をスクリーン上に提示したいのだと解釈されます。もし$Targetと書かれていれば、Targetという名前のパラメータの値を条件ファイルから読み込むのだと解釈されます。当然、条件ファイル内でTargetという名前のパラメータが定義されていなければエラーになります。 .. _fig-variable-name-or-string: .. figure:: fig03/variable-name-or-string.png :width: 80% $を付けることによって入力した値が名前を表しているのか文字列を表しているのかを区別します。 ここで、読者の皆さんの中には「ちょっと待てよ、じゃあ :numref:`fig-set-every-repeat` の時はなんで$[stim_xpos, 0]じゃなくて[stim_xpos, 0]でパラメータの値を読み込めたの?」と疑問を持った方もいるかも知れません。確かに :numref:`fig-variable-name-or-string` の規則に従うのであれば、 :numref:`fig-set-every-repeat` は$[stim_xpos, 0]と書かないといけないはずです。ここで注目してほしいのが **位置 [x, y] $** というプロパティ名の最後の$記号です。この$は本来入力欄に書くべきだった$がプロパティ名に引っ越してきたと思えばよいでしょう。考えてみれば、 **位置 [x, y] $** や **回転角度 $** と言ったプロパティには文字列が指定される可能性はありません。例えば論文の手続きに「刺激をX度回転した」と書いてあったら、常識で考えてXは変数であって文中のどこかで「Xは30または60」とかいう具合に数値が指定されているはずでしょう。それと同じことで、位置や回転角度のように数値を指定すべきプロパティに文字列が書いてあったら、常識的に考えてそれは名前であるはずです。だから、最初からプロパティ名に$を含ませてしまって、いちいち$を入力しなくてよいようになっているのです( :numref:`fig-expression-mark` )。 .. _fig-expression-mark: .. figure:: fig03/expression-mark.png :width: 80% プロパティ名に$が付いているものは、文字列が指定されることがあり得ないプロパティなので、$を入力しなくても名前として解釈されます。 以上の解説が済んだところで、ようやく条件ファイルを使って刺激の色を変化させる方法を説明することが出来るようになりました。刺激の色は **塗りつぶしの色** と **輪郭線の色** で指定します。これらのプロパティに条件ファイルで定義したパラメータstim_colorの値を代入したいのですが、 **塗りつぶしの色** にも **輪郭線の色** にも$はついていません。ではどのように書いたら良いか、もうお分かりですね。正解を :numref:`fig-change-color-every-repeat` に示します。「繰り返し毎に更新」を選択するのを忘れないようにしてください。設定が出来たら、実験を実行してみましょう。今度は刺激の位置も色もきちんと条件ファイルに従って変化するはずです。 .. _fig-change-color-every-repeat: .. figure:: fig03/change-color-every-repeat.png :width: 70% 条件ファイルを用いて刺激の色を繰り返し毎に更新する時の設定例。「高度」タブですので注意してください。 これでようやく刺激が完成しました。次は実験記録を保存したファイルを確認しますが、その前に色の指定に関してここまで説明を後回しにしていた問題を取り上げましょう。まず、第2章で色の指定方法について学んだ時に、色空間内の座標による指定では$[1.0, 0.0, 0.75]のように$を必ず付けていました。この節の内容を理解した方は、なぜ$が必要であったか想像がついているのではないかと思います。 **塗りつぶしの色** 、 **輪郭線の色** 、 **色** にはいずれも$が付いていないので、$なしで[1.0, 0.0, 0.75]と書かれているとBuilderには「[1.0, 0.0, 0.75]という名前の色」に見えてしまうのです。当然こんなヘンテコな名前はweb/X11 Color nameにはありませんので、Builderは「こんな名前の色は知らない」というエラーを出して止まってしまいます。一方、本章で条件ファイルの作成方法を解説した際に「条件ファイル内において色空間座標値で色を指定する場合は$なしで書かねばならない」と述べましたが、こちらはちょっと事情が複雑です。ごく簡単に説明しますと、Builderは条件ファイルから読み込んだ値に関しては「名前ではありえない」と考えます。ですから、条件ファイル内に書かれた$記号は「名前か、文字列か?」を判断するための記号としてではなく、単なる文字として解釈されます。ですから、条件ファイル内に$付きで$[1.0, 0.0, 0.75]と書かれていると、余計な$が付いていることになって色座標値として解釈されなくなってしまうのです。まあ、この辺りはよくわからなければとりあえず置いておいて、「条件ファイル関連でうまく値が読み込まれない時は$記号に問題があるかも知れない」と疑うことを覚えておいていただければ十分かもしれません。では$記号そのものを文字列として表示させたい場合はどうしたらいいの?という点については :ref:`topic-dollar-character-in-string` に書いておきましたので、興味がある方はご覧ください。 チェックリスト - 条件ファイルで定義したパラメータを用いてコンポーネントのプロパティ値を更新できるように設定できる。 - コンポーネントのプロパティ名の最後に$が付いているものと付いてないものの違いを説明できる。 実験記録ファイルの内容を確認しよう ---------------------------------------------- 製作中の実験もかなり体裁が整ってきたので、ここで一度実験記録ファイルの内容について解説しておきましょう。以下の手順 (図 3 19)で設定を変更してから実験を実行してください。ちょっと大変ですが、100試行すべて行ってください。 - dataフォルダ内に作成されているファイルをすべて削除する。 - 実験設定ダイアログを開いて、すべての実験記録ファイルを出力するように設定する。すなわち、「xlsx形式のデータを保存」、「CSV形式のデータを保存(summaries)」、「CSV形式のデータを保存(trial-by-trial)」、「pydat形式のデータを保存」にチェックを付ける。 - 実験実行ボタンをクリックして実験を開始し、実験情報ダイアログのparticipantにfooと入力して実行する。 .. _fig-output-all-datafiles: .. figure:: fig03/output-all-datafiles.png :width: 80% 実験設定ダイアログを開いてすべての記録ファイルを保存するようにチェックして実験を最後まで実行してください。実験開始時の実験情報ダイアログのparticipantにfooと入力してください。 実験が終了したら、dataフォルダの内容を確認してください。 :numref:`tbl-builder-generated-files` に示したファイルが出来ているはずです。ファイル名の先頭部分にはparticipantに入力した文字列が代入されており、続いて実験を実行した時刻が続きます。participantに入力する文字列を工夫すると、データの整理が非常に楽になります。participantを空白のまま実験を実行すると、アンダースコア( \_ )の後に実行時刻が続くファイル名になります。participantにファイル名として使用できない文字列を指定しないように注意してください。 .. tabularcolumns:: |p{16zw}|p{26zw}| .. _tbl-builder-generated-files: .. list-table:: Builderが作成する実験記録ファイル(fooは実験情報ダイアログのparticipantに入力した文字列、yyyy_mm_dd_hhMMは年(西暦)、月、日、時、分)。 :header-rows: 1 :widths: 36, 64 - - ファイル名 - 概要 - - foo_yyyy_mn_dd_hhMM.xlsx - 条件毎に結果をまとめたExcelファイルを保存する。実験設定ダイアログの「xlsx形式のデータを保存」をチェックすると作成される。 - - foo_yyyy_mn_dd_hhMM.trials.csv - 条件毎に結果をまとめたCSVファイルを保存する。実験設定ダイアログの「CSV形式のデータを保存(summaries)」をチェックすると作成される。 - - foo_yyyy_mn_dd_hhMM.csv - 試行毎に結果をまとめたCSVファイルを保存する。実験設定ダイアログの「CSV形式のデータを保存(trial-by-trial)」をチェックすると作成される。 - - foo_yyyy_mn_dd_hhMM.psydat - PythonのcPickleというモジュールを用いて出力された実験記録。自分で分析用Pythonスクリプトを書く場合に用いる。実験設定ダイアログの「pydat形式のデータを保存」をチェックすると作成される。 - - foo_yyyy_mn_dd_hhMM.log - 実験中のPsychoPyの動作記録が保存されている。実験設定ダイアログの「ログレベル $」の選択肢によって内容が変化する。PsychoPy自体の動作解析や開発などに用いる。通常のデータ分析向きではない。実験設定ダイアログの「ログの保存」をチェックすると作成される。 作成されるファイルのうち、拡張子が.logと.psydatのファイルはとりあえず無視してよいでしょう。.psydatファイルは「データ分析は自作のPythonスクリプトをでする」という人しか使わないでしょうし、.logファイルは通常のデータ分析では必要のないファイルです。ただ、「実験が正常に動作していたのか?」という事が問題になった時には.logファイルがあると役に立ちますので、学会や論文で公表する可能性がある実験の.logファイルは保存しておいた方がよいでしょう。 データ分析の際に基本となるファイルは、foo_yyyy_mn_dd_hhMM.csvです。拡張子の.csvは、このファイルの保存形式がカンマ区切りのテキストファイル(comma-separated values; CSV)であることを意味しています。ExcelもLibreOffice CalcもCSVファイルを開くことが出来ますので、以下の解説ではこれらのアプリケーションでCSVファイルを開くという前提で進めます。 foo_yyyy_mn_dd_hhMM.csvをExcelで開くと(LibreOffice Calcでも同様、以下省略)、シートの1行が1回の試行に対応する形で実験記録が保存されていることを確認できます。このファイルは、実験設定ダイアログで「CSV形式のデータを保存(trial-by-trial)」をチェックしていると作成されるので、以下trial-by-trial記録ファイルと呼ぶことにします。1行目は各列の見出しで、2行目が第1試行、3行目が第2試行という具合に101行目(第100試行)までデータがあることを確認してください。列数は条件ファイル数に含まれるパラメータ数やルーチンに配置されたコンポーネントによって変化しますが、一般的に以下の内容が含まれます( :numref:`fig-data-trial-by-trial` )。 .. _fig-data-trial-by-trial: .. figure:: fig03/data-trial-by-trial.png :width: 90% trial-by-trial記録ファイルの内容。「各試行で用いられたパラメータ」は条件ファイルを使用した場合のみ、「Keyboardコンポーネントの出力」はKeyboradコンポーネントを使用した場合のみ出力されます。 各試行で用いられたパラメータ 条件ファイル内で定義されているパラメータの内、どの値が使用されたかが示されています。この情報を含む列の数は条件ファイルの列数に対応しています。実行した実験で条件ファイルが使用されていない場合は出力されません。 繰り返しに関する情報。 その行の試行が何回目の繰り返しの何試行目にあたるか、全体を通して数えて何試行目にあたるかといった情報が示されています。 :numref:`fig-data-trial-by-trial` のtrials.thisRepNは何回目の繰り返しか、trials.thisTrialNはその繰り返しにおける何試行目か、trials.thisNは全体を通して何試行目か、trials.thisIndexはその試行で用いられたパラメータが条件ファイルの何個目の条件に相当するかを示しています。Pythonでは「順番は0番目から数える」という規則がありますので、第1試行が0と表記されていることに注意してください。また、列見出しのtrialsの部分はBuilderにおけるループの名前に対応しています。 Keyboardコンポーネントの出力。 もちろん実験にKeyboardコンポーネントが含まれていなければ出力されません。key_resp_2.keysは押されたキーのキー名、key_resp_2.rtはKeyboardコンポーネントが有効になってからキーが押されるまでの時間を示しています。単位は秒です。列見出しのkey_resp_2の部分はBuilderにおけるKeyboardコンポーネントの名前に対応しています。なお、時間が小数点以下ものすごい桁数まで出力されていますが、計測に詳しい方は「一体この値はどの程度精度があるのか」と不安になるかもしれません。PsychoPy Builderが出力する時間の精度については :ref:`topic-clock-resolution` をご覧ください。 実験に関する様々な情報。 実験実施日や実験名、実験情報ダイアログで入力した値、フレームレートなどが示されています。フレームレートとは、1秒あたりに描画したフレーム数のことで、モニターのリフレッシュレートと大きく異なる場合はスクリーンの描画に問題が生じている可能性があります。リフレッシュレートとフレームについては :ref:`topic-start-stop-by-frame` をご覧ください。特にこの値がモニターのリフレッシュレートより大幅に小さい場合は、スクリーンの描画に遅延が生じていて刺激が適切な時刻に表示されていない恐れがあります。 今回の実験では、刺激が提示される位置と反応する指の関係が反応の速さや正確さにどのように影響するかを調べるのが目的ですから、刺激の位置と色の組み合わせ別に、正答率と反応時間を計算すればよいでしょう。すでに自分自身でいろいろなアプリケーションを用いて実験を行っている方は各自で好みの方法で分析していただければよいですが、こういった分析が初めての方はとりあえずstim_colorとstim_xposでデータを並べ替えしてみましょう。するとそれぞれの条件に対応する試行が集まりますので、ワークシート関数を用いて平均を求めたり、xキーとslashキーが押された回数を条件毎に数えて正答率を計算したりすることが出来ます。 trial-by-trial記録ファイルは、個々の試行の情報が1行にまとめられていて分析をする際にとても便利なのですが、平均反応時間や正答率を計算するという分析は心理学実験において非常によく用いられるので、ソフトウェアが自動的に計算してくれると実験者は楽が出来ます。Builderには、条件毎に平均反応時間と正答率を計算してくれる機能が備わっています。一旦trial-by-trial形式のファイルを閉じて、拡張子がxlsxのファイル(foo_yyyy_mn_dd_hhMM.xlsx)を開きましょう。trial-by-trial記録ファイルに対して並び替えなどの操作をしていたら「変更を保存しますか?」とExcelから聞かれますが、筆者としては変更を保存しないことを強くお勧めします。今回はBuilderの使い方を学ぶために作っている実験なので別に保存してもしなくても構わないのですが、学会発表などに用いる可能性がある実験では、まったく変更が加えられていない「オリジナル」な記録ファイルが残っていることが極めて重要です。オリジナルのファイルが残っていれば新たに分析しなおすことが可能ですが、変更を保存してしまうと二度とオリジナルの状態に復元できないかもしれません。大切な記録ファイルは必ず未変更の状態で保存しておいて、変更を加えた場合は別のファイル名にするか別のフォルダに保存すべきです。 foo_yyyy_mn_dd_hhMM.xlsxを開くと、 :numref:`fig-data-xlsx` のように横方向にたくさんの値が並んだシートが表示されるはずです。このファイルは実験設定ダイアログの「xlsx形式のデータを保存」をチェックすると作成されるので、xlsx記録ファイルと呼ぶことにしましょう。xslx記録ファイルでは、シートの1行がひとつの条件に対応しています。最初に条件ファイルに記述されているパラメータが示された後、nという見出しの列が続きます。この列には各条件に対応する試行が何試行あったかが記されています。 :numref:`fig-data-xlsx` ではすべて25となっています。一般に、nの値はループの **繰り返し回数 $** に一致します。続いてkey_resp_2.keys_rawという見出しの列からずらっと横方向にKeyboardコンポーネントが記録した「押されたキー名」が記録されています。並んでいる列数は各条件に含まれる試行数(この例では25列)に一致します。キー名に続いて、key_resp_2.rt_meanという見出しの列が来ます。この列には各条件の平均反応時間が示されています(単位は秒)。key_resp_2.rt_meanに続くkey_resp_2.rt_rawは個々の試行の反応時間です。やはり各条件の試行数だけ反応時間の値が続いた後、key_resp_2.rt_stdという列に反応時間の標準偏差が示されています。最後にorderという見出しと共に、横方向に並べられたそれぞれの試行が繰り返し全体の中で何試行目であったかを示す値が入っています。というわけで、条件別の平均反応時間はわざわざ計算しなくてもBuilderの記録ファイルに出力されていることがわかりました。 .. _fig-data-xlsx: .. figure:: fig03/data-xlsx.png :width: 90% xlsx記録ファイルの内容。Keybooardコンポーネントの出力が1条件1行でまとめられています。 気を付けておかないといけないのは、xlsx記録ファイルの作成を指示する実験設定ダイアログの「xlsx形式のデータを保存」が初期状態ではチェックされていないという点です。「trial-by-trial記録ファイルだけあれば後は自分で分析するから大丈夫」という人以外は、忘れずに「xlsx形式のデータを保存」をチェックしておくようにしましょう。なお、実験設定ダイアログには「xlsx形式のデータを保存」 の下に「CSV形式のデータを保存(summaries)」という項目がありますが、この項目にチェックしておくと、xlsx形式のファイルとほぼ同一の内容がCSV形式で出力されます。ファイル名はfoo_yyyy_mn_dd_hhMM.trials.csvという具合に実験実施時刻の後に.trialsという文字列が入ります。この記録ファイルをsummaries記録ファイルと呼ぶことにしましょう。実験後の分析に使用するアプリケーションとの相性などを考慮して、xlsx記録ファイルかsummaries記録ファイルかどちらかの一方を作成しておけばよいでしょう。一般論として、summaries記録ファイルはほとんどのファイルで開くことが出来ますが、条件ファイルの値に日本語が含まれていると正常に表示されない場合があります。xlsx記録ファイルは開くためにExcelやLibreOffice Calcが必要ですが、日本語を含んでいても正常に表示できます。 さて、平均反応時間はxlsx記録ファイルに出力されていることがわかりましたが、正答率はどうでしょうか。押されたキーのキー名が条件毎に1行にまとめられていますので、xキーまたはslashキーが何回押されているか条件別に数えれば正答率を計算することはそれほど難しくありません。ですが、実は正答率の計算もBuilderに自動的にさせる方法があるのです。次節ではその方法について解説します。 チェックリスト - expInfoのparticipantに設定した文字列が記録ファイル名にどのように反映されるかを説明出来る。 - dataフォルダに作成される拡張子logとpsydatのファイルに何が記録されているか、概要を説明することが出来る。 - CSVファイルのCSVとは何の略であり、何を意味しているか説明することが出来る。 - trial-by-trial記録ファイルとxlsx記録ファイル、summaries記録ファイルの違いを説明できる。 - trial-by-trial記録ファイルから、各試行で用いられたパラメータの値を読み取ることが出来る。 - trial-by-trial記録ファイルから、各試行において押されたキーのキー名と反応時間を読み取ることが出来る。 - trial-by-trial記録ファイル、xlsx記録ファイル、summaries記録ファイルに記録されている反応時間の計測開始時点(0.0秒になる時点)がどのように決まるか答えることが出来る。 - trial-by-trial記録ファイル、xlsx記録ファイル、summaries記録ファイルから実験情報ダイアログで入力した値を読み取ることが出来る。 - trial-by-trial記録ファイル、xlsx記録ファイル、summaries記録ファイルから実験実行時のフレームレートを読み取ることが出来る。 - xlsx記録ファイルおよびsummaries記録ファイルから各条件の試行数を読み取ることが出来る。 - xlsx記録ファイルおよびsummaries記録ファイルから反応時間の平均値と標準偏差を読み取ることが出来る。 - 分析時に未変更の記録ファイルを保存しておいた方がよい理由を説明できる。 反応の正誤を記録しよう -------------------------------------- Builderの画面に戻って、exp03.psyexpを開いてください。そしてKeyboardコンポーネントのプロパティ設定ダイアログを開きましょう。 :numref:`fig-set-correct-ans` に示す通り **正答を記録** という項目がありますが、この項目をチェックすると **正答** という項目が出現します。ここに正答となるキー名を入力しておくと、Builderが押されたキーが正答キーと一致するか否かを判定して記録ファイルに保存してくれます。xキーが正解ならば'x'、 / キーが正解であれば'slash'です。GO/NOGO課題のように「押さないのが正解」の場合はNoneと入力します。Noneの前後にクォーテーションマークが付いていないことに気を付けてください。 多くの心理学実験では、条件によって正答となる反応が変化します。従って、 **正答** に入力するキー名は条件毎に変化させる必要があります。「条件毎に変化する」となると、条件ファイルの出番です。刺激が赤色の時にxキー、緑色の時に / キーを押すのが正答ですが、この関係は作成済みの条件ファイルに含まれている値からはわからないので、正答のキー名を示すパラメータ列を条件ファイルに追加する必要があります。刺激の位置と色を変化させた時にはまず条件ファイルの作成から始めましたが、どのようなパラメータ名を使用するかすでに決めているのであれば、Builder側の作業から始めてしまっても問題はありません。correct_ansという列を条件ファイルに追加して、そこへ正答キー名を入力することにしましょう。 .. _fig-set-correct-ans: .. figure:: fig03/set-correct-ans.png :width: 70% 反応の正誤を記録するよう設定する手順。 Keyboardコンポーネントのプロパティ設定ダイアログの **正答** に「correct_ansから値を代入して繰り返し毎に更新する」ように設定しないといけないのですが、ここで条件ファイルの参照について皆さんがきちんと理解しているかテストです。 **正答** に入力する値はcorrect_ansですか、それとも$correct_ansですか? :numref:`fig-set-correct-ans` を一番下まで先にご覧になった方はすでにおわかりと思いますが、答えは$付きの$correct_ansです。なぜ$が必要か、きちんと説明できない方はもう一度$記号について復習しておきましょう。繰り返し毎の更新でもう一つ注意すべき点として「「繰り返し毎に更新」を忘れずに選択する」というものがありましたが、 **正答** の右側にはそもそもプルダウンメニューがありません。この項目に関しては、「繰り返し毎に更新」を選ばなくても更新が行われます。 **正答** の設定が終わったら、今度はExcelを開いて条件ファイルを編集しましょう。correct_ansと1行目に書かれた列を追加して、正答キー名を入力してください。正答キーは刺激の色と対応しているのですから、stim_colorがredの行はx、greenの行はslashが正答キーです( :numref:`fig-edit-correct-ans` )。入力したら条件ファイルを保存しましょう。条件ファイルの名前や保存場所を変更していなければ、Builderで条件ファイル名を設定し直す必要はありません。試しにBuilderに戻ってフローペインのループを左クリックしてループのプロパティ設定ダイアログを表示させると、相変わらずパラメータはstim_colorとstim_xposの二つと表示されています。しかし、実行するときちんと新しく追加したパラメータも読み込まれません。正しく表示されないと気持ち悪いという方は、もう一度条件ファイルを設定し直してください。正しくstim_color、stim_xposとcorrect_ansの3パラメータが表示されるはずです。 .. _fig-edit-correct-ans: .. figure:: fig03/edit-correct-ans.png :width: 50% 条件ファイルにcorrect_ansの列を追加し、正答キー名を入力します。 Keyboardコンポーネントと条件ファイルの修正が終わったら、実験を実行してみましょう。きちんと100試行終わるまで実行してください。終了したら、trial-by-trial記録ファイルの内容を確認してみましょう( :numref:`fig-check-correct-ans` )。trial-by-trial記録ファイルにはkey_resp_2.corrという列が追加されています。この列の値が1の試行は正答で、0の試行は誤答です。xlsx記録ファイルとsummaries記録ファイルでは、key_resp_2.corr_mean、key_resp_2.corr_raw、key_resp_2.corr_stdという列が追加されます。それぞれ各条件におけるkey_resp_2.corrの値をまとめたものですが、1が正答、0が誤答なのですからその平均値は正答率(0=全問不正解、1=全問正解)そのものです。ですから、key_resp_2.corr_meanを見れば各条件の正答率がわかります。念のため補足しておきますが、key_resp_2の部分は当然Keyboardコンポーネントの名前に応じて変化します。 .. _fig-check-correct-ans: .. figure:: fig03/check-correct-ans.png :width: 80% **正答** を設定すると記録ファイルに正答/誤答が記録されます。 以上で、サイモン効果を題材としたこの章の実験は「一応」完成しました。「一応」というのは、確かに最初に計画した目標は一通り達成しているのですが、実際にこのpsyexpファイルを使って参加者を募って実験するとなるといくつか不都合な点があるからです。例えば、実験実行ボタンを押して実験情報ダイアログに値を入力すると、直ちに最初の試行が始まってしまいます。実験者が実験情報ダイアログに入力する場合、入力したらすぐに実験参加者にキーボードを渡さないと最初の試行の刺激に反応出来ないでしょう。また、実験参加者に対する教示も実験開始前にスクリーン上に表示しておきたいものです。終了時もいきなりBuilderのウィンドウに戻るのではなく、何か一言実験参加者へのお礼や指示があると気が利いていて良いでしょう。次の節では、こういった気配りを実験に組み込む方法を解説します。 チェックリスト - 正答/誤答を記録するようにKeyboardコンポーネントを設定することが出来る。 - キーを押さないことが正答となるように設定することが出来る。 - 正答となるキー名を条件ファイルから読み込んで繰り返し毎に更新することが出来る。 - trial-by-trial記録ファイルから、各試行の正答/誤答を読み取ることが出来る。 - xlsx記録ファイルおよびsummaries記録ファイルから各条件の正答率を読み取ることが出来る。 教示などを追加しよう ------------------------------------------- この節では、exp03.psyexpの実験開始時と終了時に教示などを表示させます。一口で教示を表示すると言っても「イラストで教示するのか、文章で表示するのかなど」いろいろと選択肢がありますが、ここでは文章で表示することにしましょう。 文章を表示するとなるとTextコンポーネントの出番ですが、ここまで解説してきた方法だけではうまく表示することが出来ません。というのも、今まで通りルーチンペイン上にTextコンポーネントを配置してしまうと、繰り返しの度に表示されてしまうので「実験開始時と終了時」ではなくて試行毎の表示になってしまうのです。繰り返しが始まる前や後に何かを表示したいときには、新しいルーチンを追加する必要があります。 :numref:`fig-insert-new-routine` はフローペインを使って新しいルーチンを作成してフローに挿入する手順を示しています。まず、フローペイン左端のInsert Routineをクリックします。すると(new)とtrialという二つの項目があるポップアップメニューが表示されます。「繰り返しを設定しよう」の節で少しだけ触れましたが、PsychoPyで実験を新規作成した時に最初から表示されているルーチンはtrialという名前がついています。ポップアップメニューのtrialという項目を選択すると、trialルーチンがもう一つフローに挿入されます。同じルーチンを何個も挿入してどうするのかと思われるかもしれませんが、その例は練習問題で触れることにしましょう。 新しくルーチンを作成してフローに挿入する場合は、(new)を選択します。すると挿入するルーチン名を入力するダイアログが表示されますので、わかりやすい名前を決めて入力しましょう。名前はパラメータ名に使用出来る文字列と同様の規則を満たすものでなければいけません。また、すでにパラメータ名やコンポーネントの **名前** プロパティで使用している名前とも重複してはいけません。ここでは実験開始前に教示を表示するためのルーチンということでinstructionという名前を付けておきます。 .. _fig-insert-new-routine: .. figure:: fig03/insert-new-routine.png :width: 90% フローペインから新しいルーチンの追加を追加します。 名前を決定すると、新しいルーチンをフローのどの位置に挿入するかを指定しなければいけません。フロー上でマウスカーソルを動かすと、マウスカーソルが挿入可能な位置に重なった時に黒い丸が表示されますので、ループの前を選んで挿入してください。すると :numref:`fig-insert-new-routine` の右上のようにinstructionと書かれた四角いアイコンがループの前に挿入されます。同時に、ルーチンペインの左上にinstructionと書かれたタブが出現しているはずです。フローのinstructionと書かれたアイコンか、ルーチンペイン左上のinstructionと書かれたタブをクリックすれば、まだコンポーネントが配置されていない空白のルーチンが表示されるはずです。この空白のルーチンが新たに挿入されたinstructionルーチンです。 instructionルーチンの編集を始める前に、操作方法の確認を兼ねてもうひとつ実験終了時のメッセージを表示するためのルーチンを追加しておきましょう。ルーチン名はthanksとします。ここでは三つの点を確認しておいてください( :numref:`fig-edit-flow` )。 - フローペインの左端のInsert Routineを使ってフローにルーチンを挿入する時にポップアップメニューにinstructionルーチンが含まれていること。 - フロー上の挿入済みルーチンの上にマウスカーソルを重ねて右クリックすると「削除」という項目のみのポップアップメニューが表示され、それを選択するとルーチンをフローから削除出来ること。 - 上記の方法でフローからルーチンを削除しても、該当するルーチンはルーチンペインに残ったままであること。 .. _fig-edit-flow: .. figure:: fig03/edit-flow.png :width: 60% フローペインにおけるさまざまな操作。フローからルーチンを削除してもルーチンそのものは削除されません。 特に、フローからルーチンを削除してもルーチンそのものはルーチンペインに残っているという点は覚えておいてください。バージョン1.82.02現在でBuilderはフローにおけるルーチンの並び替えをサポートしていませんので、ルーチンの順番を変えたいときには一旦ルーチンをフローから削除して再挿入する必要があります。その際、一旦フロー上から目的のルーチンがなくなってしまっても全く問題ありません。 さて、instructionとthanksのルーチンを追加してそれぞれループの前と後ろに挿入ら、ルーチンの編集に入りましょう。まずinstructionルーチンでは、画面中央に以下のような教示を画面上に提示することにしましょう。 :: 画面の中央に白い十字が表示されたあと、すこし遅れて赤色または緑色の円が表示されます。 刺激の色を見て、以下のキーを出来るだけ速く間違わずに押してください。 赤色:左手人差し指でキーボードのxキー 緑色:右手人差し指でスラッシュ( / )キー スラッシュキーを押すと課題が始まります。 100問終了するまで休憩できないので注意してください。 実験参加者の中には「スラッシュキー」と言われてもどのキーかわからない方もいるでしょうから、キーの確認も兼ねてスラッシュキーを押して実験を開始することにしてみましたが、スペースキーなどの実際の反応で使用しないキーを割り当てるのもよいでしょう。上記の文章を表示するためのTextコンポーネントの設定については、ここまで作業してきた皆さんでしたらヒントなしで出来ると期待します。 ひとつ注意すべき点は、ルーチン終了時刻の指定です。教示に「スラッシュキーを押すと課題が始まります。」と書いてあるのですから、Keyboardコンポーネントを使用して、スラッシュキーが押されたらルーチンを終了するように設定すればよいでしょう。もちろんTextコンポーネントとKeyboardコンポーネントの **終了** は空白にしておきます。ここまではすでに解説済みのテクニックですが、このままだと記録ファイルに「課題を開始する時に押したスラッシュキー」まで保存されてしまいます(ただし第7章参照)。分析に必要な反応が記録されなくなってしまうわけではないので致命的な問題ではありませんが、分析と無関係なキー押しが記録されていると分析の際に思わぬ手間がかかる恐れがあります。 キー押しを記録したくない場合には、Keyboardコンポーネントのプロパティ設定ダイアログを開いて、 **記録** を「なし」に設定しましょう( :numref:`fig-dont-record-keys` )。そのKeyboardコンポーネントで検出されたキー押しは一切記録されません。「そのKeyboardコンポーネントで」と断ったとおり、ひとつの実験に複数のKeyboardコンポーネントを配置している場合、個々のKeyboardコンポーネントで独立に **記録** の設定を行うことが出来ます。今回の実験の場合、instructionルーチンに配置するKeyboardコンポーネント **記録** を「なし」にして、trialルーチンに配置するKeyboardコンポーネントは「最後のキー」のままにしておけばよいでしょう。これでinstructionルーチンは完成です。 .. _fig-dont-record-keys: .. figure:: fig03/dont-record-keys.png :width: 80% Keyboardコンポーネントで **記録** を「なし」に設定すると、そのKeyboardコンポーネントで検出したキー押しが記録ファイルに出力されません。 続いてthanksルーチンですが、ここではTextコンポーネントを使用して「終了しました。ご協力ありがとうございました。」というメッセージを3秒間表示することにしましょう。Textコンポーネント以外のコンポーネントを配置する必要はありません。特に難しい点はないはずですが、ひとつ解説しておきたい点があります。Textコンポーネントの **終了** の設定を終えた後にフローペインを見ると、thanksルーチンだけ緑色で表示されていて、小さく3.00sと表示されているはずです。対して、trialやinstructionルーチンは赤色で表示されています( :numref:`fig-routine-duration` )。緑色のルーチンは、中に含まれるすべてのコンポーネントの終了時刻が確定していて、ルーチン開始から終了までに要する時間が計算できることを示しています。赤いルーチンは、キーが押されるまで終了しないルーチンのように、ルーチン開始から終了までの時間が実行時にならないと確定しないことを示しています。 .. _fig-routine-duration: .. figure:: fig03/routine-duration.png :width: 80% 赤いルーチンは終了時刻が確定していないことを、緑色のルーチンは終了時刻が確定していることを表しています。緑色のルーチンにはルーチンの実行時間の見積もりが表示されています。 以上でこの節の目標は達成しましたが、ルーチンの新規作成やフローへの挿入について解説したついでに、Builderウィンドウ上部のメニューの「実験」という項目について補足しておきます(:numref:`fig-copy-paste-routine` 上)。メニューの「実験」からは、ルーチンの新規作成やコピー&ペースト、フローへのルーチンとループの挿入の操作が出来ます。これらの操作のうち、ルーチンの新規作成とフローへのルーチンとループの挿入はフローペイン左端の「Routineを挿入」や「Loopを挿入」を用いる方法とほぼ同じです。ルーチンのコピー&ペーストは、内容がわずかに異なるルーチンを複数作る必要がある時に便利な機能です。 試しにルーチンペインにtrialルーチンを表示している状態で、「実験」メニューから「Routineのコピー」を選択してください。続いてもう一度「実験」メニューを開いて「Routineの貼り付け」を選択しましょう。すると新しいルーチンの名前を入力するダイアログが表示されるので、他のルーチンやコンポーネントなどと名前が重複しないように新しい名前を入力してください。すると、trialと同じコンポーネントが配置された新しいルーチンが作成されます。ただし、同じコンポーネントが配置されていると言っても、各コンポーネントの名前はBuilderがコピー元のルーチンに含まれるコンポーネントの名前と重複しないように自動的にアンダーバー+数字が付けられるので注意してください (:numref:`fig-copy-paste-routine` 下)。 .. _fig-copy-paste-routine: .. figure:: fig03/copy-paste-routine.png :width: 50% ルーチンのコピー&ペーストおよび削除。コンポーネントの名前が重複しないように、ペーストされたルーチン内のコンポーネント名には元のコンポーネント名にアンダーバー+数字が自動的につけられます。 ルーチンの新規作成、コピー&ペーストときたら、削除と名前変更の方法についても知りたいところです。削除はルーチンペイン左上のタブから行います。現在選択中のタブにはルーチン名の右に×マークが表示されています。この×を左クリックすると、そのタブのルーチンが削除されます( :numref:`fig-discard-routine` )。誤って削除してしまった場合はすぐにツールバーの元に戻すボタンをクリックしましょう。 .. _fig-discard-routine: .. figure:: fig03/discard-routine.png :width: 50% ルーチンを削除するにはタブに表示されている×をクリックします。誤って削除してしまったなどの理由で削除を取り消したい場合は元に戻るボタンを使います。 続いてルーチンの名前変更ですが、バージョン1.84.0より前のBuilderを使用している場合は残念ながらルーチン名の変更が出来ません。あまりお勧めできる方法ではありませんが、psyexpファイルを直接編集することによって名前の変更を行うことは可能です。詳しくは第10章をご覧ください。PsychoPy 1.84.0以降を使用している場合は、フローペインで名前を変更したいルーチンを右クリックして「名前の変更」を選択するか、ルーチンペインで名前を変更したいルーチンを表示した状態で「実験」メニューから「Routineの名前を変更」を選択してください( :numref:`fig-rename-routine` )。 .. _fig-rename-routine: .. figure:: fig03/rename-routine.png :width: 50% フローペインのルーチンのアイコン上で右クリックするか、「実験」メニューから「Routineの名前を変更」を選択するとルーチン名を変更することが出来ます。 以上で第3章の解説を終えたいとと思います。簡単な実験であればこの章の内容だけで十分に実現できるはずです。最後にこの章の締めくくりとして、この章で解説したテクニックを応用する練習問題を出しておきます。第3章の内容をマスターできたと思った方は是非挑戦してください。 チェックリスト - ルーチンを新たに作成してフローに追加することが出来る。 - 既存のルーチンをフローに追加することが出来る。 - フローからルーチンを削除することができる。 - フローペインの赤いルーチンと緑のルーチンが何に対応しているか説明することが出来る。 - 特定のKeyboardコンポーネントが検出したキー押しを記録しないように設定することが出来る。 - 既存のルーチンと同一の内容を持つ新しいルーチンをコピー&ペーストの機能を使って作成することが出来る。 練習問題:練習試行を追加しよう ------------------------------------------------ 先ほどはinstructionルーチンを終えて実験を開始する際に、実験参加者にスラッシュキーを確認させることも兼ねてスラッシュキーでinstructionルーチンを終了するようにしました。しかし、本来であれば本試行と同様の手続きの練習試行を数回体験させてから実験を開始するべきです。練習と本試行を別々のpsyexpファイルとして作成するのも良いのですが、ここでは練習問題ということで単一のpsyexpファイルで練習試行と本試行を実施するように改造してみましょう。 :numref:`fig-practice-add-practice` はこの練習問題で作成する実験の流れです。本試行と終了メッセージは本章で作成した実験から変更する必要はありません。教示はもうひとつルーチンを追加する必要があるでしょう。この練習問題のポイントは、いかに手間をかけずに練習試行を作成するかです。ヒントは「フローの中に同一のルーチンを複数回挿入できる」という点と、「練習試行と本試行はループ回数が違うだけで条件は同じ」という点の二点です。これでもまだピンと来なければ、 :numref:`fig-practice-add-practice` の一番下のフローも参考にしてください。 .. _fig-practice-add-practice: .. figure:: fig03/practice-add-practice.png :width: 80% 練習問題。本試行を開始する前に12試行の練習を行うように改造してみましょう。一番下は作成例のフローを示しています。 この章のトピックス --------------------------------------------------- .. _topic-how-to-confirm-key-name: 自分のキーボードで使えるキー名を確かめる ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Builderを起動し、ルーチンペインにKeyboardコンポーネントとTextコンポーネントを配置して以下のように設定してください。 - Keyboardコンポーネント - **名前** をtest_keyboardとする。 - **終了** を空白にする。 - **Routineを終了** のチェックを外す。 - **検出するキー $** を空白にする。 - Textコンポーネント - **終了** を空白にする。 - **文字列** に$test_keyboard.keysと入力する。$記号やピリオドには重要な意味があるので忘れずにつける。間に空白文字を含んではいけない(第4章、第6章参照)。 - **文字列** の横にある「更新しない」と書かれたプルダウンメニューを開いて「フレーム毎に更新する」を選択する。 - もし一度実行して字が小さすぎたりするようならば **単位** や **文字の高さ $** を調節する。 - 実験設定ダイアログ - Full-screen Windowのチェックを外す。このチェックを外しておかないとESCによる強制終了が効かなかった時に強制終了させるのが面倒なので忘れずにチェックを外しておく。 以上の設定を行ったら実験を保存して実行し、適当にキーボードのキーを押してみてください。押したキーに応じてスクリーン中央に文字列が表示されるはずです。これが押したキーに対応するキー名です。通常はESCキーを押すと強制終了できますが、この実験では画面上に escape とESCキーのキー名が表示されて実験が終了しない場合があります。その場合はあわてずにBuilderのウィンドウを選んで実験停止ボタンを押してください。実験が終了します。 .. _builtin-condition-editor: Builder組み込みの条件ファイル作成機能 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ループのプロパティ設定ダイアログにおいて、 **繰り返し条件** の入力欄の上にマウスカーソルを置いて右クリックすると、条件ファイルの編集ダイアログを表示することが出来ます( :numref:`fig-open-builtin-condition-editor` )。「パラメータ」の行のparam_Aなどと書かれている欄をパラメータ名に書き換え、「条件 01」以降の行に値を入力して条件ファイルを作成できます。「データ型」という行のプルダウンメニューはデータ型の指定に用います。値が文字列であればutf-8、数値であればint(整数)やfloat(小数)、 **位置 [x, y] $** やSize [w, h]で用いる[ ]で囲まれた数値の組み合わせの場合はlistを指定するとよいでしょう。条件数が足りない場合は「条件追加」、パラメータ数が足りない場合は「パラメータ追加」をクリックします。「プレビュー」ボタンを押して内容確認、「名前を付けて保存」をクリックしてファイルに保存します。 とても便利な機能のように見えますが、値のコピー&ペーストといった編集機能がExcelやLibreOffice Calcと比べて非常に貧弱なので、大規模な条件ファイルを作るのは困難です。また、条件ファイルの保存形式がPickleという特殊な形式ですので、後でExcelなどを使って開くことが出来ません。予算が足りない、大学の端末に勝手にインストールできないなどの理由でExcelを導入することが難しいでも、LibreOffice Calcであれば無料で利用できますし、インストールせずにUSBメモリに入れて利用できるポータブル版が用意されています。Calcを利用する方が良いと思います。 なお、xlsx形式の条件ファイルを **繰り返し条件** に指定している時に入力欄を右クリックすると、読み込んだ条件ファイルの内容をプレビューすることが出来ます。 .. _fig-open-builtin-condition-editor: .. figure:: fig03/open-builtin-condition-editor.png :width: 80% **繰り返し条件** の入力欄をクリックすると、Builder組み込みの条件ファイル作成ダイアログを開くことが出来ます。 .. _topic-test-reserved-names: Builderで使用できない名前を判別する ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Builderを起動し、適当なコンポーネントをルーチンに配置して、 **名前** に名前として使用したい文字列を入力してみましょう。文字列がPythonの予約語やPsychoPyのモジュール名、Builderの予約語に一致する場合は、図 3 33のようにプロパティ設定ダイアログの下部に赤色でエラーメッセージが表示されます。ダイアログ左下のOKボタンをクリックできなくなりますので、意図せずに予約語を名前に使用してしまった場合でもまず気づくでしょう。 .. _fig-check-valid-name: .. figure:: fig03/check-valid-name.png :width: 70% Builderで適当なコンポーネントをルーチンに配置して **名前** に文字列を入力することによって、その文字列が予約されていないかを確認することが出来ます。 この方法でチェックできるのは予約語などと一致する場合と、自分で定義した他のコンポーネントの **名前** や条件ファイルのパラメータ名などと一致している場合です。ただし、第4章で紹介する、読み込む条件ファイルを実行時に切り替える方法を用いている場合は、Builderは名前の重複を判断できません。実験作成者が管理する必要があります。 .. _topic-random-seed: 無作為化と疑似乱数 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 予測不可能な順序に並べられた数の列のことを乱数(または乱数列)と呼びます。乱数には、一様乱数や正規乱数など、値の出現確率の違いによってさまざまな種類があります。コンピュータゲームなどにおいて人間にとって予測困難な動作を実現する際には、乱数が非常によく用いられます。例えば「地図上を歩き回っていると予測困難なタイミングで敵と遭遇する」というゲームの場合、「地図上を一歩歩くごとに乱数の先頭から順番に値をひとつ取り出し、その値を20で割った余りが0であれば遭遇する」といった処理を行うと上手くいきます。10で割ると遭遇しやすくなり、100で割るとめったに遭遇しないといった具合に遭遇頻度の調節も出来ます。 このように便利な乱数ですが、実は完全な乱数を発生させるのは難しいことで、代用のために「乱数っぽく見える」数列を作成する方法がいろいろと考案されてきました。「乱数っぽく見えるけれども、実は確定的な計算によって生成されている数列」のことを疑似乱数と呼びます。疑似乱数にはシード(seed)と呼ばれるパラメータを持っており、シードの値が一定であれば毎回同じ数列が得られます。あまり良い例ではないかも知れませんが、関数 y=sin kx (kは定数)において、kの値が一定であればx=1,x=2,x=3,…の時のyの値は何度計算しても同じです。しかし、kの値を変えればx=1,x=2,x=3,…の時のyの値は変化します。y=sin kx程度の式であれば生成される数列に規則性があることはすぐにわかりますが、工夫して疑似的に乱数としての性質を持つ数列を生成するように考えられた式が疑似乱数というわけです。 Builderでは、 **乱数のシード $** が空白であれば、実験実行時にBuilderが適当なシードを決定して疑似乱数を発生させます。 **乱数のシード $** に整数が与えられていれば、それをシードとして疑似乱数を発生させます。そして、生成した疑似乱数を用いて条件の実行順を並び替えます。ですから **乱数のシード $** を指定すれば必ず同じ順番で繰り返しが行われるのです。 .. _topic-select-condition-rows: Loopのプロパティ設定ダイアログの **使用する行 $** について ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ この機能を使いこなすには第5章以降で学ぶ知識が必要なので、pythonの文法をご存じない方はひとまずこの機能は無視して先へ進むことをお勧めします。 **使用する行 $** は、条件ファイルで定義されている条件のうち、一部分だけを利用して実行したい場合に利用します。1行に1条件が定義されているので、使用したい条件が書かれている行番号をカンマ区切りなどで列挙します。注意が必要なのは、pythonは順番を表現するときは最初を「0番目」と書く点です(第8章)。 具体的な使用方法ですが、例えば今回の実験で条件ファイルの1行目と3行目に書かれた条件のみを実施する場合には :: "0,2" と書きます。" "を忘れないでください。他にもリストやタプル(第5章、第9章)を用いて :: (0,2) [0,2] という書き方も受け付けます。この場合は" "が不要です。連続する多数の行を指定する場合はスライス(第10章)を使用します。 :: [:20] 筆者は普段この機能を利用しないのですが、第5章で学ぶ「実験ダイアログからの情報の取得」を利用して、実行時に利用する行を指定するといった使い方が便利そうです。また、数か月、数年後に実験を再確認する必要が出てきた場合に備えて、条件ファイルにコメントを書いておいて、この機能を用いてコメント行を読み飛ばすといった使い方もできるでしょう。 .. _topic-dollar-character-in-string: $を含む文字列を提示する ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 本文中で、Textコンポーネントの **文字列** プロパティに$を入力すると条件ファイル内で定義されたプロパティの値を代入することが出来ると述べました。では、Textコンポーネントで「$を含む文字列を表示させたい」場合はどうすればいいのでしょうか。ただ$を書くとBuilderに「名前」として判断されてしまうため、目的を達成できません。一番シンプルな解決策は、「半角ではなく全角の$を使う」というものです。コンピュータにとって半角と全角の$は全く別の文字なので、問題なく表示することが出来ます。 どうしても半角の$を使いたい、という場合はエスケープ文字を利用する方法があります。エスケープ文字とは半角のバックスラッシュ( :math:`\backslash` )のことで、日本語フォントでは円記号(¥)として表示されます。こう書くと初心者の方は「エスケープ文字って何?」と「日本語フォントでは円記号で表示されるってどういう意味?」という二つの疑問を持たれることと思いますが、まずエスケープ文字の説明から始めましょう。 エスケープ文字の役割は、Builderにおける$の役割と似ています。例えばPythonのスクリプトにおいては、Targetという文字列がデータとして文字列を表すのか、データに対してつけられた名前(変数)を指すのかを区別するために、文字列の前後を半角のシングルクォーテーションまたはダブルクォーテーションで囲みます。 .. csv-table:: 変数と文字列の区別 Target, Targetという変数 \"Target\", Targetという文字列 言語によってダブルクォーテーションのみしか使えないなどの違いがありますが、このような表記は多くのプログラミング言語で用いられています。さて、Pythonの場合、シングルクォーテーションやダブルクォーテーション自体を含む文字列、例えば He said, "Please respond as quickly and precisely as possible." という文字列はどう表記すればよいのでしょうか。何も考えずに前後をダブルクォーテーションを付けてしまうと **"He said, "** Please respond as quickly and precisely as possible. **""** となってしまい、Pleaseからpossibleまではダブルクォーテーション囲まれていないことになってしまいます。Pythonは文字列をシングルクォーテーションで囲んでも良いのでシングルクォーテーションを使えば回避できるのですが、もう一つの回避方法として、「文字列中に含まれるダブルクォーテーションの前には\\を付ける」という方法が用意されています。この方法を使うと、先の文字列は "He said, **\\"** Please respond as quickly and precisely as possible. **\\"** " と表記することが出来ます。多くのプログラミング言語において、\\には「その直後に続く文字(列)を通常とは異なる方法で解釈させる」という役割があります。\\などの特別な文字によって、後続の文字を通常とは異なる方法で解釈させることをエスケープと呼び、エスケープによって異なる意味を示す文字列をエスケープシーケンスと呼びます。エスケープシーケンスを開始する記号(ここでは\\)はエスケープシーケンスプレフィックスやエスケープ文字などと呼びます。He said,…の例文では、\\"と書くことによって\\に続く " が「文字列の終了を表す」という通常の意味を失って、単なる " という文字だと解釈されています。もし皆さんが将来プログラミング言語を本格的に学習するのであれば、他にもさまざまなエスケープの例に出会うことになるでしょう。 BuilderのTextコンポーネントで$を含む文字列を表示したい場合にも、この\\によるエスケープが利用できます。つまり、\\$と書けば$を表示することが出来ます。ぜひ試してみてください。なお、本文中で述べた「Builderは条件ファイル内に書かれた$記号を単なる文字として解釈する」という話はこの問題でも同様ですので、Textコンポーネントの **文字列** プロパティの値を条件ファイルから読み込んで表示する場合にはエスケープをする必要はありません。$を含む文字列をそのまま表示することが出来ます。 最後に蛇足ですが、「日本語フォントでは円記号で表示されるってどういう意味?」という疑問にもお答えしておきましょう。コンピュータでは、文字を管理するためにすべての文字に数値を割り当てています。例えばアルファベットの大文字のAは0x41、Bは0x42、小文字のaは0x61が割り当てられています。この数値を文字コードと呼びます。困ったことに、現在のコンピュータでは歴史的な経緯から複数の文字コードが使用されており、ある文字コードで書かれた文書を別の文字コードで解釈すると、本来意図されていた文字とは全く別の文字として解釈されてしまいます。昔の電子メールで時々生じていた「文字化け」の原因のひとつが送信側と受信側で使用している文字コードの違いでした。今回問題になっているバックスラッシュ( :math:`\backslash` )は、初期のコンピュータからずっと利用され続けているASCIIコードという文字コードで0x5Cに割り当てられています。一方、日本のコンピュータで最初に用いられたJIS規格の文字コードでは、大半がASCIIと共通のコードが割り当てられていたのですが0x5Cには円記号(¥)が割り当てられていました。結果として、同じ0x5Cというコードの文字が、解釈に用いるコードによってバックスラッシュになったり円記号になったりするようになってしまったのです。現在のコンピュータでは、欧文フォントを用いて表示するとバックスラッシュで表示され、日本語フォントを用いて表示しなおすと円記号になるといった具合に使用するフォントによって表示が切り替わるという現象が見られます。 .. _topic-clock-resolution: PsychoPyの時間計測の精度について (上級) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 本文中でも述べた通り、PsychoPyの記録ファイルを確認すると、キーが押された時刻が 0.766847908126秒 のように小数点以下かなりの桁数が出力されています。この数値は一体何桁目まで信頼できるのでしょうか。 残念ながらこの疑問の答えはPsychoPyを実行しているハードウェアやOS、デバイスドライバに依存するので一概には答えられません。筆者が主にプログラムの開発等に使用しているPCでは、約2.6MHzのタイマーカウンターが使用されているようです。分解能は約260万分の1秒ですから :math:`3.8 \times 10^{-7}` 、0.38マイクロ秒です。Web上でいろいろな資料を確認する限り、この周波数はあまり高くない部類で、10MHzを超えるタイマーカウンターが利用できる場合もあるようです。反応時間を指標とした心理学実験の論文では「ミリ秒」の小数点1桁まで報告されることがしばしばありますが、その用途には十分な分解能があると言えます。 むしろ注意しないといけないのは、実験参加者がキー押しの動作をはじめてから実際に「キーが押された」とPsychoPyのプログラムまで到達する時間や、PsychoPyが「刺激を画面に描画せよ」という命令を実行してから、実際にそれがモニターに伝わって画面に表示されるまでの時間です。これらの値もやはりハードウェアやOS、デバイスドライバに依存するので一概に言えないのですが、「ゲーム用」などと謳われている高性能なキーボードやモニターでなければ、数十ミリ秒もの時間を要することも珍しくありません。 - 先行研究の結果と比較して平均反応時間が十数ミリ秒にわたってずれている場合は、機材が原因である可能性も考慮する。可能であれば先行研究と同一条件の追試を行っておき、そこで大きなずれがないか確認しておくことが望ましい。 - 複数の実験参加者を呼んで並行して実験を行う場合、実験に使用するハードウェアやソフトウェアは可能な限り統一する。 といった点を守っておけば、多くの実験において時間計測の精度が大きな問題となることはないと思います。