この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
サザエさんじゃんけんの予測をAmazon MLでやってみたら6割ぐらいの勝率になりました。ということで、どんな感じでやってみたのか解説します。
前提
- モデル:多項分類
- 目的変数:予測対象となる回のじゃんけんの手
- 説明変数:予測対象となる回の過去n回の手。最大10回。
- 評価データ:100件(第1136回〜第1239回)
- 学習データ:1,089件(第11回〜第1135回)
- Maximum ML model Size:100MB
- Maximum number of data passes:10
- Regularization type (amount):L2, 1e-6 - Mild
評価データが100件とあるのは約1,200件ぐらいあったので、とりあえず直近の100件を予測対象として、それより過去を学習データとすればいいかぐらいのざっくりした考えからです。なお、学習データが100件に対して番組の回数の差が103回あるのはじゃんけんが休みの回は除外しているためです。また、学習データが第11回からなのは最大で過去10回を説明変数として利用しているためです。Maximum ML model Size、Maximum number of data passes、Regularization type (amount)についてはAmazon MLのデフォルト値をそのまま使いました。
今回は予測対象となる手の過去10回分の手を1行のCSVファイルとして作成して、Recipeを使って実際に利用する過去の手の回数を制御しました。
times,target,previous1,previous2,previous3,previous4,previous5,previous6,previous7,previous8,previous9,previous10
第1239回,チョキ,チョキ,グー,チョキ,パー,パー,チョキ,グー,チョキ,パー,グー
第1238回,チョキ,グー,チョキ,パー,パー,チョキ,グー,チョキ,パー,グー,パー
第1237回,グー,チョキ,パー,パー,チョキ,グー,チョキ,パー,グー,パー,チョキ
第1236回,チョキ,パー,パー,チョキ,グー,チョキ,パー,グー,パー,チョキ,グー
Recipeは以下の様な感じです。利用する過去の手の回数が増えるとoutputsの中の変数の数が増えます。
{
"groups": {},
"assignments": {},
"outputs": [
"previous2",
"previous1"
]
}
Recipeの詳細はAmazon Machine Learning Recipeまとめを参照して下さい。
結果
説明変数の数(過去の手の数)を1〜10に増やしてみた結果は以下のグラフの通りです。過去2回が一番Average F1 scoreが高く、0.59でした。それ以上過去の手を増やしても0.57ぐらいだったので6割ぐらいの正解率でいいなら過去2回分の手があれば十分なようです。
最も正解率が高い過去2回分を利用した際のML model performanceの画面は以下の図の通りです。
おまけ
じゃんけんのデータはサザエさんの過去の手 一覧を利用させていただきました。このページの過去の手のデータを丸ごとコピーしてjanken.txtというファイルに保存します。後は以下のPythonスクリプトでjanken-training.csvとjanken-evaluation.csvが生成されるので、janken-training.csvでモデルを作成し、janken-evaluation.csvで評価します。
# coding: UTF-8
DATA_WINDOW_SIZE = 10
NUM_OF_EVALUATION_RECORDS = 100
records = []
for line in open('janken.txt', 'r'):
items = line.split()
# 空行を除去
if len(items) == 0:
continue
# グー/チョキ/パーという文字列に変換(「(観月ありさ)」などの文字列を除去)
hand = items[2].split('(')[0]
# 休みの行を除去
if hand == '休み':
continue
records.append({"number_of_times":items[0], "hand":hand})
formated_lines = []
for i, v in enumerate(records):
if i + DATA_WINDOW_SIZE >= len(records):
break
line = v["number_of_times"] + ',' + v["hand"]
# 説明変数として利用する過去の手を追加
for j in range(1, 1 + DATA_WINDOW_SIZE):
line += ',' + records[i + j]["hand"]
formated_lines.append(line)
evaluation_file = open("janken-evaluation.csv", "w")
training_file = open("janken-training.csv", "w")
try:
# ヘッダ行の書き込み
header = 'times,target'
for i in range(1, 1 + DATA_WINDOW_SIZE):
header += ',previous' + str(i)
evaluation_file.write(header + '\n')
training_file.write(header + '\n')
for i, v in enumerate(formated_lines):
if i < NUM_OF_EVALUATION_RECORDS:
evaluation_file.write(v + '\n')
else:
training_file.write(v + '\n')
finally:
evaluation_file.close()
training_file.close()
まとめ
サザエさんじゃんけんは割りとメジャー?なテーマらしく、8割近くの勝率を出している方もいました!Amazon MLで更に正解率を上げる場合は、学習期間の調整とか追加の変数を探すとかすることになるのかなーと思います。