はじめに
「逆問題のことを知る」の第1回 に続いて、第2回を書きます。
今回のテーマは「逆問題の解は複数存在しうる」です。
この話は大学の講義などでも何度も話に出しているのですが、逆問題の話は人生全般に役に立つものだと思いますし、恐らくChatGPTを使って逆問題を解く時にも有用と思いますので、ぜひ楽しみながらご一読下さい。
人生に役立つ逆問題の知識
まずは以下の問題を考えてみましょう。
貴方はさっき、テーブルの上にいちごショートケーキを置いたまま部屋を後にしました。数分後部屋に帰ってきたら、楽しみにしていたいちごショートケーキがなくなっていました。さて、誰が食べちゃったと思いますか?
この問題は、いわゆる「犯人捜し」という典型的な逆問題です。 イラストではお母さんが、息子さんとペット?の猫を疑っていますね。でも本当にそうでしょうか?
逆問題を考える際には、人の能力の限界に起因する以下の一般法則を忘れないようにする必要があります。
人は、ある結果をもたらす原因候補を全て網羅的に思いついているとは限りません。
候補を全て網羅的に思いついていない可能性を自覚せず、思いついた候補の中だけで考えてしまうことを一般に「決めつけ」と呼びます。逆問題を考える時には、決めつけをしないよう注意する必要があります。
ついでに言うと、「決めつけ」に基づいて誰かに疑いの言葉を発することを「言いがかり」と呼び、人間関係を悪化させる可能性がある行為となりますので注意が必要ですね。実はこの知識が、逆問題関連の知識の中で一番、人生で役に立つのかも?
さて、原因の候補が息子さんとペット?の猫だけでしょうか?そうとは言い切れないことの方が多いでしょう。他の家族の方々も可能性があると思いますし、実は部屋のドアが開いていて、カラスや野良猫が持って行ってしまった可能性もあります。もっと言えば「誰かが食べちゃった」という仮説すら「決めつけ」で、例えば突風で外に飛んで行った等、全く別の原因かもしれません。まさに
「逆問題の解は複数存在しうる」
なのです。
この問題をChatGPT(3.5)にも聞いてみましたw
おお、かなりいい線行ってる回答!
「誰かが食べちゃった」という仮説の全体を「部屋にいた人物全員」と「部屋の外」できっちり網羅するいい回答です。
ただ、模範解答かというとそこまでには到達していないです。「誰かが食べちゃった」というのが「決めつけ」である可能性に言及できていません。GPT-4だとそこまでも言及する性能を備えてくるのでしょうか?
ChatGPTにも、1つの質問に対して複数の解候補を依頼できます
さて、「逆問題の解は複数存在しうる」のであれば、ChatGPTには1つの質問に対し複数の解候補を案出してもらった方がよいですよね。
そこでChatGPTのAPI reference を見ると、1つの質問に対して複数の解候補を出力するよう指定するパラメータが存在します。以下の「n」です。
How many chat completion choices to generate for each input message
(筆者意訳:各入力メッセージに対し、何個のチャットの選択肢を生成するか)
これを使ってプログラミングしてみましょう。以下は、1個の質問で3個の回答を取り出すPythonプログラムです。太字で示したn=3がその指定です。
res = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
n=3,
messages=[
{"role": "user", "content": f"{text}"}
]
)
response = "Answer 1:\n" + res.choices[0].message['content'] + "\n" \
+ "Answer 2:\n" + res.choices[1].message['content'] + "\n" \
+ "Answer 3:\n" + res.choices[2].message['content']
例えば、第1回で聞いた大喜利の質問 をこのプログラムで行ってみると、3つの候補を答えてくれます。
なんか、この例の3つ、どれも冴えてないけど・・・第1回の「うまい棒」 はなかなかよかったのになぁ
さて、念のためですが、ChatGPTは、質問を見て「これは逆問題だからいろんな案を案出しなきゃ」と気を回して複数の回答を出してくれているわけではありません。あくまで、モデルに蓄積された言語と言語の相関関係から、評価値の高いものを順に出しているだけです。
その証拠に、質問が順問題であっても、まあ見事に指定された数の回答を無理矢理?作ってきますので参考までに掲載しておきます。
この回答を見てると、ChatGPTはあくまで「言語モデル」であるってことがよくわかる気がします・・・
デバッグは逆問題:プログラミングで役立つ逆問題の知識
逆問題に関して、ちょっと別の話を記載しておきます。
プログラミングの経験がある方は「プログラムを書くのはスイスイ進むのに、バグが起きるとその原因究明に大変時間が掛かってしまう」という経験をなさったことはないでしょうか?
バグの原因究明に時間が掛かるのは、バグの原因究明は本質的に逆問題だからだと考えられます。別の言い方をすると、以下のようになるからです。
バグの原因究明を開始した段階では「バグの原因候補は複数存在しうる」(だから厄介)
さて、逆問題には以下の性質があります。
逆問題の難易度は、原因候補を絞り込みやすいかどうかに大きく依存する
絞り込める度合いが高いと難易度は下がり、その度合いが低いと難易度は上がる
したがって、バグの原因究明の難易度も「原因候補を絞り込みやすいかどうか」に大きく依存するのです。
原因候補を絞り込みやすいかどうかは、プログラムをモジュール化できているかどうかに大きく依存します。ですからモジュール化はプログラミングにおける重要な技術。この技術につきましては「組込みソフトウェアのための構造化プログラミング (*)」でも解説していますので参考にしてください。
(*)凝集度、Fail Early And Openlyの原則、予防的プログラミングなどを解説しています。Python版作らなきゃなぁ・・・
ちなみに、現在のChatGPTであっても、簡単な「バグの原因究明」は可能でした。
もちろん、現段階では、複雑なプログラムに対してこの例のような模範的な原因究明を行うことは難しいと思いますが、ChatGPTは言語モデルですので、あてずっぽうでも何かは候補を出してきます。第1回 で述べた通り「案出」段階では外れても構いませんし、時には人が気づかない原因候補を挙げてくれるかもしれませんので、バグ原因の「案出」にLLMを使い、絞り込みと最終的な結論付けを人間で行う、というCopilot的な使い方があり得るかもしれませんね。
(注)ただ、プログラムをアップロードする前には、OpenAIのデータ利用ポリシーをよく理解した上で、自己責任でChatGPTに対しそのプログラムを読ませてよいかどうか判断する必要が出てくるものと思われます。筆者はしばらくはChatGPTの能力を趣味レベルで測定しているだけですので、上記のような差し障りのないプログラムしかテストしません。
設計には、複数の正解があり得る
ここまでは、犯人捜しやバグ原因究明のようなタイプの逆問題を中心に議論してきましたが、最後に「宴会の作戦」や、各種設計、プログラミングのような「未来創造」側の逆問題についても言及しておきます。これも数理的には「逆問題の解は複数存在しうる」と同じです。
「ある目的を達成する手段は、複数存在しうる」
これを知り、意識しておくと、逆問題に対して複数人で取り組む際に「あ、それもひとつの解だね」「あ、それも使える可能性あるね」という感じで、冷静に他者のアイデアも受け止めながら議論を進めることができると思います。
また、AIを設計のような逆問題に活用する場合にも、AIの提案に依拠し過ぎず「AIの提案も解候補のひとつだね」と冷静に比較・判断でき、人がAIの言説をうのみにしたり、それが唯一の絶対解かのように勘違いしてしまうことを防ぐ一助になると思います。