Shigeta のすべての投稿

230922 卒論進捗

実験Ⅰ

1. プログラム解説
 ソフトウェアArduino, Processing開発環境双方のプログラム解説が終わりました。また, ハードウェアの解説も終了したので, 卒論本文の方法が完成しました。

Arduino開発環境
Processing開発環境

2. 卒論本文
 ソフトウェアの解説に加え結果・考察を記入し, 本文完成。
 お時間があるときに, 添削をお願いします。

========================================================================

*訓練期間の表記に関して、漆師さんから「訓練~週間後」より「計測~回目」の方がわかりやすいとアドバイスをいただいて、表記を変えましたが、画像内で修正できていない部分がありますのでご承知おきください。
①修正前:「訓練期間:訓練初日, 1週間後, 2週間後, 3週間後」
②修正後:「訓練期間:計測1回目~計測4回目」

実験Ⅱ

1. データ収集
 一昨日, 実験参加者15名分のデータ収集が完了し, 実験終了とした。

2. 生理指標

① 訓練期間別_大学での計測

計測回数が増えるごとに, 訓練方向の差が開いていき、分別ができてきているように見受けられた。

③ 訓練期間および制御方略別_皮膚温変化量

計測4回目の制御方略「その他」が訓練方向の差が鮮明に見受けられる。

④ 訓練期間および性別ごとの皮膚温変化量

計測2回目以降の男性の皮膚温変化量は, 訓練方向の差がはっきりしてる。

⑤ 「性別×期間×方向」3要因4水準混合計画の分散分析

 「2(性別:男性, 女性)×4(訓練期間:計測1回目~計測4回目)×2(訓練方向:上昇/下降)」の3要因4水準混合計画の分散分析を行った結果, 性別および訓練期間の主効果は認められなかった。訓練方向の主効果が5%水準で認められた(F(1, 13)=7.01, p<.05)。また, 性別×訓練方向の交互作用は有意傾向であった(F(1, 13)=3.90, p<.10)。交互作用の効果が有意傾向であったため, 単純主効果の検討を行ったところ, 訓練方向と男性において1%水準で有意な差が認められた(p<.01)。

⑥ 「訓練期間×訓練方向×課題期間(1分ずつ)」3要因5水準混合計画の分散分析

 「4(訓練期間:計測1回目~計測4回目)×2(訓練方向:上昇/下降)×5(課題期間:1分目~5分目)」の3要因5水準混合計画の分散分析を行った結果, 訓練期間の主効果が有意傾向であった(F(3, 42)=2.41, p<.10)。訓練方向の主効果が有意傾向であった(F(1, 14)=3.96, p<.10)。課題期間の主効果は5%水準で有意な差が認めれた(F(4, 56)=3.56, p<.05)。また, 訓練方向×課題期間の交互作用の効果が1%水準で有意な差が認められた(F(4, 56)=4.85, p<.01)。訓練期間×課題期間の交互作用の効果が5%水準で有意な差が認められた(F(12, 168)=1.87, p<.05)。訓練期間×訓練方向の交互作用は有意な差が認められなかった(F(3, 42)=0.92, n.s.)。
 訓練期間の主効果が有意傾向であったため, Holm法による多重比較を行った結果, 有意な差は認められなかった。また, 課題期間について, 多重比較を行ったところ, 1分目より5分目の方が高かった(p<.05)

質問1
・他にも有意差がみられましたが、3要因の結果の見方がわかりません。
・グラフに表す際、1つにまとめるのではなく, 訓練期間(計測1回目~4回目)に分けて、計4つのグラフを作成方法でよろしいでしょうか。

3. 心理指標_自尊感情尺度(RSES-J)→分析やり直し

① 訓練期間ごとのRSES-J平均得点の推移

 「2(性別:男性, 女性)×4(訓練期間:計測1回目~計測4回目)」の2要因4水準混合計画の分散分析を実施したところ,性別の主効果は認められなかった(F(1, 13)=0.17, n.s.)。また, 訓練期間の主効果は有意傾向が認められた(F(3, 39)=2.32, p<.10)。Holm法による多重比較を行った結果, 有意な差は認められなかった。また, 訓練期間×性別の交互作用は有意な効果が認められなかった(F(3, 39)=2.05, n.s.)。

「群×計測回数×訓練方向」

 独立変数をRSES-Jの群(高群, 低群),計測回数, 訓練方向,  従属変数を皮膚温変化量として, 「2(群:高群, 低群)×4(計測回数:計測1回目~計測4回目)×2(訓練方向:上昇, 下降)」の3要因4水準混合計画の分散分析を実施したところ, 群の主効果に有意傾向(F(1, 12)=3.29, p<.10), 計測回数の主効果に有意傾向(F(3, 36)=2.34, p<.10), 訓練方向の主効果の有意傾向(F(1, 12)=4.09, p<.10)が認められた。また, 群×計測回数の交互作用に有意傾向な効果が認められた(F(3, 36)=2.85, p<.10)。
 計測回数の主効果が有意傾向であったため, Holm法による多重比較を行った結果, 計測1回目より2回目が高い(p<.05)。計測1回目より4回目が高い(p<.05)。
 群×計測回数の交互作用の効果が5%水準で有意であったため, 単純主効果の検討を行ったところ, 群と計測1回目に有意傾向(p<.10), 群と計測2回目に5%水準で有意(p<.05), 計測回数と高群に1%水準で有意な差が認められた(p<.01)。

「変動性×計測回数×訓練方向」

 独立変数をRSES-Jの変動性(安定, 不安定), 従属変数を皮膚温変化量として, 「2(変動性:安定, 不安定)×4(計測回数:計測1回目~計測4回目)×2(訓練方向:上昇, 下降)」の3要因4水準混合計画の分散分析を実施したところ, 変動性の主効果は認められなかった(F(1, 12)=1.98, n.s.)。計測回数の主効果に有意傾向が認められた(F(3, 36)=2.44, p<.10)。訓練方向の主効果に有意傾向が認められた(F(1, 12)=9.06,  p<.10)。また, 変動性×計測回数の交互作用の効果に有意傾向が認められた(F(3, 36)=2.43,  p<.10)。計測回数×訓練方向の交互作用では, 5%水準で有意な効果が認められた(F(3, 36)=3.17,  p<.05)。
 計測回数の主効果が有意傾向であったため, Holm法による多重比較を行った結果, 計測1回目より2回目が高い(p<.05)。計測1回目より3回目が高い(p<.05)。
 変動性×計測回数の交互作用の効果が有意傾向であったため, 単純主効果の検討を行ったところ, 変動性と計測2回目に有意傾向(p<.10), 計測回数と安定群に有意差が認められた(p<.01)。
 訓練方向×計測回数の交互作用の効果が5%水準で有意であったため, 単純主効果の検討を行ったところ, 計測回数と上昇訓練に有意(p<.05), 訓練方向と計測2回目に有意傾向(p<.10), 訓練方向と計測3回目に有意(p<.05), 訓練方向と計測4回目に有意差が認められた(p<.01)。

先行研究
 自尊感情の質問紙研究を調べたところ, 自尊感情の「高群/低群」「安定/不安定」の2パターンから見るのが主流のようだ。自尊感情が高群だからといって, 変動が激しかったり, 攻撃性を持つこともあるからだ(櫻井, 2014)。そのため, 有意差がでなくても「自尊感情の揺れ幅が小さく, 安定的であることが精神的健康や適応の指標となる」

⑤ 変動性・高群/低群の算出方法の確認

質問4

①高群/低群に分類したいのですが, 平均得点から割り当てでしょうか。
②変動性(安定, 不安定)に分類したいのですが, 標準偏差から割り当てでしょうか。
③上記2点について, 期間で推移をみたいのですが, 平均化して一つにまとめた後に折れ線をプロットすればいいのでしょうか。

4. 内省報告等

①実験中の制御方略別イメージ内容

*本実験で使用した制御方略は、「温冷感イメージ, 情動イメージ, イメージなし, その他」の4種類です。「その他」に関しては, 「温冷感, 情動イメージ」の併用。もしくは, 液晶ディスプレイの温度が変化するイメージなど, 文字通り制御方略1~3に該当しない方略です。

② 訓練期間別_実験後の内省報告

 計測最終日の実験参加者の体調不良率が, 1/3という状態。また, 眠いと回答した人の睡眠時間を確認したところ, 「1~3時間」のため, 実験による眠気ではなかった。

5. 卒論本文
方法まで記入済み。これから, 取得したデータを元に結果・考察を執筆。

===========================================================================

質問5

・実験Ⅰ:プログラム解説部分で, 卒論本文にプログラムの画像を添付いたしましたが, 画像内にコメント文を付けた方がいいでしょうか。
・実験Ⅲ(仮):8月の上旬に先生に発注依頼した「XIAO ESP32S3」の状況はいかがでしょうか。もし到着していて, 先生のお時間をいただければ日曜日などを利用して, 装置開発を行いたいです。

========================================================================

残りの分析
・「制御方略×期間×方向」
・カウンターバランス:「訓練順序×期間×方向」
・内受容感覚
・自宅での訓練
・訓練回数×計測回数×RSES-J

========================================================================

コメント

・抄録の余白幅を狭める。
・STBFでのメンストラムサイクルの論文を読む。

実験Ⅰ
・プログラムは資料として、別枠で添付する。引用文献のあと。
 →本文を読んでほしいから資料として添付。本文とは?
・本文はBF装置の機能面のみを記載する。
・プログラム内の説明で、「~」ではなく「から」と表記する。
・プログラム画像が見えにくい。高解像度の倍率100%でスクショ。
 →先駆者にならって,プログラムを4Kモニターでスクショして記載
・Processingもコメント文つける

実験Ⅱ
【生理指標】
・交互作用の表記「有意な効果が…」に訂正
・制御方略:最初は「温冷, 情動」だったが、回数を重ねていくうえで自分に合ったものを参加者自身が能動的に選んでいき、その他を選んだ人は訓練方向の区別ができていた。
・性差の考察:生理周期(メンストラムサイクル)から男性は環境が安定しているが、女性は体調不良や体温が上昇するなどから、性差がでたのではないか。海外の論文等を調べる。→今回得られた結果だと、「男性は徐々にうまくなる結果だった」。
・2要因の分析(訓練期間×訓練方向)は、性別や課題期間で3要因の分析をしているため、かさまし疑惑が生じるため消す。
・交互作用の図をプロットする。
・「訓練期間×課題期間」の交互作用をプロット
・交互作用の解釈に内省報告を用いて、考察を記載する。
・総括としては、従来の方法では装置が限られているうえ、クリニックに通わない限り訓練を行うことができない。しかし、装置10台作成し、クリニックだけではなく、装置を持ち帰ってもらい、日常的に訓練を行うことで、よりクリアな結果を得ることができる。

・皮膚温の変動として概日(24時間)・概月(1か月)リズムによる変動。
・概月リズム:女性の概月リズムに体温の変動がある。月経後の増殖機で低体温が続き、排卵日後・分泌期(黄体期)の前半にプロゲステロンの作用で「0.2~0.4℃」急上昇し、以後その水準を維持する。月経開始とともに急激に下降する(P224)。
・女性は生理周期により基礎体温は排卵期後に上昇し, 月経開始とともに急激に下降し, 卵胞期を通じて低体温にとどまる(P230)

【心理指標】
・縦軸を「0~」ではなく、「15~30」など範囲を狭めて見やすくする。
・とりあえず、群(高群/低群)の分析を優先して、変動性は忘れていい。
 →群分けしたら、生理指標と絡めて分析する

仮想殺人場面における目撃証言の信憑性について検討

はじめに
去年の前期に受講した司法犯罪心理学で、「授業で扱った内容に触れて、独自の研究を行って下さい。方法は何でもよい」とレポート課題を出された。ん?何でもいいっt…つまり自分の土俵に持ち込んでいいってことですよね。じゃあ文献調べて書くのも面白みがないから、Unity, Mixamo使って目撃証言の実験でもやるか!と思い立った次第。期限が近くて、結構雑な実験計画と結果だった。

ほんで、さっそく実験刺激の作成に取り掛かり、キャラ10分, ステージ5分程度で作成。キャラ作成に服装とか考えないといけないから、割と面倒くさかった記憶が。先行研究のステージ暗めにしたのがシリアスにするためだったか?

改めて読み返すとページ指定があってだが、文章がめちゃくちゃ。要は目撃証言の信頼性が、検査官の質問の仕方や証言が曖昧過ぎて、冤罪になる事例が多い。前者に関しては惜しくも断念したが、この研究では後者に焦点を充てて、直後・遅延再生(1時間後)群に分けて聞き取り調査を行った。刺激提示の流れとしては、女性の悲鳴が聞こえて、正面から犯人が逃走しながら、参加者とすれ違う。これを8試行数秒間隔で呈示して、最後に呈示したうち1人について、外見的特徴を答えてもらった。

結果
・画面が見えにくい→画質/ライトの角度の問題
・大まかに捉えてはいる→服の色や袖の長さ
・細かいところまでは覚えていない/画質が悪く見えていない
・直後再生群の方が誤答数が少ない

→質問の仕方もあるが、かなり大雑把な回答だった。これで誤答数がどうと言われても正直微妙な気がする。ほんで、回答するキャラも統一せにゃならんでしょうに、バラバラにした時点で問題のある研究すねぇ。

考察・展望
1. 実験刺激
・ステージ:路地にして、よりリアルにするかな
・犯人:統一っすね
・画質等:VRで呈示
・参加者:時間的にMain Cameraを固定にしたが、いっそのこと歩かせて場面に

2. 実験計画
・群ではなく条件でもいいかも→後から証言の撤廃もあるだろうし
・群分け:今回は遅延再生群を1時間後としたが、実際に警察官が通報を受けてからどれくらいで到着するかを検索して、より現実的に再現したいな。
・生理指標:場面遭遇時・すれ違い時のHRを測定, ST・SCで緊張度合い
・心理指標:一般感情尺度とか, VASでどれくらい証言に自信あるか
・スケジュール:「安静→刺激提示→安静」かな。刺激提示に関しては、どうだろう。仮に8試行呈示すると、現実場面では一回だしなぁ。ダミーは入れるべきか?わからんな。

この辺を含めて先行研究なり、データを揃えないと話にならねえや。あくまで個人の見解で止まるだろうし。それじゃあ意味がないや。でもそうだな。二段階で実験やるのも面白うなんだよな。それこそ、刺激提示して「群1:服装は?衝撃度合は?」「群2:明るい目の色だった?ガツンと突っ込んでた?」とか。あーなんか面白そう。え、でもこれやってそうなんだよな。どうなんだろ。Unityとは別でやってそうじゃん。やってなかったらやるわ。こんなん。面白うそうじゃんかよ。

ただ、手っ取り早いが、これは請野さんの卒論のように、匂い採取の段階で問題が起きて…っていう落ちになるのだろうか。あーこればっかりは、調べるか、やらないとわからないもんだな。仮にやってたら、先行研究の問題点を踏まえてか、再現実験になりそうだな。なんか再現実験だけはやりたくないんだよな。新しいことしたいし、発展させる方が好きだしな。やる意義を感じないんだよな。まあそれはどうでもいいけども。

HADで因子分析

はじめに
以前のブログで紹介した、統計ソフトHADについて紹介する。
今回は、DLからの一連の流れと、基礎統計量・因子分析の算出を行う。

インストラクション動画

心理学ではプロマックス回転

抽出方法・回転方法の説明

1. 抽出方法
・最尤法:母集団を推定する考え方。イメージとしては、全国規模。
・主因子法:今得られてるデータの中でまとめる方法。学生の中だけ。
・最小二乗法:よく使われる。尺度の単位を考慮する。

2. 回転方法
・プロマックス回転 (斜交回転)
 因子同士に相関があるようにまとめる方法。心理学は、人の心に関係するという共通事項があるので、相関があると見なしプロマックス回転を使う。
・バリマックス回転 (直交回転)
 反対に相関がないことを前提にする場合はバリマックス回転を使う。

因子分析手順
・分析1回目は, スクリープロットなどから因子数を予測する。
・分析2回目は, それをもとに因子負荷量を算出する。
・算出したら事前に建てた目安をもとに項目の削除を行う。目安としては, 共通性を0.2以下の項目は削除。パターン行列は0.4以上の項目で区切る。内的整合性の検討は, α=.80とするなど適宜調整する。
・分析3回目以降は, 項目の削除がある場合行う。
・残りは, 因子の命名, 下位尺度の算出。表の作成は, 因子負荷量・共通性・α係数・相関行列があればok.(固有率, 寄与率, 累積寄与率を書くことも)

質問紙研究の分析
・因子分析:尺度作成時 (作成しなくても行う場合も)
・相関分析:下位尺度得点から, 他に使用した尺度と
・分散, 重回帰分析:より詳細なデータが欲しいとき
・t検定:因子, 尺度内で, 高群/低群を25%ずつ抽出

因子分析のレポート(SPSS)
 過去に質問紙の作成を行って、因子分析・相関分析・t検定を行った例。統計ソフトは, SPSSを用いた。2年次に執筆したレポートだから書き方が間違いだらけ。表は動画内か先行研究などを参照してください。ついでにSPSSのマニュアルも添付。

マニュアル

====================================================================

余談(js-starとの比較)

js-starと分析結果が合うか確認してみた。
画像の通り、結果は合っていたが、なぜか有意差が出た時にHADのp値の表記がバグる。おそらく設定が足りてないんだと思うがなぜだ。まあでも、心理学レポートのフォーマットにあった図表もでるし、分析の選択も楽だし、外部ソフトを仲介せず、エクセル操作できるのはかなりお得。あとは使いこなせるかが問題

Processing_プログラム解説

はじめに
前回のBFプログラム解説に続き, processingのプログラムについて要点を絞って解説していく。 processingのプログラム解説が終われば, 卒論Ⅰは残りまとめだけ。

要点
・.csv発行
・時刻表示, カウント
・皮膚温の波形をプロット
・Arduino開発環境と連携し, シリアルモニタの値を確認(安静期間の確認も)

SBF230707(ST波形表示, シリアル通信)

import processing.serial.*;

Serial myPort;
String portName = "COM6"; //BT serial port
int baudRate = 115200;
int dataPlotWidth = 640;
int dataPlotHeight = 200;
float[] data = new float[5];
String[] dataMV = new String[5];
float[] prevData = new float[5];
color[] colors = {
  color(255, 0, 0), 
  color(0, 0, 255), 
  color(0, 0, 0, 0), 
  color(0, 0, 0, 0)
};
int datacount=0;
String OutFileName;
String buf2;
PrintWriter writer;
int startMillis;


void setup() 
{
  //size(dataPlotWidth, dataPlotHeight);
  size(600,500);
  myPort = new Serial(this, portName, baudRate);
  
  OutFileName=getTimestamp()+".csv";
  writer = createWriter("./data/"+OutFileName); // Create a new file in the sketch directory
  buf2="";

}

void draw()
{
  
  if((datacount % 600) == 0) {
    background(255);  // clear screen    
    fill(0, 0, 0); // set the fill color to black
    textSize(12);
    text("40 deg", 10, 20); // 
  }
  
  while (myPort.available() > 0) 
  {
    String inString = myPort.readStringUntil('\n');
    
    if (inString != null) 
    {
      inString = trim(inString);
      String[] parts = split(inString, ',');
      
      if(parts.length >3) 
      {
        for (int i = 0; i < 5; i++) 
        {
          prevData[i] = data[i];
          data[i] = map(float(parts[i]), 20, 40, 0, 500);  // Assuming your data is in the range 0-200
          dataMV[i] = parts[i];
          
        }
        String stamp=getTimestamp2();
        String etime= getElapsedTime();
        String buf=stamp+","+etime+","+dataMV[0] + "," + dataMV[1] + "," + dataMV[2] + "," + dataMV[3] + "," + dataMV[4];
        println(buf);
        buf2=buf2+buf+"\n";
        
        if(datacount%10==0){
          writer.print(buf2);
          writer.flush();
          buf2="";
        }

        int xp = datacount%600;
        strokeWeight(1);
        for (int i = 0; i < 1; i++) 
        {
          stroke(colors[i]);
          line(xp-1, 500 - prevData[i], xp, 500 - data[i]);
        }
        
        drawCurrentTime();
        drawElapsedTime();

    
        datacount++;
      }
    }
  }
}

void stop() {
  writer.flush(); // Writes the remaining data to the file
  writer.close(); // Finishes the file
  super.stop();
}

Subroutine1(現在時刻, 経過時間)

String getTimestamp() {
  int y = year();
  int m = month();
  int d = day();
  int h = hour();
  int min = minute();
  int s = second();

  // Use nf() to add leading zeroes to each time component if needed
  String timestamp = nf(y, 4) + nf(m, 2) + nf(d, 2) + "_" + nf(h, 2) + nf(min, 2) + nf(s, 2);
  
  return timestamp;
}

String getTimestamp2() {
  int h = hour();
  int min = minute();
  int s = second();

  // Use nf() to add leading zeroes to each time component if needed
  String timestamp =  nf(h, 2) +":"+ nf(min, 2) +":"+ nf(s, 2);
  
  return timestamp;
}

void drawCurrentTime()
{
  String stamp2=getTimestamp2();
  fill(255); noStroke();
  rect(450, 5,130,50); 
  fill(0); stroke(0);textSize(24); 
  text(stamp2, 450, 30); //   
}

void drawElapsedTime()
{
  String elapsedTime = getElapsedTime();
  fill(255); noStroke();
  rect(450, 55,130,50); 
  fill(0); stroke(0);textSize(24); 
  text(elapsedTime, 450, 60);
}

String getElapsedTime() {
  int elapsedMillis = millis() - startMillis;

  int s = elapsedMillis / 1000;
  int m = s / 60;
  int h = m / 60;

  s = s % 60;
  m = m % 60;

  return nf(h, 2) + ":" + nf(m, 2) + ":" + nf(s, 2);
}

生理心理学実験_資料Ⅰ

Ⅰ計測準備

1. 主な生理指標
 ①皮膚温(Skin Temperature):リラクセーションの指標 ex)匂い, 自然環境
 ②皮膚コンダクタンス(Skin Conductance):感情やストレス ex)お笑い, ホラー
 ③心拍数(Heart Rate):身体活動,集中程度    ex)運動, 映像視聴
 ④心拍変動(Heart Rate Variability):健康,リラックス   ex)睡眠の質
 ⑤心電図:心臓の電気活動 (心臓/心拍のどちらに焦点を当てるか)

*1)  ストレス反応は,瞬時的なもの(皮膚コンダクタンス),ゆっくりしたもの(皮膚温)があるため,実験計画を踏まえどちらを使用するか判断する。ストレス, リラックス時の各生理反応は下記の通り。

2. 計測に必要なもの

 ①皮膚温:緑の計測器, メンディングテープ
 ②発汗のみ:透明の計測器, みの虫クリップ, ピンク色の電極, 手袋
 ③心拍数, 発汗:透明の計測器, 電極, 手袋
 ④ Polar H10(心拍数, 心拍変動):黒色の計測機,水(小皿程度)
 ⑤Polar Unite(心拍数, 歩数, 睡眠など):腕時計型の計測器

*2)  発汗のみ計測する場合, 「②」を使用してください。また, 青色の電極は心電図に使用するので,ピンク色の電極を使用してください。
*3)  心拍数の計測精度は, 「③→④→⑤」の順番です。運動時の心拍数を計測する際は, Polar Uniteがおすすめです。

3. 計測リンク
 計測機(①~③)はそれぞれ機体名が割り振らており,こちらのリンク内「http://kodamalab.sakura.ne.jp/~~~~~/showchannels.php」の赤文字に入力すると計測中のデータが確認できます。

 ①皮膚温:http://kodamalab.sakura.ne.jp/M2TP/showchannels.php
 ②発汗:http://kodamalab.sakura.ne.jp/M2/showchannels.php
 ③心拍数, 発汗:http://kodamalab.sakura.ne.jp/M5log/showchannels.php

*4)   Polar(計測機④, ⑤)は, 確認方法が異なるため, こちらのリンク(http://protolab.sakura.ne.jp/LAB01/?p=22881)を参照してください。

4. 計測方法
 ①皮膚温:右下スイッチを入れる (左下ボタンはイベント記録)
 ②皮膚コンダクタンス:右下スイッチを入れ,左下ボタンを押す(赤く光ればok)
 ③心拍数, 発汗:(センサを上向きとして)右下のボタンを長押し

*5) 波形が緩やかな放物線を描いていれば正常だが, ギザギザした波形の場合, 計測が失敗している可能性が高い(ex.センサの装着に問題)。

=======================================================================

Ⅱ 参照サイト

1. 計測機の引用文献
・皮膚温/心拍数, 発汗:長野・吉田(2018).
・発汗(単一):長野他(2019).
・Polar Unite/H10:POLAR社製

2. 基礎実験
・皮膚温:リンク
・発汗:リンク

3. 分析方法の解説
・分散分析等:リンク

=======================================================================

HADを使ってみる

はじめに
 卒論の統計処理を行おうとしたものの、js-starでは3要因の分散分析までしかできないことを知った。以前のブログで分析候補を挙げたところ、生理指標の大半が4, 5要因分散分析のため、かなり厳しめである。sasはちょいと面倒だし、だからといってspssを使うにも一々大学行って、21:50までしかできないから、新たなる統計ソフトのHADを使ってみる。分析したら、図表を作ってくれるらしい。

HADの詳細
・機能一覧:こちら
・DLサイト:こちら

BFプログラムの解説

はじめに
 卒論実験ⅠのBF装置の開発にソフトウェアの解説も取り入れるため、ChatGPTを用いてプログラムを解読中。といっても長野(2022)の測定器開発で半分書いてあるから、「FB有無の切り替え, 液晶ディスプレイ, 安静管理の自動化」を組み込めば終わり。Processingのプログラム解説もつけるべきか?

プログラム

#include <Adafruit_NeoPixel.h>  //LEDのライブラリ
#include <ST7032_asukiaaa.h>    //液晶ディスプレイのライブラリ

#define PIN        3   //LEDの制御ピン
#define NUMPIXELS 1    //LEDの数

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);   //LEDのライブラリを使用
ST7032_asukiaaa lcd;        //液晶ディスプレイのライブラリを使用

const int switchPin = 7;    //FB有無の切り替えに用いるスイッチ

double mv, temp0, temp1, tempd;   //温度データを格納する変数
double sum, average;    //温度データの合計値と平均値を格納
long t, t0, cnt;      //現在の時刻・温度データをサンプリングした時の時刻・温度データのサンプリング数
int Bpin = 2;  //ブザーPIN2

const int HISTORY_SIZE = 180; // 履歴のサイズ
double history[HISTORY_SIZE]; // 測定値の履歴
int historyIndex = 0;         // 履歴のインデックス

double minTemp = 0.0;  // 最小温度
double maxTemp = 0.0;  // 最大温度

bool readyFlg=false;  //安静準備フラグ

void setup() {
  pinMode(switchPin, INPUT_PULLUP);  // 内部プルアップ抵抗を有効にする

  pinMode(Bpin, OUTPUT);
  pinMode(13, OUTPUT);
  Serial.begin(115200);  //シリアル通信115200
  analogReference(INTERNAL); //参照電圧を1.1Vに設定
  cnt = sum = 0;
  pixels.begin();      //LEDを初期化

  lcd.begin(8, 2);     //液晶ディスプレイで8列2行で指定表示
  lcd.setContrast(5);  //液晶ディスプレイのコントラスト
}

void loop() {
  t0 = t;
  t = millis();        //現在時刻をms単位で取得
  mv = (double)1100 / (double)1024 * analogRead(0);  //デジタル値を電圧に変換
  sum = sum + mv;
  cnt++;        //サンプリング数のカウント
  if (t0 / 1000 != t / 1000) {    //1秒(100ms)毎に平均算出
    average = sum / (double)cnt;  //平均を計算

    temp0 = temp1;                //前回の温度を保存
    temp1 = average * 0.1;        //電圧を温度に変換
    tempd = temp1 - temp0;        //温度変化量を算出

    int mag, dir;                 //変化の程度(mag)と方向(dir)
    if (tempd > 0) {
      mag = abs(tempd * 100);
      dir = 1;                    //温度上昇時
    } else if (tempd <= 0) {
      mag = abs(tempd * 100);
      dir = -1;                   //温度下降時
    }

    int switchState = digitalRead(switchPin);

    if (switchState == LOW) {   //FBスイッチがオフの時に
      pixels.clear();
      if (dir == 1) {
        pixels.setPixelColor(0, pixels.Color(mag, 0, 0)); //温度上昇を赤で表示
        if (mag > 0) {
          tone(Bpin, 500, 10);    //温度上昇時は500Hz
        }
      }
      if (dir == -1) {
        pixels.setPixelColor(0, pixels.Color(0, 0, mag)); //温度下降を青で表示
        if (mag > 0) {
          tone(Bpin, 1000, 10);   //温度下降時は1000Hz
        }
      }
    } else if (switchState == HIGH) {         //左下のスイッチを入れるとFBなし
      pixels.setPixelColor(0, pixels.Color(0, 0, 0));    //LEDを消す
      noTone(Bpin);         //ブザー音を消す
    }

    pixels.show();

    Serial.print(temp1); //現在温度
    Serial.print(",");   //カンマ区切り
    Serial.print(tempd); //温度変化量
    Serial.print(",");
    Serial.print(mag);   //変化の強さ
    Serial.print(",");
    Serial.print(cnt);   //サンプリング数

    if(readyFlg==true){
      Serial.print(",***"); //安静期間終了時に「***」表示
    }
    else{
      Serial.print(",---"); //安静期間が終了していない場合「---」表示
    }
    
    Serial.println();   //シリアルモニタに「***/---」を表示するための空行
    sum = 0;    //合計値の初期化
    cnt = 0;
    delay(10);  //10ms単おきに行う

    history[historyIndex] = temp1;  //温度データを記録するための配列
    historyIndex = (historyIndex + 1) % HISTORY_SIZE;  //新しい温度データを保存

    minTemp = history[0];   //最小温度をデータの最初の要素で初期化
    maxTemp = history[0];   //最大温度をデータの最初の要素で初期化

    for (int i = 1; i < HISTORY_SIZE; i++) {  //温度データから最小・最大温度を算出
      if (history[i] < minTemp) {   //データ内で最小温度より低い場合
        minTemp = history[i];       //最小温度を更新
      }
      if (history[i] > maxTemp) {    //データ内で最大温度より低い場合
        maxTemp = history[i];        //最大温度を更新
      }
    }

    //3分間の皮膚温の変動が0.4℃以内の時にアスタリスク表示
    if (maxTemp - minTemp <= 0.4) {   //最大・最小温度の差が0.4℃以内の場合
      lcd.setCursor(7, 0);        //液晶ディスプレイの右上に
      lcd.print("*");             //「*」表示
      //Serial.println("***");
      readyFlg=true;
    } else {                      //条件を満たさなかった場合
      lcd.setCursor(7, 0);        //液晶ディスプレイの右上に
      lcd.print(" ");             //何も表示しない
    }

    String buf1, buf2;
    buf1 += temp1;      //buf1は現在温度
    buf2 += tempd;      //buf2は温度変化量

    lcd.setCursor(0, 0); //液晶ディスプレイの1行目にカーソルを移動
    lcd.print(buf1.c_str()); //1行目に現在温度を表示
    lcd.setCursor(0, 1);    //液晶ディスプレイの2行目にカーソルを移動
    lcd.print(buf2.c_str());  //2行目に温度変化量を表示
  }
}

【液晶ディスプレイ】

#include <ST7032_asukiaaa.h>    //液晶ディスプレイのライブラリ

ST7032_asukiaaa lcd;  //液晶ディスプレイのライブラリを使用

double temp1, tempd;   //温度データを格納する変数

double minTemp = 0.0;  // 最小温度
double maxTemp = 0.0;  // 最大温度

void setup() {
  lcd.begin(8, 2);     //液晶ディスプレイで8列2行で指定表示
  lcd.setContrast(5);  //液晶ディスプレイのコントラスト
}

void loop() {
  //3分間の皮膚温の変動が0.4℃以内の時にアスタリスク表示
  if (maxTemp - minTemp <= 0.4) {   //最大・最小温度の差が0.4℃以内の場合
    lcd.setCursor(7, 0);        //液晶ディスプレイの右上に
    lcd.print("*");             //「*」表示
    readyFlg=true;
  } else {                      //条件を満たさなかった場合
    lcd.setCursor(7, 0);        //液晶ディスプレイの右上に
    lcd.print(" ");             //何も表示しない
  }

  String buf1, buf2;
  buf1 += temp1;      //buf1は現在温度
  buf2 += tempd;      //buf2は温度変化量

  lcd.setCursor(0, 0); //液晶ディスプレイの1行目にカーソルを移動
  lcd.print(buf1.c_str()); //1行目に現在温度を表示
  lcd.setCursor(0, 1);    //液晶ディスプレイの2行目にカーソルを移動
  lcd.print(buf2.c_str());  //2行目に温度変化量を表示
}

【安静期間の自動管理化】

double temp1;   //現在温度のデータを格納する変数
double sum, average;    //温度データの合計値と平均値を格納
long cnt;      //温度データのサンプリング数

const int HISTORY_SIZE = 180; // 履歴のサイズ
double history[HISTORY_SIZE]; // 測定値の履歴
int historyIndex = 0;         // 履歴のインデックス

double minTemp = 0.0;  // 最小温度
double maxTemp = 0.0;  // 最大温度

bool readyFlg=false;  //安静期間のフラグ


void loop() {

    if(readyFlg==true){
      Serial.print(",***"); //安静期間終了時に「***」表示
    }
    else{
      Serial.print(",---"); //安静期間が終了していない場合「---」表示
    }
    
    Serial.println();   //シリアルモニタに「***/---」を表示するための空行
    sum = 0;    //合計値の初期化
    cnt = 0;
    delay(10);  //10ms単おきに行う

    history[historyIndex] = temp1;  //温度データを記録するための配列
    historyIndex = (historyIndex + 1) % HISTORY_SIZE;  //新しい温度データを保存

    minTemp = history[0];   //最小温度をデータの最初の要素で初期化
    maxTemp = history[0];   //最大温度をデータの最初の要素で初期化

    for (int i = 1; i < HISTORY_SIZE; i++) {  //温度データから最小・最大温度を算出
      if (history[i] < minTemp) {   //データ内で最小温度より低い場合
        minTemp = history[i];       //最小温度を更新
      }
      if (history[i] > maxTemp) {    //データ内で最大温度より低い場合
        maxTemp = history[i];        //最大温度を更新
      }
    }

    //3分間の皮膚温の変動が0.4℃以内の時にアスタリスク表示
    if (maxTemp - minTemp <= 0.4) {   //最大・最小温度の差が0.4℃以内の場合
      lcd.setCursor(7, 0);        //液晶ディスプレイの右上に
      lcd.print("*");             //「*」表示
      //Serial.println("***");
      readyFlg=true;
    } else {                      //条件を満たさなかった場合
      lcd.setCursor(7, 0);        //液晶ディスプレイの右上に
      lcd.print(" ");             //何も表示しない
    }

①測定している値を60回分覚えるプログラム

const int HISTORY_SIZE = 60; // 履歴のサイズを60に変更
double history[HISTORY_SIZE]; // 測定値の履歴
int historyIndex = 0;         // 履歴のインデックス


// 履歴に温度データを追加する部分
history[historyIndex] = temp1;  //温度データを記録するための配列
historyIndex = (historyIndex + 1) % HISTORY_SIZE;  //新しい温度データを保存

②180個覚えた履歴の中から最大値と最小値を求めて, その差を算出するプログラム

const int HISTORY_SIZE = 180;   // 履歴のサイズ
double history[HISTORY_SIZE];   // 測定値の履歴
int historyIndex = 0;           // 履歴のインデックス
double minTemp = 0.0;  // 最小温度
double maxTemp = 0.0;  // 最大温温度

void loop() {
    history[historyIndex] = temp1;                  // 温度データを記録するための配列に保存
    historyIndex = (historyIndex + 1) % HISTORY_SIZE; // 新しい温度データを保存するインデックスを更新

    minTemp = history[0];   // 最小温度をデータの最初の要素で初期化
    maxTemp = history[0];   // 最大温度をデータの最初の要素で初期化

    // 温度データから最小・最大温度を算出
    for (int i = 1; i < HISTORY_SIZE; i++) {
        if (history[i] < minTemp) {
            minTemp = history[i];   // 最小温度を更新
        }
        if (history[i] > maxTemp) {
            maxTemp = history[i];   // 最大温度を更新
        }
    }
}

③最大値と最小値の差が0.4℃以内であった場合は, 液晶ディスプレイにアスタリスクを表示するプログラム

const int HISTORY_SIZE = 180;   // 履歴のサイズ
double history[HISTORY_SIZE];   // 測定値の履歴
int historyIndex = 0;           // 履歴のインデックス
double minTemp = 0.0;           // 最小温度
double maxTemp = 0.0;           // 最大温度

void loop() {
    history[historyIndex] = temp1;  // 温度データを記録するための配列に保存
    historyIndex = (historyIndex + 1) % HISTORY_SIZE;  // 新しい温度データを保存するインデックスを更新

    minTemp = history[0];   // 最小温度をデータの最初の要素で初期化
    maxTemp = history[0];   // 最大温度をデータの最初の要素で初期化

    // 温度データから最小・最大温度を算出
    for (int i = 1; i < HISTORY_SIZE; i++) {
        if (history[i] < minTemp) {
            minTemp = history[i];   // 最小温度を更新
        }
        if (history[i] > maxTemp) {
            maxTemp = history[i];   // 最大温度を更新
        }
    }

    // 最大・最小温度の差が0.4℃以内の場合、アスタリスク表示
    if (maxTemp - minTemp <= 0.4) {
        lcd.setCursor(7, 0);  // 液晶ディスプレイの右上に
        lcd.print("*");       // 「*」表示
    } else {
        lcd.setCursor(7, 0);  // 液晶ディスプレイの右上に
        lcd.print(" ");       // 何も表示しない
    }
}

【FB有無の切り替え】

#include <Adafruit_NeoPixel.h>  //LEDのライブラリ
#include <ST7032_asukiaaa.h>    //液晶ディスプレイのライブラリ
 
#define PIN        3   //LEDの制御ピン
#define NUMPIXELS 1    //LEDの数
 
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);   //LEDのライブラリを使用

const int switchPin = 7;    //FB有無の切り替えに用いるスイッチ
int Bpin = 2;  //ブザーPIN2

void setup() {
  pinMode(switchPin, INPUT_PULLUP);  // 内部プルアップ抵抗を有効にする
  pinMode(Bpin, OUTPUT);

void loop() {
  int switchState = digitalRead(switchPin);
 
  if (switchState == LOW) {   //FBスイッチがオフの時に
    pixels.clear();
    if (dir == 1) {
        pixels.setPixelColor(0, pixels.Color(mag, 0, 0)); //温度上昇を赤で表示
      if (mag > 0) {
        tone(Bpin, 500, 10);    //温度上昇時は500Hz
      }
    }
    if (dir == -1) {
      pixels.setPixelColor(0, pixels.Color(0, 0, mag)); //温度下降を青で表示
      if (mag > 0) {
        tone(Bpin, 1000, 10);   //温度下降時は1000Hz
      }
    }
  } else if (switchState == HIGH) {         //左下のスイッチを入れるとFBなし
    pixels.setPixelColor(0, pixels.Color(0, 0, 0));    //LEDを消す
    noTone(Bpin);         //ブザー音を消す
  }

230714 進捗報告

進捗

1. 装置10台作成

・10台分作成完了
・毎週10人計測中→7~8月まで
・ストラップを100均で追加購入
・新しい3Dプリンタでケース作成

2. イメージ方略の選択

選択
訓練2週間後の参加者が「イメージなし方略」を選択するようになった。

理由
・温冷感, 情動イメージなどイメージするネタが尽きた
・イメージ無しだとイメージする手間が省けて皮膚温制御に没頭できる

しかし、イメージ方略を使用して慣れてきたため、訓練1週目からイメージ無しは難しいかもとのこと。そのため、訓練1週目にイメージ方略(情動, 温冷感)で感覚を掴み、以降イメージ無しで訓練を行う方法は有効?実験Ⅲや分析

3. Processing3.5.4

安静終了の合図を液晶ディスプレイ, シリアルモニタに表示するようにした。さっそく実験に導入し、動作上の問題は今のところ見られない。

4. 3週間の訓練を終えた感想

①自宅などでの訓練
・訓練を負荷と感じず、むしろリラックスできる時間となった。楽しい
・毎日寝る前に訓練を行う習慣をつけたら、眠りやすくなった。
・当初より上達した、コツを掴めた
・学内で装置を身に着けている人と訓練した
・自分の体の変化に気を向ける機会がついた

②改善点
・エンターテインメント性は欲しい(訓練が上手くいくとモニタに犬の画像などランダム表示。日によって変われば、訓練のモチベアップ?)
・自宅での訓練で、安静2分が面倒(いきなり訓練を始めたい)
・モニタの数値だとわかりづらいため、折れ線グラフとかにしてほしい

5. 生理指標

大学での各訓練期間別の皮膚温制御成績を図に示した。訓練3週間後以外、訓練間であまり差はみられない。

・訓練初日12名
・1週間後8名
・2週間後5名
・3週間後5名

6. 心理指標(RSES-J)

心理指標RSES-Jの平均得点を図に示した。「訓練初日~3週間後」までの実験参加者5名を対象に、1要因4水準参加者内の分散分析を行った結果、有意差は認められなかった。

===================================================================

質問内容

・プロセッシングのエラー

===================================================================

やる事

・参加者16~18名を今月中に取る
・装置の修繕
・研究計画書の作成

===================================================================

ご指摘

・Processingの問題に関しては、配列の問題。要はプログラム側で指定したデータ容量の値が不足しているため、500から900や1200に変更すれば解決される。
・生理指標の分析に関しては、長野・廣田先生の論文のように皮膚温変化量を算出する。基礎実験の皮膚温計測のように、「安静・課題期間の最後1分間」を基準に変化量を算出する。下記動画が変化量の算出例。

「皮膚温変化量=課題期間-安静期間」

統計処理
・各期間:1要因4水準の分散分析/2要因4水準の分散分析(訓練による)
・訓練別:上昇・下降訓練で対応ありのt検定を行う

第29回精神神経内分泌免疫学研究会_東工大

はじめに
東工大で内分泌免疫学研究会が開催されるとのことで、さっそく行ってきた。電車の外回りと内回りがよくわからなくて道に迷ったが、いつものことなので慣れた。去年の研究交流会依頼で久々に行ったが、チーズケーキとか建築物がすごかった。

講演
正直、心理学についての内容が来るものだと思ってたから、小講演で栄養学について語られてびびった。ただ、時間栄養学では、酸化ストレス・肥満などへの対策として、どの時間帯に食品を摂取すべきか。また運動栄養学では、筋トレ(運動量・タンパク質の摂取タイミング)など興味がひかれるような内容で、かつ分かりやすく面白かった。
講演1の内受容感覚に関しては、以前の交流会で大雑把には知っていたが、もうほぼほぼ完成してた。内受容の超短縮版BPQ-BA?を使ってた。それにしても、ストレス系の内受容と生理指標(HR, SCL, コルチゾール?)との関連が先行研究で検討されていないのは知らなかった。いっそのことSTBFで検討するかなぁ。卒論で内受容感覚の心理指標MAIAを使用するため、定義・敏感さ(IS)・正確さ(IAc)について改めて学び直す機会となった。

講演3の爪からのストレス検討については、聞いたことのない内容だったため、参加前からかなり気になっていた。毛髪や唾液のようにコルチゾールを検出するようで、マイナーらしい。違いとしては、爪は累積的に評価され、唾液は即時的な反応を検出するらしい。実験時期がコロナ渦のため、剰余変数である手洗い・手指消毒が結果に影響を及ぼしたような内容を語っていた。分析としては、「爪採取→粉砕→検査にかける」といった手順らしい。先端1mmで10日分のコルチゾール採取できるらしい。これを15日おきに採取ってことは1mm×15日(1ヶ月)??ってことは( ^ω^)・・・

なんにしてもめちゃくちゃ面白かった。本学では、コルチゾールの実験なんてやらないし、小川奈美子先生は非常勤だしで、教わる機会がないから新しい知識を蓄えられて満足…とまではいかないけど、機械があれば計測の方を体験したいな。下のファイルが講演時に取ったメモ帳。スカスカだからたぶんわからんと思うぞ。

内受容感覚

メモ
卒論の書きたしで、緒言もしくは心理指標の欄に内受容感覚, MAIAの使用理由とISなど軽く触れておく。今のところRSES-JはSTBFの臨床系の先行研究で実証されているが、MAIAに関しては、特に書かれていなかったよう気がしたから尚更記載が必要。

本実験 事前準備

実験環境

1. メモ
・室温24~26℃
・パーテーション2枚
・モニタ
・マスキングテープ
・計測機器(BF装置, PC, USB)

(BF装置配布時に、単4電池3本・教示文スライドを忘れずに)

2. 注意点
・窓は閉める
・室温は適切か
・センサに風は当たってないか

データ関連

1. Forms(編集者用)
計測初日:MAIA, 事前質問
計測4回分:Rosenberg, 独自項目→完成!!
自宅訓練:訓練時の温度など→インストラクション挿入のみ
実験参加のお願い:第1~3希望

2. Forms(参加者用)
・計測初日:リンク
・計測4回分:リンク
・自宅訓練:BF装置裏面に添付
・実験参加のお願い:リンク

3. 教示文