302 lines
6.8 KiB
Org Mode
302 lines
6.8 KiB
Org Mode
#+TITLE: 研究室配属希望調査 解析スクリプト
|
||
#+AUTHOR: Takahiro Ohkubo
|
||
#+OPTIONS: toc:2 num:nil
|
||
|
||
* 概要
|
||
|
||
Google Forms で実施した3年生の研究室配属希望調査について、結果画面から
|
||
コピーしたテキストを解析し、研究室ごとの希望者数と GP の統計量を集計する
|
||
Python スクリプトです。
|
||
|
||
Google Forms の管理者権限がなく CSV を直接取得できない場合でも、結果画面の
|
||
テキストをコピーしてファイルに保存すれば解析できます。
|
||
|
||
主な処理内容:
|
||
|
||
- Google Forms の結果テキストから研究室番号を抽出
|
||
- 各研究室の回答値を抽出
|
||
- 在校生と編入生を分類
|
||
- 研究室ごとの希望者数を集計
|
||
- 在校生 GP の平均値と標準偏差を計算
|
||
- 必要に応じて元データと集計結果を Excel に保存
|
||
|
||
* 必要な環境
|
||
|
||
Python 3 と以下のパッケージが必要です。
|
||
|
||
- numpy
|
||
- pandas
|
||
- openpyxl
|
||
|
||
Conda を使う場合:
|
||
|
||
#+begin_src sh
|
||
conda install numpy pandas openpyxl
|
||
#+end_src
|
||
|
||
* 入力データ
|
||
|
||
Google Forms の結果画面に表示されたテキストをコピーし、テキストファイル
|
||
として保存します。
|
||
|
||
例:
|
||
|
||
#+begin_example
|
||
googleform.txt
|
||
#+end_example
|
||
|
||
研究室ごとの回答は、例えば以下の形式を想定しています。
|
||
|
||
#+begin_example
|
||
研究室10(極限環境材料科学研究室)
|
||
7 件の回答
|
||
380
|
||
288
|
||
300
|
||
375
|
||
280
|
||
310
|
||
359
|
||
#+end_example
|
||
|
||
Google Forms の表示によっては、回答数の前に =GP= が付く場合にも対応します。
|
||
|
||
#+begin_example
|
||
研究室10
|
||
GP7 件の回答
|
||
236
|
||
377.5
|
||
292
|
||
1.8
|
||
385
|
||
350
|
||
#+end_example
|
||
|
||
* 回答値の形式
|
||
|
||
** 1行1回答の形式
|
||
|
||
通常は各回答値が1行ずつ並びます。
|
||
|
||
#+begin_example
|
||
研究室1
|
||
GP7 件の回答
|
||
260
|
||
181
|
||
395
|
||
340
|
||
396
|
||
380
|
||
365
|
||
#+end_example
|
||
|
||
小数値にも対応します。
|
||
|
||
#+begin_example
|
||
348.3
|
||
377.5
|
||
403.51
|
||
#+end_example
|
||
|
||
値の後ろに注記がある場合も、行頭の数値を読み取ります。
|
||
|
||
#+begin_example
|
||
365(修正済)
|
||
#+end_example
|
||
|
||
この場合は =365= として処理します。
|
||
|
||
** 編入生
|
||
|
||
回答が =編入生= の場合は、内部的に 0 として扱います。
|
||
|
||
#+begin_example
|
||
研究室2
|
||
GP6 件の回答
|
||
編入生
|
||
217
|
||
248
|
||
350
|
||
342
|
||
360
|
||
#+end_example
|
||
|
||
この例では、
|
||
|
||
- 在校生: 5人
|
||
- 編入生: 1人
|
||
|
||
として集計します。
|
||
|
||
** 値 / カウント形式
|
||
|
||
同じ値が複数回出現する場合、Google Forms の表示によっては
|
||
「値 / カウント」形式になることがあります。
|
||
|
||
#+begin_example
|
||
値 カウント
|
||
300 2
|
||
350 2
|
||
370 1
|
||
380 1
|
||
#+end_example
|
||
|
||
この場合、カウント数に応じて値を展開します。
|
||
|
||
例えば、
|
||
|
||
#+begin_example
|
||
300 2
|
||
350 2
|
||
#+end_example
|
||
|
||
は内部的に、
|
||
|
||
#+begin_example
|
||
300
|
||
300
|
||
350
|
||
350
|
||
#+end_example
|
||
|
||
として処理されます。
|
||
|
||
Google Forms のグラフ表示からコピーした際に、表の前に連結した数字列が
|
||
含まれることがあります。
|
||
|
||
#+begin_example
|
||
19423023625427427734435036037001231 (8.3%)...
|
||
値 カウント
|
||
194 1
|
||
230 1
|
||
236 1
|
||
254 1
|
||
274 1
|
||
277 1
|
||
344 1
|
||
350 1
|
||
360 3
|
||
370 1
|
||
#+end_example
|
||
|
||
この場合は「値 / カウント」表を優先して使用し、表より前のグラフ由来の
|
||
文字列は無視します。
|
||
|
||
* 実行方法
|
||
|
||
#+begin_src sh
|
||
./analyze_lab_assignment_survey.py googleform.txt
|
||
#+end_src
|
||
|
||
* 出力
|
||
|
||
実行すると、研究室ごとの集計結果を標準出力に表示します。
|
||
|
||
#+begin_example
|
||
----------------------------------------------------
|
||
回答者数: 98
|
||
研究室 在校生 編入生 GP mean GP std
|
||
----------------------------------------------------
|
||
1 7 0 345.1 50.7
|
||
2 5 1 303.4 63.0
|
||
3 7 0 351.6 69.0
|
||
6 7 0 354.0 32.9
|
||
#+end_example
|
||
|
||
=GP std= は標本標準偏差です。対象が1人の場合は =-= と表示します。
|
||
|
||
* 在校生と編入生の判定
|
||
|
||
解析時には、回答値について
|
||
|
||
#+begin_src python
|
||
df_lab["値"] > 10
|
||
#+end_src
|
||
|
||
を満たす回答を在校生の GP データとして扱います。
|
||
|
||
したがって、
|
||
|
||
- 値 > 10 : 在校生
|
||
- 値 <= 10 : 編入生
|
||
|
||
として分類します。
|
||
|
||
現在のスクリプトでは、文字列 =編入生= を内部的に =0= として保存するため、
|
||
この条件で編入生として分類されます。
|
||
|
||
* GP の統計量
|
||
|
||
研究室ごとに在校生のみを抽出し、GP の平均値と標準偏差を計算します。
|
||
|
||
平均値:
|
||
|
||
#+begin_src python
|
||
df_regular["値"].mean()
|
||
#+end_src
|
||
|
||
標準偏差:
|
||
|
||
#+begin_src python
|
||
df_regular["値"].std()
|
||
#+end_src
|
||
|
||
=pandas.Series.std()= を使用するため、標準偏差は標本標準偏差
|
||
(=ddof=1=)です。
|
||
|
||
* Excel 出力
|
||
|
||
=-o= または =--output= を指定すると、解析結果を Excel ファイルに保存します。
|
||
|
||
#+begin_src sh
|
||
./analyze_lab_assignment_survey.py googleform.txt -o result.xlsx
|
||
#+end_src
|
||
|
||
Excel ファイルには以下のシートを作成します。
|
||
|
||
- =raw= : 抽出した研究室番号と回答値
|
||
- =summary= : 研究室ごとの集計結果
|
||
|
||
* 対応している入力形式
|
||
|
||
以下の形式に対応します。
|
||
|
||
- =研究室1= などの研究室番号
|
||
- 全角数字を含む研究室番号
|
||
- =7 件の回答=
|
||
- =GP7 件の回答=
|
||
- 整数値
|
||
- 小数値
|
||
- =365(修正済)= のような注記付き数値
|
||
- =編入生=
|
||
- 「値 / カウント」表
|
||
- Google Forms のグラフ由来の連結数字列
|
||
|
||
* 可視化例
|
||
|
||
解析スクリプトでは、研究室ごとの GP 分布や、特定研究室の希望者が全体の中で
|
||
どの位置にいるかを確認できます。
|
||
|
||
以下は出力図の例です。
|
||
|
||
#+CAPTION: GP 分布と第10研究室希望者の位置を示した可視化例
|
||
#+NAME: fig:gp-distribution
|
||
[[file:hogen.png]]
|
||
|
||
上段では、研究室ごとの GP 分布を箱ひげ図として示しています。
|
||
各研究室の希望者の GP のばらつきや中央値を比較できます。
|
||
|
||
下段では、全回答者の GP 分布をヒストグラムとして示しています。
|
||
第10研究室希望者の GP は縦線として重ねて表示しており、
|
||
第10研究室希望者が全体分布の中でどの程度の位置にいるかを確認できます。
|
||
|
||
* 注意事項
|
||
|
||
- 入力テキストは Google Forms の表示形式に依存します。
|
||
- Google Forms のコピー形式が変わった場合、正規表現の修正が必要になる可能性があります。
|
||
- 編入生の判定は「値が10以下」という運用上の仮定に基づきます。
|
||
- GP が実際に10以下となるデータ形式では判定条件を変更してください。
|
||
- 回答値の誤入力は自動修正しません。
|
||
- 回答数と抽出数が一致しない場合は警告を表示します。
|
||
- 回答数が0件の研究室は出力しません。
|