「理想の家」と出会う確率を最大化する合理的な意思決定とは？

**■１．はじめに**
---

最近コロナの影響で家で過ごす時間が増えましたね。

それでなくとも家は生活の中でも長時間過ごす場所ですし、極力理想的な居心地のいい場所にしたいですよね。

皆さんはいま住んでいる家への満足度は高いでしょうか？

ある調査によると自分の家の満足度を0~100点で評価したとき、「90点以上」と回答した人がわずか約9.8%しかいなかったそうです。

人生の出費の中でも「住宅」への出費は大きいものの一つであり、毎月何万、何十万(あるいは数百万)の支払いをしているにも関わらずです。

(読者の方はどうでしょうか？)

どうして胸張って「おれん家は100点！(せめて90点)」っていえないのでしょうか？？

あくまで個人の仮説ですが、「実はこれよりももっと安くていい物件があったんじゃないか・・・。」というモヤモヤが(あるいはそのモヤモヤを払しょくするための意思決定をしたという実感がないこと)が関係しているじゃないかなーと思ったりしています。

そこで、この記事ではそんな不安を払拭すべく、数学確率論を使って「理想の家」と出会う確率を最大化するような意思決定の方法を紹介／解説していこうと思います。

実は、数学確率論的なアプローチを駆使すれば、この確率を最大化するような意思決定をすることは**可能**です。

このような意思決定を行うことで、**「合理的な意思決定をした」という実感**が得られ、それがあなたの住生活への満足度を上げてくれるかもしれません。

※ちなみに、勘のいい読者の方は気づいたかもですが、「家選び」と類似した条件の意思決定への応用も可能です(多少制約条件が異なりますが)。
例えば、理想的な婚約者／彼氏選び／彼女選び／就職先の会社選び等々。

**■２．本記事の大まかな流れ**
---

１．どんな意思決定をすればよいのか？

２．解説／数理モデル導出

３．Pythonによる確率シミュレーション

４．数理モデルを数学的にいじいじする

(結論だけで知りたければ「１」読んでいただければ大丈夫です。２以降はちょいアナリスト向けかも。)

**■３．どんな意思決定をすればよいのか？**
---

###意思決定の方法

結論から書きますが、

「確認する物件数のうち36.8%の物件は無条件で見送り、次以降「これがいままでの中で1番の理想や！」な物件に出会えたらそこで契約する」

というのが、確率を最大化させる意思決定方法となります。

どういうこっちゃ？って感じかと思うので具体例を見ていきましょう。

###具体例

例えば、あなたがこれから50件の物件を確認しようとします。

その場合は、最初の18件(≒約36.8%)は確認したうえで無条件ですっとばしてください。

そして19件目以降の物件の中で(最初にみた18件を含めて)「一番いい！」と思える物件が現れたらそれを採択します。

あてずっぽうに選ぶよりも、その物件が全50件の中で1位である確率が最大化されるのです。
<img width="700" alt="あつこ画像.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498278/b3731fe0-a4e0-e0e5-9d3e-e3d8757c9714.jpeg">

**■４．解説／数理モデルの導出**
---

どうしてこのような手段で理想の家を選択できる確率が最大化されるのでしょうか？

当然、時間も無制限で世の中にある物件をすべて確認することができればこのような手法は不要ですよね。

しかし現実にはそのような家選びは不可能で、我々は有限時間内である程度決められた物件数の中で最も理想とする選択をすることを求められます。

それだけでなく、「めっちゃええやん！」って思った矢先誰かに契約されてしまう…みたいなこともありますよね。

このような家選びにおける諸々の条件を「制約条件化」としておいて、「理想の家」と出会える確率最大化問題として考えてみましょう。

###問題の明文化

以下制約条件を満たし、最大n件の物件を確認する中で最も「理想の家」とする家を選択する確率を最大化せよ。

###制約条件

1. 必ず1件の物件を選択する。
2. 候補物件数nはあらかじめ決められている。
3. 候補物件数には順位が付けられ、複数の候補物件が同じ順位になることはない。
4. 無作為な順序で1件ずつ確認を行う。次にどの物件を確認するかは常に同じ確率である。
5. 確認の直後に契約するかどうかを決定する（最後まで決まらなかった場合は無条件で最後の候補物件を選択）。
6. 過去にさかのぼって不採用にした物件を選択できない。
7. 候補物件自身が選択されることを拒否をしない。

###何をもって「理想」とするか？

上記問題設定／制約条件から「理想の家」は自分で物件に対して順位を決め、順位1位の物件となることと定義して進めていきます。

###問題を解くアプローチ

なるべく上位の候補者がくるようにする(無情報型)順位最小化問題ではなく、1位を得る確率を最大化する（無情報型）最良選択問題として扱っていきます。

また、制約条件6「過去にさかのぼって不採用にした物件を選択できない。」より、大枠の方針としては「物件をr件まで確認し、それまでの中で暫定１位を決める。(r+1)件以降の中で暫定1位を超える物件が出てくる確率が最大化されるrを求める」方針でいきたいと思います(1<r≦n)。

まずは具体例を確認し、その後一般化された確率モデルを導出します。

その確率モデルを微分し極大値を求め、その時のパラメータrを求めていきます。

###具体例の確認：n=10、r=5の場合

まず最大10件の物件の中で、5件まで無条件で見送り(reject)し、6件目を選択し、かつそれが10件の中で「1位(best)」であった場合の確率を求めてみましょう。

$$\underbrace{{9\over 10}\times{8\over 9}\times{7\over 8}\times{6\over 7}\times{5\over 6}}_{reject}\times{1 \over 5}$$

式は上記の通りとなり、結果は

$${1 \over 10}$$

となります。

これでは超絶テキトーに選択をした場合の確率と変わらず、うまくいっていませんね。

そこで、**「最初に観察した5件の情報を活かす方法」**ことを考えてみましょう。

つまり、**「最初に観察した5件の中に暫定１位が含まれる、かつ、6件目以降(j番目)に暫定１位を超える物件(=全体の中での１位)が存在する確率P」**を計算してみましょう。

すなわち、

$$P= \sum_{j=6}^{10} {5 \over j-1}\cdot{1 \over 10}$$

上記を計算すればOKです。

実際に計算してみると、およそ37％となることがわかります。

$$P= \sum_{j=6}^{10} {5 \over j-1}\cdot{1 \over 10}={5 \over 10}\sum_{j=6}^{10} {1 \over j-1}$$

$$={1 \over 2}({1 \over 5}+{1 \over 6}+{1 \over 7}+{1 \over 8}+{1 \over 9})\approx0.3728174603$$

テキトーに選んだ時よりもはるかに１位を選べる確率が上がりましたね。

###見送り件数rによって確率はどう変動する？

さて、上記は、全体の半分(10件中5件)まで無条件で見送り、暫定１位を決め、6件目以降で全10件中の１位が出現するケースを考えました。

次の興味として、無条件で6件目まで見送ったほうが確率が上がるのか７件目まで見送ったほうが確率が上がるのか、、、、一体何件目まで見送るのが正解なのでしょうか？

制約条件6「過去にさかのぼって不採用にした物件を選択できない。」があるので、見送りすぎもよくないですね。

これを具体的に確認するために、簡単にシミュレーションをしてみました。

※縦軸(Probability)・・・選択した物件が1位である確率

※横軸(% of candidates rejected)・・・「全物件数の何％の物件を見送るか？」を表す割合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498278/977172c3-a451-2bab-69f1-5e0201533f6d.png)

~~~Python:
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    
    %matplotlib inline
    
    def choose_candidate(n, reject=np.e):
        candidates = np.arange(1, n+1)
        np.random.shuffle(candidates)
        
        if reject == np.e:
            stop = int(round(n/reject))
        else:
            stop = int(round(reject*n/100))
    
        best_from_rejected = np.min(candidates[:stop])
        rest = candidates[stop:]
        
        try:
            return rest[rest < best_from_rejected][0] 
        except IndexError:
            return candidates[-1] 
        
    best_candidate = []
    for r in range(5, 101, 5):
        sim = np.array([choose_candidate(n=100, reject=r) for i in range(100000)])
        best_candidate.append(np.histogram(sim, bins=100)[0][0]/100000)
    
    plt.figure(figsize=(10, 6))
    plt.scatter(range(5, 101, 5), best_candidate)
    plt.xlim(0, 100)
    plt.xticks(np.arange(0, 101, 10))
    plt.ylim(0, 0.4)
    plt.xlabel('% of candidates rejected')
    plt.ylabel('Probability')
    plt.grid(False)
    plt.axvline(100/np.e, ls='--', c='orange')
    plt.show()
~~~
これをみると、全物件数の約37%を見送ったぐらいで確率が最大化していることがわかりますね。

###どうして約37%で確率が最大化するのか？

さて、このシミュレーションをみる限り、全体の物件数のうち約37%を見送り、それ以降の物件の中で暫定1位を超えた物件があればそれで契約をする場合、その選んだ物件が全物件の中で1位となる確率が最大化されるようですね。

どうしてこのようなことが起こるのでしょうか？

それを数学的に解明していきましょう。

まず、確認ですが、「全物件数が10件かつ5件までは見送る場合」の確率は以下式で現されました。

$$\sum_{j=6}^{10} {5 \over j-1}\cdot{1 \over 10}$$

これを一般化した「全物件数がn件かつr件までは見送る」場合の確率は

$$\sum_{j=r+1}^{n} {r \over j-1}\cdot{1 \over n}$$

で表すことができます。

これについて、最大値とその時のパラメータを求めていきます。

$$\sum_{j=r+1}^{n} {r \over j-1}\cdot{1 \over n}={r \over n}\sum_{j=r+1}^{n} {1 \over j-1}$$

$$={r \over n}\sum_{j=r+1}^{n} {n \over j-1}\cdot{1 \over n}={r \over n}\sum_{j=r+1}^{n} ({j-1 \over n})^{-1}\cdot{1 \over n}$$

ここで、t = j/nと置く。すなわち、tn = jであるから、

$$j = r+1 \Leftrightarrow tn = r+1$$

$$t = {r+1 \over n}$$

である。また、

$$j = n\Leftrightarrow tn = n$$

$$t=1$$

したがって、元の式は、

$${r \over n}\sum_{j=r+1}^{n} ({j-1 \over n})^{-1}\cdot{1 \over n}={r \over n}\sum_{t={r+1 \over n}}^{1} ({tn-1 \over n})^{-1}\cdot{1 \over n}={r \over n}\sum_{t={r+1 \over n}}^{1} (t-{1 \over n})^{-1}\cdot{1 \over n}$$

このように表せます。

ここで、n→∞の時、(r/n)の極限値を

$$\lim_{n→∞}{r \over n}=x$$

と置くと、

$$\lim_{n→∞}{r \over n}\sum_{t={r+1 \over n}}^{1} (t-{1 \over n})^{-1}\cdot{1 \over n}＝\lim_{n→∞}（{r \over n}）\lim_{n→∞}(\sum_{t={r+1 \over n}}^{1} (t-{1 \over n})^{-1}\cdot{1 \over n})$$

$$＝x\lim_{n→∞}(\sum_{t={r+1 \over n}}^{1} (t-{1 \over n})^{-1}\cdot{1 \over n})$$

※nとrの比率は常に一定と仮定。

また、ロピタルの定理(※2)より、

$$\lim_{n→∞}{r+1 \over n}=x+0=x, \lim_{n→∞}(t-{1 \over n})^{-1}=t^{-1}$$

ですね。

また、ここで、n→∞かつΔx→0を考えると、

$$x\lim_{n→∞}(\sum_{t={r+1 \over n}}^{1} (t-{1 \over n})^{-1}\cdot{1 \over n})=x\int_{x}^{1}{t^{-1}} \, dt=x\int_{x}^{1}{1 \over t} \, dt$$

と近似することができます。


ようやくここまできました。

あとはこれを解くだけ。

$$x\int_{x}^{1}{1 \over t} \, dt=x[\log{t}]_{x}^{1}=x(\log{1}-\log{x})=-x\log{x}$$

求めたい成功確率の式を、

$$-x\log{x}$$

と**非常にシンプルな形**に置くことができました。

さて、これを最大化する時のxを求めていきましょう。

成功確率の式を微分し、

$${df(x) \over dx}=-1logx-1$$

これが0となる時、

$$-1logx-1=0$$

$$-logx=1$$

$$x={1 \over e}$$

自然対数e≈2.718281828459であるため、

$$x={1 \over e}\approx0.3678794412$$

以上より、約37%見逃すことで、全体の中の1位を見つけられる確率が最大化されることが示されました。

**■５．さいごに**
---
現在、株式会社LIFULLでアナリストをしているので、Qiita一発目の記事は家×数学(分析)ネタにしてみました。

数学を使って世の中の現象をモデル化して分析すると、直感とはズレた事実が浮き上がったりしてきて面白いですね。

下にも紹介していますが、東北大学の浜田先生著[「その問題、数理モデルが解決します」](https://www.amazon.co.jp/dp/B07RGWJQFQ/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)の内容をかなり参考／参照／引用させていただきました。

個人的に数理モデル領域の本は最近わかりすい本が増えてきたなーと思いつつ、その中でも対話形式で誰でもわかりやすく書かれており、数理モデルについて知りたい人にはかなりいい本だなーと思いました。

もっと上記の内容についてもっと詳しく知りたい方やもっと他の数理モデルネタを知りたい方はぜひ購入してみてください(参考文献欄にもリンク記載してます)。

■残った課題

・本当の意味での合理的な意思決定問題へのアプローチはこれまで述べたような数学的確率論的立場からだけではなく、行動科学や心理学的な観点からの知見も合わせてブラッシュアップする必要があるでしょう。本記事ではそこについては触れられていないため、時間ができたらそのあたりの論文や本とか読んでみようかなーと思ってます。

・出来るだけ順位の高い順位最小化問題として取り扱った場合、どうなるのか試してみたいなー。そのうち気が向いたらまた書きます。

・数学的に取り扱いやすくするために「過去にさかのぼって不採用にした物件を選択できない。」という制約を採用したが、まあ現実は完全にそうではないのでこの辺の改良余地はありますね。


・初Qiitaで力加減分からずこってりしてしまった。次もうちょいあっさりめにしよ。

**■参考/引用文献**
---

その問題、数理モデルが解決します

[https://www.amazon.co.jp/dp/B07RGWJQFQ/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1](https://www.amazon.co.jp/dp/B07RGWJQFQ/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

その他参照／引用させていただいた記事たち

[http://www.kurims.kyoto-u.ac.jp/~kyodo/kokyuroku/contents/pdf/1263-11.pdf](http://www.kurims.kyoto-u.ac.jp/~kyodo/kokyuroku/contents/pdf/1263-11.pdf)

[https://brave-answer.jp/15547/](https://brave-answer.jp/15547/)

[https://asset.crasco.jp/shuekibukken/2138](https://asset.crasco.jp/shuekibukken/2138)

[https://imrankhan17.github.io/pages/Solving the secretary problem with Python.html](https://imrankhan17.github.io/pages/Solving%20the%20secretary%20problem%20with%20Python.html)

[http://www.iba.t.u-tokyo.ac.jp/iba/SE/Secretary.pdf](http://www.iba.t.u-tokyo.ac.jp/iba/SE/Secretary.pdf)

[https://mathtrain.jp/lhopital](https://mathtrain.jp/lhopital)

※本記事内容については、最適化問題の専門家としていないデータアナリストによる数理モデルを実生活へ応用することの面白さの発信程度にとどめています。

アナリスト向けに数学的な解説もつけていますが、何かしら内容に齟齬などあればご教示いただけますと幸いです。