!!! サイト改修中のため表示が乱れる場合があります(1月末頃まで) !!!
雑記

26-8. 人文系の研究で卒業できなかった卒論のお話(後編)

はじめに

前編ではAさんの研究の悪かった点として「対照群(コントロール)がない」「現役教員へのヒアリング方法が適切でない」ことを挙げました。早速これらを検証・検討してみましょう。

コントロール実験

コントロールの設計

Aさんは「既存のデータを解析する場合は今更コントロール実験なんてできないでしょ」と思っていましたが、生徒たちの対照実験はできなくても解析方法のコントロールはできます。それは、「解析手法をランダムデータに適用するとどれくらいの大問が抽出されるか」を調べることです。ランダムデータ(無意味なデータ)でも同じように5問くらい抽出されるようであれば、Aさんの結果は意味があるか甚だ疑問になってしまいますので、願わくば1問も抽出されてほしくありません。さっそくやってみましょう。

コントロール実験(Pythonで)

生徒数100、大問数500、t検定の有意水準を1%とします。高1時の500問のスコア(各20点満点)を正規分布で生成します。また、入学した大学(学部)の偏差値も正規分布で生成します。これらはまったく無意味なデータです。

import numpy as np
import numpy.random as nr
import scipy.stats as stats
import matplotlib.pyplot as plt

#乱数シード
nr.seed(0)

#パラメータ
num_student = 100
num_question = 500
p_border = 0.01


#高校1年時の様々なテストの大問スコア
ko1_score = (nr.randn(num_student, num_question) * 3 + 12).astype(int)
ko1_score = np.clip(ko1_score, 0, 20)
#確認
print(ko1_score.shape)
plt.hist(ko1_score.flatten(), bins=range(0, 21, 1))
plt.xlim(0, 20)
plt.show()

#入学大学(学部)の偏差値
hensachi = (nr.randn(num_student) * 9 + 50).astype(int)
hensachi = np.clip(hensachi, 25, 75)
#確認
print(hensachi.shape)
plt.hist(hensachi, bins=range(0, 101, 5))
plt.xlim(0, 100)
plt.show()
(100, 500)
(100,)

高1時の大問のスコアはこのような分布に

入学した大学(学部)の偏差値はこのような分布に(ちょっと正規分布に見えないですが)

次に、「高偏差値集団」と「低偏差値集団」のマスクを作成します。

#大学偏差値が高い人のマスク、低い人のマスク
high_mask = (hensachi >= 60)
print(np.sum(high_mask))
low_mask = (hensachi <= 40)
print(np.sum(low_mask))

#大学偏差値が高い人の大問スコア、低い人の大問スコア
ko1_score_high = ko1_score[high_mask]
print(ko1_score_high.shape)
ko1_score_low = ko1_score[low_mask]
print(ko1_score_low.shape)
17
19
(17, 500)
(19, 500)

それぞれ17人、19人いました。Aさんの実データでは20人ずついたので同じくらいと考えていいでしょう。

最後に、各大問でt検定を行い、「高偏差値集団」と「低偏差値集団」でスコアに有意差があった大問を見つけます。グラフ化の関数にちょっとこだわりました。

#ヒストグラム関数
def show(data1, data2, size=6):
    plt.hist(data1, bins=range(0, 21, 1), alpha=0.3, density=True, color='green', label='high hensachi daigaku')
    plt.hist(data2, bins=range(0, 21, 1), alpha=0.5, density=True, color='orange', label='low hensachi daigaku')
    
    #確率密度
    def gauss(x, mu, sigma):
        return np.exp(-(x - mu)**2/(2*sigma**2)) / (2*np.pi*sigma**2)**0.5
    
    #最尤推定でフィット曲線
    mu, sigma = np.mean(data1), np.std(data1)
    x_ = np.arange(0, 20, 0.001)
    y_ = gauss(x_, mu, sigma)
    plt.plot(x_, y_, color='green')
    
    mu, sigma = np.mean(data2), np.std(data2)
    x_ = np.arange(0, 20, 0.001)
    y_ = gauss(x_, mu, sigma)
    plt.plot(x_, y_, color='orange')
    
    plt.xlim(0, 20)
    plt.xlabel('ko1 daimon score')
    plt.legend()
    plt.show()

#全問題を調べる
for i in range(num_question):
    #対応のないt検定、等分散仮定
    t, p = stats.ttest_ind(ko1_score_high[:, i], ko1_score_low[:, i], equal_var=True)
    #有意差あり、highのほうが高平均なら表示
    if p < p_border and t > 0:
        print('i={}, p={}'.format(i, round(p, 4)))
        print('high mean={}, low mean={}'.format(round(np.mean(ko1_score_high[:, i]), 1), round(np.mean(ko1_score_low[:, i]), 1)))
        show(ko1_score_high[:, i], ko1_score_low[:, i])
i=52, p=0.0087
high mean=12.8, low mean=10.0
i=234, p=0.0062
high mean=13.8, low mean=10.7
i=281, p=0.0092
high mean=13.2, low mean=10.3
i=422, p=0.0099
high mean=12.6, low mean=10.4
i=479, p=0.0074
high mean=12.6, low mean=10.3

500問中5問に有意差がありました。

結論

結局、ランダムで無意味なデータを用いても5問が抽出されました。もちろん乱数シードを変えると抽出数は変わります。

荒削りではありますが、こんなに短いコードで、わずか数秒間待つだけで、コントロール実験が1つできました。結論、「Aさんが実データから5問を抽出したことは意味があるとは思えない」と分かり、違う切り口で解析をしていく必要があることになります。

現役教員へのヒアリング方法

Aさんは「現役の高校教員3名に研究の趣旨を伝え、5問にどのような共通点があるかを自由記述形式で質問」しました。

これの良くないところは、「どのような共通点がありますか?」と聞いた点です。そう聞かれれば頑張って共通点を探そうとしますし、探せば何か共通点は見つかるものです。極端な話、国語の漢字書き取りの問題と数学の二次関数のグラフを描かせる問題でも、「問題文を読んで適切な線を書く力」とか言えるわけです。

そういったバイアスを生みそうな情報は事前に与えるべきではありませんし、もっと言えば、コントロールとして無関係な問題を数問混ぜてヒアリングを行い、抽出された5問だけに共通する特徴があったかどうかを解析するべきです。高校教員の負担は増えますが、それは余計な負担ではなく「実験に必要な負担」と考えるべきです。

Aさん
Aさん

えー、なんか思っていた研究方法と違う!エレガントじゃない!

審査教員
審査教員

研究とはそういうものです。

さいごに

最近、中高生から自由研究の相談を受けることが増えてきました。HPの記事を見てメールやSlackで技術的な点を質問してくださるのですが、話を聞いてみるとそもそも実験設計が良くないこともあったりします。私たちは全員が修士・博士卒業者なので、研究は楽しく聞かせていただきますし、時間があるときであれば一緒に議論します。(秘密は守りますが、他の人と共同で行っている研究の相談は十分にご注意ください)

リアクションのお願い

「参考になった!」「刺激された!」と思ったらぜひリアクションをしましょう。エンジニアの世界はGive and Takeによって成り立っています。これからも無料で良質な情報にアクセスできるよう、Giveする人への感謝をリアクションで示しましょう!

この記事をシェアする

自身のブログ等で使用する場合は引用を忘れずに!

また、寄付も受け付けています。コーヒー1杯でとても喜びます(*˘︶˘*)

 Amazonでギフト券(アマギフ)を贈る

こちらのリンク から金額を指定してお贈りください。(デフォルトで10000円になっているのでご変更ください)

配送:Eメール
受取人:staffあっとvigne-cla.com
贈り主:あなたのお名前やニックネーム
メッセージ:◯◯の記事が参考になりました。など

のようにご入力ください。見返りはありませんのでご了承ください。

 Amazonで食事券(すかいらーく優待券)を贈る

500円 1000円 2000円 5000円 からお贈りください。

配送:Eメール
受取人:staffあっとvigne-cla.com
贈り主:あなたのお名前やニックネーム
メッセージ:◯◯の記事が参考になりました。など

のようにご入力ください。見返りはありませんのでご了承ください。

 その他、ギフト券やクーポン券をメールで贈る

デジタルのギフト券/クーポン券はメールアドレス(staffあっとvigne-cla.com)までお送りください。受領の返信をいたします。
紙のギフト券/クーポン券は 「郵便物はこちらへ」の住所 まで送付してください。名刺やメールアドレスを同封していただければ受領の連絡をいたします。
余った株主優待券等の処理におすすめです。
いずれも見返りはありませんのでご了承ください。

不明点はSNSでお気軽にご連絡ください

ビネクラのTwitter・Youtubeでコメントをください!


Slack・Discordの場合はこちらの公開グループに参加してShoya YasudaまでDMをください!


※当ブログに関することは何でもご相談・ご依頼可能です。

この記事を書いた人
Yasuda

博士(理学)。専門は免疫細胞、数理モデル、シミュレーション。米国、中国で研究に携わった。遺伝的アルゴリズム信者。物価上昇のため半額弁当とともに絶滅寸前。

タイトルとURLをコピーしました