Pythonで芥川龍之介の短編小説『羅生門』をもとにしたシンプルなテキストゲームを作る
この記事について
今回はPythonで芥川龍之介の短編小説『羅生門』を基にしたシンプルなテキストゲーム「羅生門」を作ります。アドベンチャー要素のない単純なインタラクティブフィクションか紙媒体のゲームブックに近く、選択肢のある小説と言った方が的確で、ゲームとしての面白味は欠けていると思います。選択肢も2択だけで、主人公の心情に沿って小説の結末を目指し、作者の意図と異なる選択をするとその場でゲームは終了となります。選択肢は国語の試験や参考書で頻出する定番の問いをもとにしています。
以前の記事でGoogle Colaboratoryの無料GPUサービス上でKeras /TensorFlowを使って英詩であるポーの『大鴉』のような文章生成を行いました。その後LSTMモデルに採用した日本語小説の自動生成の練習として同作品『羅生門』で試みましたが、結果が面白くなかったので本ブログでの掲載を取り止め、何か他にできないかと考えて思い付いたのが今回のテキストゲームです。移動の待ち時間などに書いたので、文章生成とは打って変って簡易的なコードです。
参考記事・先行事例
↳小説テキストデータの出典です。
↳シンプルなテキストアドベンチャーのコードを紹介しています。
- 他にもGitHubなどで有名なテキストゲームのコードが公開されています。
モジュールとコードの流れ
今回は追加のパッケージなどを使用しないコードで、Pythonを触れたばかりの方でもわかるような非常に初歩的なものです。小説なので、段落や場面の切り替えを視覚的に表すために、timeモジュールをインポートして、スリープ処理のみ行っています。あとは選択肢の答え方、つまり読者(プレイヤー)が入力すべき2択のキーを指定し、if関数で選択肢をわたしているだけです。青空文庫で公開されているパブリックドメインである芥川龍之介の『羅生門』(新字新仮名、ルビ有)のテキストデータを、場面で4分割して各場面を定義し、正しい選択肢を入力すると小説が進むコードになっています。
Pythonをインストールしていない環境でもブラウザ上で実際にコードを動かし、アウトプットをゲームのようにわかりやすく表示するためにTrinketのサービスを使用しました。モバイル・デスクトップなど端末を選ばず、ログインなしで、誰でも無料で確認でき、コードの共有も容易だったのでこのサービスを試してみました。(他に同様の用途・方式でコードを共有可能なサービスがあれば是非知りたいです。) 前述の通り、GPUも必要としない初歩的なコードなので、Google Colaboratoryのクラウドサービス上はもちろんのこと、他のPython向けのWebサービスでもコードを動かすことができます。
実際にTrinketのサービスにアップしたコードは以下のリンク先及び埋め込みの通りです。アウトプット表示欄を拡げて、答えが含まれているコード部分を隠すと、より楽しむことができると思います。リンク先は、モバイルでの表示だとアウトプット部分しか表示されないようになるので、iPhoneやAndroidなどのモバイル端末のブラウザ上で開くことが最適かもしれません。
全コード
長くなりますが、以下がコードの全体です。
Google ColaboratoryのGPUクラウドサービス上でKeras /TensorFlowを使ってLSTM(ニューラルネットワーク)によるエドガー・アラン・ポー風の文章の自動生成を行う(自然言語処理/ディープラーニング)
この記事について
ディープラーニング/深層学習(Deep Learning)のライブラリにTensorFlowの公式フロントエンド・ラッパーライブラリであるKeras(ケラス)を使って(KerasをTensorFlowバックエンドで実行して)、リカレントニューラルネットワーク/回帰型ニューラルネットワーク(Recurrent Neural Network: RNN)の一種であるLSTM/長・短期記憶(Long Short-Term Memory)をニューラルネットワーク(Neural Network: NN)に採用し、プロジェクト・グーテンベルク(Project Gutenberg: PG)で公開されているパブリックドメインであるエドガー・アラン・ポー(Edgar Allan Poe)の詩『大鴉』(“The Raven”)のテキストを訓練データとして自然言語処理(Natural Language Processing: NLP)である文章の自動生成を行います。簡単に言うとポーの詩『大鴉』のような文章の生成に挑戦します。
今回は無料でGPUをクラウド(Cloud)サービス上で利用することができるGoogle Colaboratoryにてプログラミング/コードの実行をすることにしました。データ量が大変多いので、筆者の低スペックパソコンのローカルCUP処理では、実行結果の取得まで時間がかかることが予想されたからです。
文章の自動生成に挑戦しようと考えたきっかけは、CourseraのDeep Learning SpecialisationのCourse 5: Sequence Models,Week 1: Recurrent Neural NetworksにてLSTMとシェイクスピアの『ソネット集』("The Sonnets")風の文章生成を学んだことにあります。コードについても、そのコース内ものを模している部分が多いですが、同コースの参考文献にもなっているKeras teamがGitHubで公開しているLSTM text generatorのコードも倣ってもいます。文章の自動生成は何度も試みられ、同様のトピックについて書いた記事が、ネット上に既に多く存在しますが、このブログのディープラーニング練習ということで投稿することにしました。この試みの目的としては、成功例に倣ってコードを実行することで、Google Colaboratory上でのKeras /TensorFlowの使用スキルやLSTMによる文章の自動生成の手順を自分のものにするところにあります。
参考記事・先行事例
ディープラーニングで自動筆記 - Kerasを用いた文書生成(前編) - Deep Insider
ディープラーニングで自動筆記 - Kerasを用いた文書生成(後編) - Deep Insider
↳前後編ともにLSTM text generatorを使って日本語の小説を生成の解説。
Keras LSTMでサクッと文章生成をしてみる | cedro-blog
↳LSTM text generatorについての日本語での解説
KerasのSingle-LSTM文字生成サンプルコードを解説 – Qiita
↳LSTM text generatorの各コードを細かく解説
パッケージとライブラリ
最初に、必要なパッケージのライブラリ及びモジュールを取り込み(import)ます。今回はGoogle Colaboratoryを使うので、仮想環境の構築などの手間を省くことができ、ノートブックの設定を、ランタイムのタイプをPython 3、ハードウェアのアクセラレータ/device typeをGPUにするだけで使用できます。TensorFlow, Keras, NumPy(計算)と、Python標準ライブラリのrandomモジュール, sysモジュール, ioモジュールが必要です。
import tensorflow as tf import keras import numpy as np import random import sys import io from __future__ import print_function from keras.callbacks import LambdaCallback from keras.models import Model, load_model, Sequential from keras.layers import Dense, Activation, Dropout, Input, Masking from keras.layers import LSTM from keras.utils.data_utils import get_file from keras.preprocessing.sequence import pad_sequences
テキストの読み込み
エドガー・アラン・ポー(Edgar Allan Poe)の詩:『大鴉』(“The Raven”)のUTF-8形式でファイル名を「theraven.txt」で保存し、ファイルを読み込みます。
from google.colab import files file = files.upload()
FILE_PATH = "./theraven.txt" text="" with open(FILE_PATH, 'r',encoding="utf-8") as f: for line in f: lines = line.split() text += " ".join(lines) text = text.lower() len(text)
コードの流れ
テキストを読み込んだら、重複しているキャラクターを排除し、キャラクターを番号に変換、辞書を作成します。文字の区切り(maxlenパラメータ)、スキップ数(step)とシーケンスの設定をします。次にLSTMのモデルを作成します。その後、関数の設定をして、モデルの出力結果を指定し、Callbackを設定、文章を生成できるようにします。これらのコードの流れは、前述のLSTM text generatorコードとほぼ同じなので、本ブログでは割愛します。
今回の実行結果
実際に自動生成されたエドガー・アラン・ポーの詩『大鴉』のような文章は以下の通りです。
"f pallas just above my chamber door;and "
また、【Python】LSTMを使って文章を自動生成 | エンジニアの眠れない夜の記事で解説しているRNN_alice_pub_002のコードを写経し、条件を変更して実行すると以下の文章を生成しました。
HIDDEN_SIZE = 128; BATCH_SIZE = 128; NUM_ITERATIONS = 5; NUM_EPOCHS_PER_ITERATION = 5; NUM_PREDS_PER_EPOCH = 200の場合、
“oject gute oject gutenberg-tm electronic work is death and the poet's tounthe stance the menore and the foundation of the poet's tounthe stance the menore and the foundation of the poet's tounthe stance the menore and the”
HIDDEN_SIZE = 128; BATCH_SIZE = 128; NUM_ITERATIONS = 5; NUM_EPOCHS_PER_ITERATION = 10; NUM_PREDS_PER_EPOCH = 100の場合、
“riodic tax riodic taxed to owner the work and states the project gutenberg-tm electronic works in the poet's pooms, and t”
雑感
思考回数/エポックを重ねた方が、単に長い文字列を生成しようとするよりも、文章として成り立っている結果を得やすいことがわかります。この記事は/も非常に読み難い悪文になっていますが、筆者の英語で行ってきた学習成果としての理解と日本語での表現・理解をすり合わせるために致し方ないと考えています。次回以降、SimpleRNNなど他のNNを使用した文章の自動生成や日本語の文章生成・自然言語処理にもチャレンジしてみたいです。また、LSTMによる株価・FX予想も試そうと思います。
余談
文章の自動生成の精度向上や、GANを用いた画像認識による判別や画像生成などにも挑戦したいですが、現在所有するマシンはGPUもなく、圧倒的にスペック不足なので、何か作るためにハードウェア環境を整えたいと思っています。今回のようにGPUクラウドサービスを活用する案として、アマゾン ウェブ サービス(Amazon Web Services: AWS)のGPUインスタンスの使用がありますが、インスタンスの止め忘れによるいわゆるクラウド破産が怖くて使用していません。インスタンスの止め忘れを防止のためにモニタリングサービスであるAmazon CloudWatch導入したとしても、リージョンにより料金に変動がある有料・従量制サービスであることが現在の筆者には抵抗があり、使用に二の足を踏んでしまいます。ハードウェア環境が整いかつ居所が定まるまでは、メモリ、連続学習時間、アイドリング時間などの制限があるものの、無料のGPUクラウドサービスであるGoogle Colaboratoryを工夫して使用するのが筆者にとっては現実的かと考えます。
このブログについてとプログラミング関連の学習歴
はじめに
このブログは、文系出身の筆者がMinicondaの環境で主にPython 3を用いた様々なプログラミングに挑戦する記録です。初学者がCoursera Deep Learning Specializationからの学習内容の再現性を意識して、そこで扱っているパッケージやコードを中心にプログラミングにチャレンジするので、新味がない記事もあると予想されます。その点から、「プログラミングに関する知識を記録・共有するためのサービス」であるQiitaにて、ガイドラインで望ましいとされる「投稿者以外の人にとっても価値のある記事」を書くことは難しいかと考えます。しかし、筆者の日本語での備忘録もくしは公開学習メモという性格が強くとも、ブログの投稿内容や知識が誰かの役に立つことがあればとは思うので、はてなブログで記事を書いていきます。
また、ブログ名の通り、このブログを書いているのはあくまでも日本と欧州とをふらふらしているワタリガラスです。誤りなども多く見受けられるかと思います。コメントなどでご助言や間違いのご指摘をいただければ大変嬉しいです。
きっかけ
機械学習やその周辺のプログラミング技術を事業に取り入れることのハードルが随分と低くなり、近い将来にはどの領域の研究者にとってもOfficeソフトやEndnote等の文献管理ソフトの使用スキルのようにツールとして一般化するのではないでしょうか。その時がきた場合に遅れをとらないように、筆者もPython 3などの使用スキルや機械学習の基礎知識だけでも押さえておきたいです。新元号令和の時代の初めに合わせて、新しいチャレンジをしようと思い立ったことがきっかけです。自分の分野の研究に機械学習を研究方法やツールとして取り入れたい、もしくはプログラミングで何か面白いことがしたいと考えています。また、ブログ投稿のネタを用意するということを、コードを書いてプログラミングを継続的に行うための動機付けにしようと思いました。Kaggleへの挑戦や、一つの目標として文系の筆者がPyConのような情報交換会やカンファレンスにも参加して発表できれば良いなとも考えています。もちろん、このブログに書くスキルを研究や仕事につなげることができれば理想的だなと思います。
この記事について
ここでは、このブログの最初の記事として、チャレンジ開始以前の筆者の事前知識を示すため、プログラミング関連の学習歴を簡単にまとめます。筆者自身が何を勉強したか後で確認しやすいように、随時更新して書きとめておきます。無料の学習教材を利用して時間をかけない勉強法を行うことが多いです。
これまでの学習歴(随時更新)
大学院進学以前
-
義務教育期間中にHTMLでウェブページなどを作成した経験があり、C, Java, JavaScript, PHPの基礎もふれたことがあるのでプログラミングに抵抗はないが、ある程度のスペックのパソコンとサーバー管理などが必要で面倒だと考えていた。
-
高校・大学と文系を選択したが、高校時代の数学担当教員が「文系の範囲だけでは物足りないだろうし、将来何かの役に立てば」と、大学センターで十分な得点を取れるだけの数IIIと数C、旧課程では高校数学に含まれていた範囲の大学数学の初歩を、放課後や長期休業中に教えてくださった。(機械学習には数学の予備知識が必要だと思うので、この期間の学習効果は大きいのではないだろうか。先生ありがとう。)
-
英語圏における大学院の出願要件を満たす英語力がある。(大学院修了後で考えると、英語での学位論文執筆や学会発表、英語のみの職場で仕事ができる程度の英語運用能力がある。)
大学院在学中
- 社会科学分野の若手研究者向け研修に参加し、Rの研究への活用やプログラミングを中級レベル程度まで習得。(RStudioも好んで使っていた。)
大学院修了後 (特に2018年12月末頃から)
- CourseraでStanford Universityが提供する人気コースのMachine Learningに聴講のみのAuditモードで登録して、機械学習の基礎を勉強(2018年12月末)。
- O’Reilly公式が公開しているFree Programming Ebooksやその他の公式無料公開の電子書籍を複数流し読み(2019年1月から2月)。
- 海外のあまり有名ではない全て無料のMOOCsで、復習と学習成果の確認を兼ねてPython 3, Ruby, Java, JavaScript, C, C++, C#, PHP, Swift 4, CSS, HTML, SQL, jQueryの各コースを受講し、修了(2019年2月上旬から中旬)。
- Google Developer JapanのML Study Jams: Machine Learning初心者向けトレーニングに参加し、Google Cloud Platform(GCP)を利用して機械学習の基礎などを習得するQwiklabのコースを修了(2018年2月下旬)。
- Courseraでdeeplearning.aiが提供するDeep Learning Specializationの5コース全てを受講登録から4日か5日で修了。学習成果の確認のため、できるだけ早く修了できるようチャレンジしました。より深めたい項目などはノートも取ったので、初学者の筆者にとっては大変良い勉強になりました(2019年4月中旬)。
- ML Study Jams: Machine Learning中級者向けトレーニングに参加してQwiklabのコースを修了(2018年4月下旬)。
- Anacondaで仮想環境の構築を試みも、パソコンのスペックがあまり高くないので、Minicondaでの環境に落ち着く(2018年4月下旬)。
このように筆者は主に英語での学習教材やオンラインコースを活用してきましたが、最近になって「世界最大級のオンライン学習プラットフォーム Udemy」のように日本語で無料もしくは低コストかつ高品質なコースを提供するサービスも増えてきたように思えます。日本語での学習をする場合、取り入れても良いかもしれません。
免責事項
Coding Common Ravenは、記載されている情報の正確さについて可能な限り努力していますが、その背育成や適切性に問題がある場合、告知なしに情報を変更・削除することがございます。
当ブログの情報を用いて行う一切の行為、被った損害・損失に対しては、一切の責任を負いかねます。ご了承ください。
プライバシーポリシーについて
Coding Common Ravenは、「個人情報の保護に関する法律」に基づき、「個人情報保護の基本方針(プライバシーポリシー)」を定め個人情報の適切な管理・保護に努めます。
個人情報保護の基本方針(プライバシーポリシー)
1.個人情報の利用目的をできるだけ特定し、特定された利用目的の達成に必要な範囲を超えて利用することはありません。
2.個人情報を偽りその他不正な手段による取得しません。取得したときは、本人に速やかに利用目的を通知又は公表します。
3.個人情報を利用目的の範囲内で正確かつ最新の内容に保つように努めます。
4.個人情報の漏洩や滅失を防ぐために、必要かつ適切な安全管理措置を講じます。
5.あらかじめ本人の同意を得ないで第三者に個人情報を提供することはありません。ただし、法令に基づく場合、人の生命、身体又は財産の保護に必要な場合、公衆衛生・児童の健全育成に特に必要な場合、国等に協力する場合は除きます。
お問い合わせ
このブログの管理人(筆者)へのお問い合わせフォームはこちらです。
記事の訂正依頼、質問、お仕事の依頼、勧誘など、なんでも御用の方はこちらからお願いします。