banner
二階堂春希

春希のブログ

山雨欲来风满楼,故攻八面以铸无双。 孤战非所望,俗安不可期。
tg_channel
telegram
twitter
github

空港ユーザーのパッケージ選択に関する数学的モデリング

前段時間、ある空港のオーナーが私に数学的な助けを求め、ユーザーがどのパッケージを選ぶかを計算する手助けをしてほしいと言ってきました。私は、数学モデルを構築するために必要なデータが必要だと返答しました。しかし、彼らはデータを提供することを拒否しました。おそらく、データを収集することができなかったか、データの匿名化が面倒だったからでしょう。

そこで、協議の結果、私はデータを必要とせず、データに基づいて調整可能なモデルを構築し、コストを削減するためのいくつかの提案も行いました。その結果、彼らは私により高い報酬を支払うことに同意しました。

彼らの空港では PHP を使用していますが、計算の便宜上、私は pytorch を使用しました。彼らはこのモデルを実行するために Python を使える人を見つける必要があるようです。

モデルパラメータ#

ユーザーの予算が従う確率密度関数をb(x1)b(x_1)、流量需要が従う確率密度関数をt(x2)t(x_2)、ノードの品質需要が従う確率密度関数をq(x3)q(x_3)と仮定します。

ユーザーが上記の 3 つの要因に対する重視の比率の確率密度関数をa(y1,y2)a(y_1,y_2)と仮定し、次のように定義します:

  • y1(0,1)y_1\in(0,1)y2(0,1)y_2\in(0,1)y1+y2<1y_1+y_2<1、そうでなければa(y1,y2)=0a(y_1,y_2)=0
  • y1y_1は予算の重み、y2y_2は流量の重み、1y1y21-y_1-y_2は品質の重みです。

各パッケージには価格、流量、品質の 3 つの属性があります。ユーザーがどのパッケージを購入するか考えるとき、階層分析法に従って意思決定を行うと仮定します。上記のbbttqqのパラメータはパラメータ推定が必要です。

P=(pr1,pr2,pr3,,prn)P=(p_{r1},p_{r2},p_{r3},\cdots,p_{rn})'T=(t1,t2,t3,,tn)T=(t_1,t_2,t_3,\cdots,t_n)'Q=(q1,q2,q3,,qn)Q=(q_1,q_2,q_3,\cdots,q_n)'を製品配列ベクトルとし、それぞれ製品の価格、流量、品質を表します。製品配列ベクトルは製品の特性によって決定され、パラメータ推定は必要ありません。

import torch

# パッケージの価格、流量、品質を定義
packageNumber = 3
packagePrice = [1, 2, 3]
packageTrafficLimit = [1, 2, 3]
packageQuality = [1, 2, 3]

階層分析法による定量化#

予算の満足度はf(pr,x1)=10prx1f(p_r,x_1)=10^{-\frac{p_r}{x_1}}と定義できます。ここでprp_rはパッケージ価格、x1x_1は予算です。

流量の満足度はg(t,x2)=4tx234g(t,x_2)=\sqrt{\displaystyle\frac{4t}{x_2}-\frac{3}{4}}(平方根の下が 0 未満の場合は 0 と定義)と定義できます。ここでttはパッケージ流量、x2x_2はパッケージ需要です。

ノード品質の満足度はh(q,x3)=qx33h(q,x_3)=\sqrt[3]{\displaystyle\frac{q}{x_3}}と定義できます。ここでqqはノード品質の定量指標、x3x_3はノード品質需要です。

ユーザーは満足度を選択します。

y110prx1+y24tx234+y3qx33y_1\cdot10^{\displaystyle-\frac{p_r}{x_1}}+y_2\sqrt{\displaystyle\frac{4t}{x_2}-\frac{3}{4}} + y_3\sqrt[3]{\displaystyle\frac{q}{x_3}}

最大のパッケージ

また、すべてのパッケージの満足度が 0.1 未満であれば、そのパッケージは選択されません。

ベクトル形式で表すと、次のようになります:

SATISFY=[f(P,x1),g(T,x2),h(Q,x3)]Y\text{SATISFY} = [f(P,x_1),g(T,x_2),h(Q,x_3)]'Y
SELECT={maxSATISFYPACKAGE, SATISFY>0.1, SATISFY0.1SELECT=\begin{cases} \max_{\text{SATISFY}} \text{PACKAGE},\ \text{SATISFY}>0.1\\ \varnothing,\ \text{SATISFY}\leq 0.1 \end{cases}

対応する Python コードは次のとおりです。

# ユーザーのパラメータとパッケージから満足度へのマッピングを定義
def user_satisfaction(vector_x, vector_y, pr, t, q):
    # XとYがtorchテンソルであることを確認
    vector_x = torch.tensor(vector_x, dtype=torch.float32)
    vector_y = torch.tensor(vector_y, dtype=torch.float32)
    
    term1 = vector_y[:, 0] * 10 ** (-pr / vector_x[:, 0])
    term2 = vector_y[:, 1] * torch.sqrt(4 * t / vector_x[:, 1] - 0.75)
    term3 = vector_y[:, 2] * (q / vector_x[:, 2]) ** (1 / 3)
    
    return term1 + term2 + term3

ユーザーモデリング#

ユーザー予算分布#

予算はおおよそパレート分布に従うと考えられ、初期パラメータをx1Par(1,0.6)x_1\sim Par(1,0.6)と仮定します。すなわち、

b(x1)=0.6x11.6(x1>1)b(x_1) = \frac{0.6}{x_1^{1.6}} (x_1>1)

ここで 0.6 は正確な値を得るためにパラメータ推定が必要です。

パレート分布は通常、不平等な分布を説明するために使用され、例えば富や収入、対応する予算などです。現実の世界では、富の分布はしばしば非常に不平等であり、少数の人々が大部分の富を所有しています。したがって、ユーザーの予算を反映するために、パレート分布を使用することは適切であると考えられます。

さらに、パレート分布は「80/20 ルール」と密接に関連しており、80% の効果(消費など)が 20% の原因(消費者など)から生じるというものです。多くの経済モデルにおいて、この現象は一般的であり、少数の消費者が大部分の消費支出を占めています。

パレート分布の 2 つのパラメータのうち、最初のパラメータはカットオフ値であり、x1<1x_1<1のとき、b(x1)=0b(x_1)=0です。カットオフ値はパラメータ推定できませんが、1 と仮定することは適切です。

流量需要分布#

流量需要は近似的に正規分布に従うと考えられ、パラメータはx2N(130,302)x_2\sim N(130,30^2)とします。すなわち、

t(x2)=1402πe12(x212040)2t(x_2)=\frac{1}{40\sqrt{2\pi}}e^{-\displaystyle\frac{1}{2}\left(\frac{x_2-120}{40}\right)^2}

これらの 2 つのパラメータはパラメータ推定が必要です。

品質需要分布#

品質を1101\sim10で定量化すると、1 は完全なリムジン空港、10 は全 IPLC 多入口スマート解析空港(性能はゲーム加速器に近い)とします。この場合、品質需要もパレート分布に従うと考えられ、パラメータはx3Par(1,2)x_3\sim Par(1,2)とします。すなわち、

q(x3)=2x32q(x_3)=\frac{2}{x_3^2}

このパレート分布も同様に、2 番目のパラメータのみがパラメータ推定を必要とします。

重み分布#

y1y_1y2y_2y3y_3の分布は、実際には等辺三角形の中に均等に配置されていることに注意してください。この等辺三角形は三角錐の底面です。この三角錐の 3 つの側面は、直角辺の長さが 1 の直角三角形です。

等辺三角形の 3 つの頂点は、それぞれ 1 つの重みが 1 で他の 2 つの重みが 0 である場合を表します。

(y1,y2)(y_1,y_2)を使用する場合、3 つの状況はそれぞれ(0,0)(0,0)(1,0)(1,0)(0,1)(0,1)に対応します。y1,y2,y3y_1,y_2,y_3をより均等な等辺三角形にするためには、この領域を(3+1,0)(-\sqrt{3}+1,0)(31,1)(\sqrt{3}-1,1)(31,1)(\sqrt{3}-1,-1)に線形変換する必要があります。この線形変換は簡単に求めることができます。

まず、(3+1,0)(-\sqrt{3}+1,0)(0,0)(0,0)を整列させると、他の 2 つの点は(3,1)(\sqrt{3},1)(3,1)(\sqrt{3},-1)になります。したがって、変換行列は次のようになります。

[3311][1001]1=[3311]\begin{bmatrix} \sqrt{3} & \sqrt{3} \\ 1 & -1 \end{bmatrix} \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}^{-1}= \begin{bmatrix} \sqrt{3} & \sqrt{3} \\ 1 & -1 \end{bmatrix}

平行移動ベクトルは(1,0)(-1,0)であり、すなわち

[y1y2]=[3311][y1y2]+[10]\begin{bmatrix} y_1' \\ y_2' \end{bmatrix}= \begin{bmatrix} \sqrt{3} & \sqrt{3} \\ 1 & -1 \end{bmatrix} \begin{bmatrix} y_1 \\ y_2 \end{bmatrix}+ \begin{bmatrix} -1 \\ 0 \end{bmatrix}

ただし、3 つの要因の重視については、一般的に人々はノードの品質を気にせず、価格と流量だけを考慮すると考えられます。したがって、半分の二項正規分布を選択することができます。以前のパラメータは次のようになります。

(y1,y2)N([1/21/2],[1/9001/9])(y_1,y_2)\sim \mathcal{N}\left( \begin{bmatrix} 1/2 \\ 1/2 \end{bmatrix}, \begin{bmatrix} 1/9 && 0 \\ 0 && 1/9 \end{bmatrix} \right)

すなわち、確率密度関数は

a(y1,y2)=9πe92[(x11/2)2+(x21/2)2]a(y_1,y_2)= \frac{9}{\pi}e^{\displaystyle -\frac{9}{2}\left[(x_1-1/2)^2+(x_2-1/2)^2\right]}

これらの 2 つのパラメータもパラメータ推定は必要ないと考えられます。

from torch.distributions import Pareto, Normal
from torch.distributions.multivariate_normal import MultivariateNormal

# ユーザー予算分布を定義
user_budget_distribution = Pareto(1, 0.6)
# ユーザー流量需要分布を定義
user_traffic_demand_distribution = Normal(130, 30)
# ユーザー品質需要分布を定義
user_quality_demand_distribution = Pareto(1, 2)
# ユーザー重視分布を定義
user_weight_mean = torch.tensor([0.5, 0.5])
user_weight_covariance = torch.tensor([[1 / 9, 0], [0, 1 / 9]])
user_weight_distribution = MultivariateNormal(user_weight_mean, user_weight_covariance)

# サンプルを生成
sample_size = 10000     # サンプル数
user_budget_sample = user_budget_distribution.sample((sample_size,))
user_traffic_demand_sample = user_traffic_demand_distribution.sample((sample_size,))
user_quality_demand_sample = user_quality_demand_distribution.sample((sample_size,))
user_weight_sample = user_weight_distribution.sample((sample_size,))

# ユーザーのパッケージ選択をシミュレート
y_1 = user_weight_sample[:, 0]
y_2 = user_weight_sample[:, 1]
y_3 = 1 - y_1 - y_2
user_sample = torch.stack([user_budget_sample, user_traffic_demand_sample, user_quality_demand_sample], dim=1)
user_weight_sample = torch.stack([y_1, y_2, y_3], dim=1)
user_satisfaction_of_packages = []
for i in range(packageNumber):
    pr = packagePrice[i]
    t = packageTrafficLimit[i]
    q = packageQuality[i]
    satisfactions = user_satisfaction(user_sample, user_weight_sample, pr, t, q)
    user_satisfaction_of_packages.append(satisfactions)
    
user_satisfaction_of_packages = torch.stack(user_satisfaction_of_packages, dim=1)
max_values, max_indices = torch.max(user_satisfaction_of_packages, dim=1)
indices = torch.where(max_values < 0.1, torch.tensor(-1), max_indices)

パラメータ推定#

以上より、推定が必要なパラメータは次の通りです:

  • ユーザー予算のパレート分布のkkパラメータ:kbk_b
  • 流量需要分布の平均と分散:μt\mu_tσt2\sigma^2_t
  • 品質需要のパレート分布のkkパラメータ:kqk_q

これらのパラメータは神経ネットワークを通じて推定できるようですが、私は研究していません。初期パラメータは使用できないわけではありません。

コストの最小化#

パラメータ定義#

ユーザーのノードの好みを

R=[r1r2rn]R = \begin{bmatrix} r_1 \\ r_2 \\ \vdots \\ r_n \end{bmatrix}

と仮定し、i=1nri=1\sum_{i=1}^n r_i = 1と規定します。

ユーザーが各ノードで実際に使用する流量は

U=[u1u2un]=uRU= \begin{bmatrix} u_1 \\ u_2 \\ \vdots \\ u_n \end{bmatrix} = uR

ここで、uuはユーザーが実際に使用する総流量です。

ここでは、ユーザーが流量を超過使用することを避けるために、好まないノードに切り替えることはないと仮定します。

各ノードが受け入れることができるユーザー数の制限を考慮せず、ユーザーはノードの流量を先に使い切ると仮定します。したがって、各ノードの限界コストは

C=[c1c2cn]C=\begin{bmatrix} c_1 \\ c_2 \\ \vdots \\ c_n \end{bmatrix}

となり、コストはCU=uCRC'U=uC'Rとなります。

ここでは限界コストが一定であると仮定していますが、一般的に空港は規模の経済(限界コストが使用量に応じて低下する)です。

価格をprp_rとすると、限界利益はpruCRp_r-uC'Rとなります。

したがって、利益データを得て、各パッケージの平均利益は

rˉ=pruˉCR\bar{r} = p_r - \bar{u}C'R

となります。

オーバーブッキング問題#

ノードの流量限界コストを決定するためには、オーバーブッキング比を計算する必要があります。cn=ctn/Rosc_n=c_{tn}/R_{os}とし、ここでctnc_{tn}は実際の流量限界コスト、RosR_{os}はオーバーブッキング比です。

オーバーブッキングが多すぎて可用性が低下しないようにするために、RamaxRa_{max}をオーバーブッキング可用性と定義し、意味は:RamaxRa_{max}の確率でオーバーブッキングによって利用できなくならないことを意味します。

ここで、超パラメータRamax=1104=99.99%Ra_{max}=1-10^{-4}=99.99\%と定義します。

パッケージg1,g2,,gng_1,g_2,\cdots,g_nに対して、ユーザーが実際に使用する総流量の確率密度関数をfn(u)f_{n}(u)とすると、特定のノードで使用される流量の確率密度関数はrnfn(urn)r_nf_n(ur_n)となります。

ノードの実際の流量をtrt_rとすると、可用性を満たすためには

Pr{u<tr}RamaxPr\{u<t_r\} \geq Ra_{max}

すなわち、

n0trrnfn(urn)durn=n0tr/rnfn(u)duRamax\sum_n\int_0^{t_r} r_nf_n(ur_n) dur_n=\sum_n\int_0^{t_r/r_n}f_n(u)du\geq Ra_{max}

例えば、1 つのパッケージのみがあると仮定し、そのパッケージの制限が 150G で、日本のノードの倍率が 1、ユーザーの好みが 0.5 で、使用する流量が正規分布uN(80,100)u\sim N(80,100)に従う場合、trt_r58.59558.595、オーバーブッキング比は2.54232.5423となります。

ユーザーが使用する流量は、以前のパラメータ推定から得られたユーザー需要流量と大体同じですが、一定の誤差があります。これは、ユーザーが自分の必要な流量を過大評価することが多いためです。ただし、ユーザーが実際に使用する流量がユーザーの流量需要と等しいと仮定することは可能であり、少しの流量の冗長性は問題ではありません。

Ros=trnrntR_{os}=\frac{t_r}{\sum_n r_nt}

また、trt_rは方程式を解くことで求めることができるため、RosR_{os}はデータ分析によって得ることができます。

最大期待利益問題#

最大期待利益問題は、次のようにすることです。

nfnrnˉ=fn(pr,nunˉCR)\sum_n f_n\bar{r_n} =f_n\left( p_{r,n} - \bar{u_n}C'R\right)

を最大化する問題です。(ここで $f_n$ は選択率です)

CCRRは基本的に不変の量であり、ユーザーの需要分布が推定された後、fnf_nはパッケージの属性のみに依存し、unˉ\bar{u_n}も安定しているため、最大利益問題はパッケージ属性を決定する問題となります。

もしパッケージの品質属性が定数であると仮定すると、変数は各パッケージの価格と流量のみになります。

したがって、最大期待利益を計算する方法は次のとおりです:

  • CRC'Rを統計的に得る
  • 各パッケージの品質を決定する
  • 各パッケージの価格または流量を決定し、もう一方を変数として設定する。
  • 変数に対して勾配降下法を適用し、上記の和を最大化する
    • fnf_nはユーザーの数学モデルの後にモンテカルロ法で得られる
    • prp_rは価格であり、入力変数です
    • unu_nはユーザーのモデリングに関連しています
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。