機械学習の定性評価用アンケートを省エネ生成する簡単なスクリプト

機械学習エンジニア・データサイエンティストの[muraokaz](https://qiita.com/muraokaz)です。[VISITS Advent Calendar 2020](https://qiita.com/advent-calendar/2020/visits) 23日目の記事です。今回は、定性評価用データからアンケートフォームを自動生成するスクリプトを紹介します。

# Google Formを使った定性評価用アンケートの自動生成

機械学習系のプロダクトに携わっていると、遅かれ早かれ「そのアウトプットが良いかどうか、実際に見て確認したい」と言われるタイミングがあります。一般的に、データセットを学習用・テスト用（・バリデーション用）に分割するなどして性能を計測する**定量評価**に対し、人間の評価者が結果の良し悪しを主観的にジャッジする評価は**定性評価**と呼ばれます。定量評価が、データセットさえ準備しておけば比較的手軽に実施できるのに対し、定性評価は、評価者に評価をお願いしたり、評価用アンケートを設計・作成・集計するなど、結構手間のかかる作業が多いという傾向にあります。

例えば、評価用アンケートをゼロから作成しようとしたとき、最初に思いつくだけでもこれだけのタスクが発生します。

- 定性評価用アンケートのUI作成
- 比較したいデータの流し込み
- 回答の保存機能の作成（データベースの構築）
- 結果の集計スクリプトの作成

特に、普段フロントエンドを作り慣れているわけではない機械学習エンジニアにとって、こうしたシステムを作る労力は省力化したいところです。実は、簡単なアンケートでGoogle Formで実装できるものであれば、Google Apps Script (GAS)を使った簡単なスクリプトからの画面の自動生成が可能です。以下、その手順を見てみましょう。

## Side by Side定性評価

今回題材として扱う定性評価として、Side by Sideと呼ばれる方式を考えます。これは、2つのアウトプットを横（縦）に並べ、評価者はそのどちらがより良いかを選んで相対評価する評価方法です。例えば質問応答システム（旧）と質問応答システム（新）があったとき、2つのシステムのアウトプットに違いのあったデータを抽出し、人間が見てそのどちらが好ましいかを判断することで、システムの優劣を評価することができます。Side by Sideの定性評価を行うような評価用アンケートでは、次のような特徴が求められます

- 2つのシステムからのアウトプットを、ランダムに左右配置する（配置によるバイアス、評価者の思い込みによるバイアスを排除するため）
- 結果集計時には、配置情報と照合することで、どちらのアウトプットのほうが高い評価を得たかを測定する

GASでは、このような方式を実現するアンケートフォームを作成できます。

## Googleスプレッドシートの準備

まず最初に、Google Formに流し込むためのデータを準備します。GoogleスプレッドシートとGAEとの相性が良いので、比較したい2つのシステムのアウトプットを、次のようなフォーマットで用意します。

![](https://raw.githubusercontent.com/KazumaMurao/qiita_visits/master/fig/5.png)

ここで、A・B列にはそれぞれ、C・D列のデータがどちらのシステムのアウトプットであるかを記載します。この例では、新しい質問応答システムからのアウトプットを1に、旧型の質問応答システムからのアウトプットを0に対応させています。左右どちらに新旧のアウトプットを配置させるかは、一行ごとにランダムに割り当てます。

## Google Apps Scriptを使ったGoogle Formへの変換

このようなスプレッドシートが準備できたら、次はGASを使ってこのシートをGoogle Formへと変換します。スプレッドシートのメニューから「ツール」→「スクリプト エディタ」を選択すると、GASの編集画面が開かれます。ここでは、先程のスプレッドシートの"sample_data"シートから、"左右比較型アンケート自動生成サンプル"という名前のGoogle Formを作成するスクリプトを書きました。

```actionscript:sample.gs
function Makeform() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var lastRow = ss.getLastRow();
  var quizdata = [];
  quizdata=ss.getSheetByName('sample_data').getRange(1,1,lastRow,4).getValues();

  const formTitle = "左右比較型アンケート自動生成サンプル";
  const formDescription = "質問に対する回答が正しいほうのアイデアにチェックをつけてください。選択肢はランダムに表示されます";
  const form = FormApp.create(formTitle);

  form.setIsQuiz(true);
  form.setDescription(formDescription);

  for(var i = 0;i<quizdata.length;i++){
    var choices;
    var item = form.addMultipleChoiceItem();
    if(quizdata[i][0] > quizdata[i][1]){
      choices=[
        item.createChoice(quizdata[i][2],true),
        item.createChoice(quizdata[i][3],false)
      ];
    }else{
      choices=[
        item.createChoice(quizdata[i][2],false),
        item.createChoice(quizdata[i][3],true)
      ];
    }
    item.setTitle(i).setChoices(choices);
    item.setPoints(1);
    item.setRequired(true);
  }

  Logger.log(quizdata);
}
```

このスクリプトを先程のエディタ画面から実行すると、次のようなGoogle Form編集画面と回答画面が出来上がります。

![表示されない](https://raw.githubusercontent.com/KazumaMurao/qiita_visits/master/fig/6.png)

![](https://raw.githubusercontent.com/KazumaMurao/qiita_visits/master/fig/7.png)

左右で比較したかった選択肢が上下に並んでいますが、手軽に作成できるアンケートの機能としては許容範囲かと思います。このままアンケートのURLをシェアすることで、評価者に定性評価に参加してもらうことが可能です。ここでは非常に単純なアンケートの例を示しましたが、ページごとにセクションを区切って集計するなど、GASで作成できる機能は多数存在するようです（詳しくは参考ページ等を参照ください）。

## 回答結果の表示

Google Formを使うことで、定性評価の回答結果を簡単に集計することができます。ここで気をつけたい点として、先ほどのスクリプトにおいて、便宜上アウトプット（新）の結果を「正解」としてアンケートを作成したため、アンケートの集計結果の正答率は、アウトプット（新）を選んだ評価者の数（割合）となります。本来の位置付けとしては評価者の評価結果のほうが「正解」となるので対応関係が逆になりますが、実用的にはこの集計方法でも本来の「正解率」と同じ集計結果となるので問題ないはずです。

![](https://raw.githubusercontent.com/KazumaMurao/qiita_visits/master/fig/8.png)

# まとめ

最初にも書いたとおり、定性評価を実施しようとなると、集計用ページを作成するだけで割と一仕事という感があります。このような作業を省エネ化する方法とサンプルスクリプトを紹介しました。意外とまとまった情報がなかったので、本記事が機械学習に関わるどなたかの役に（少しでも）立てばと思います。また「もっと便利な方法があるよ」という方がいらっしゃいましたら、ぜひコメントにて教えていただければ助かります。

# 参考にさせていただいたページ

- https://tonari-it.com/gas-create-form/
- https://yo3kaki.com/2020/04/25/gas_createtest01/
- https://ameblo.jp/mathematics-ojisan/entry-12400076560.html