前段時間,有個機場主找到我,希望我提供數學上的幫助,幫助他們計算用戶會選擇什麼套餐。我回覆,需要必要的數據來建立數學模型。但他們拒絕給我提供數據,可能原因是沒有收集或者脫敏麻煩。
於是,經過協商,我為他們建立不需要數據、且可以根據數據調整的模型,並且順帶給出一些降低成本的方案;他們給我更高的報酬。
儘管我強烈懷疑他們能夠通過這個模型獲得到的利潤需要多久才能填補聘用我的費用,但我還是給了他們做。並且,他們允許我把這個模型部分開源出來。
他們的機場用的是 PHP,但我為了方便計算,用的是 pytorch,我想他們似乎還需要找個會 Python 的來跑起來這個模型。
模型參數#
假設用戶的預算服從的分布的概率密度函數為,流量需求服從的分布的概率密度函數為,節點質量需求服從的概率密度函數為
假設用戶對以上 3 種因素側重比例的概率密度函數為,定義為:
- ,,,否則
- 為預算的權重,為流量的權重,為質量的權重
每種套餐都有價格、流量、質量 3 個屬性。假設當用戶思考買哪一種套餐時,會按照層次分析法決策。上述 , , 的參數需要參數估計。
令 , , 為產品數組向量,分別為產品的價格、流量、質量。產品數組向量由產品性質決定,不需要參數估計。
import torch
# 定義套餐的價格、流量、質量
packageNumber = 3
packagePrice = [1, 2, 3]
packageTrafficLimit = [1, 2, 3]
packageQuality = [1, 2, 3]
層次分析法量化#
對於預算的滿意度,可以定義為,其中為套餐價格,為預算
對於流量的滿意度,可以定義為(當根號下為 0 以下時定義為 0),其中為套餐流量,為套餐需求
對於節點質量的滿意度,可以定義為,其中為節點質量量化指標,為節點質量需求。
用戶會選擇滿意度
最大的套餐
並且,如果對套餐的滿意度都小於 0.1,那麼他將不會選擇這個套餐。
寫成向量形式,則有:
對應的 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
用戶建模#
用戶預算分布#
預算可以認為大致是服從帕累托分布的,假設初始參數為,即
其中 0.6 需要參數估計以獲得準確值。
帕累托分布通常用來描述不平等的分布,例如財富或收入,以及對應的預算。在現實世界中,財富分布往往是高度不平等的,少數人擁有大部分財富。因此,為了反映用戶預算,使用帕累托分布應該是合適的。
此外,帕累托分布與所謂的 “80/20 規則” 密切相關,即 80% 的效果(如消費)來自 20% 的原因(如消費者)。在許多經濟模型中,這種現象是普遍存在的,比如少數消費者貢獻了大部分的消費支出。
帕累托分布的兩個參數中,第一個參數為截止值,當時,。截止值無法參數估計,但假設為 1 是合適的。
流量需求分布#
流量需求可以認為近似服從正態分布,參數為,即
這兩個參數都需要參數估計。
質量需求分布#
如果量化質量為,其中 1 為完全靈車機場,10 為全 IPLC 多入口智能解析機場(性能接近遊戲加速器),那麼質量需求也可以認為是服從帕累托分布的,參數為,即
這個帕累托分布同樣只有第二個參數需要參數估計。
權重分布#
注意到, , 的分布實際上被均勻地放在了一個等邊三角形上。這個等邊三角形是一個三棱錐的底面。這個三棱錐的 3 個側面都是直角邊邊上為 1 的直角三角形。
等邊三角形的 3 個頂點分別表示其中一個權重為 1 而另外兩個權重為 0 的情況。
在使用表示時,3 種情況分別對應, , 。而為了讓變成更加均勻的等邊三角形,需要將這個區域線性變換為, , 。這個線性變換很容易求得。
首先把和對齊,那麼其他兩個點是, 。於是,變換矩陣為
平移向量為,即
不過,對於 3 種因素的側重,可以認為一般人根本不在乎節點質量,而只考慮節點的價格和流量。所以,可以選擇截半邊的二元正態分布。截取之前的參數為
即概率密度函數為
這兩個參數應該也是不需要參數估計的。
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)
參數估計#
綜上,需要估計的參數有:
- 用戶預算的帕累托分布參數:
- 流量需求分布的均值和方差:,
- 質量需求的帕累托分布參數:
似乎是可以通過神經網絡估計出這幾個參數,不過我沒去研究,初始參數又不是不能用。
最小化成本#
參數定義#
假設用戶的節點偏好為
且規定
用戶在各節點實際使用的流量為
其中,為用戶實際使用的總流量。
這裡假設用戶不會因為差點用超流量而改用不喜歡的節點。
不考慮每個節點能夠承載的用戶數量限制,假設用戶會先用完節點的流量而不是因為請求導致節點超載。於是,假設各個節點的邊際成本為
則成本為
這裡假設了邊際成本為常數,但一般機場是規模經濟(邊際成本隨用量降低)的。
若定價為,則邊際利潤為
於是,得到利潤數據,平均每個套餐的利潤為
超售問題#
為了確定節點的流量邊際成本,需要計算超售比,因為,其中為實際流量邊際成本,為超售比。
為了確保不會因為超售太多而導致可用性下降,定義為超售可用性,意義為:有的概率不會因為超售而不可用。
這裡定義超參數
對於套餐,設用戶實際使用總流量的概率密度函數為,則對於某一個節點,使用的流量的概率密度函數為
設節點實際的流量為,則為滿足可用性,需要
即
例如,假設只有 1 個套餐,這個套餐的限額為 150G,對於日本節點,倍率為 1,用戶的偏好程度為 0.5,使用的流量服從正態分布,那麼,應該為,超售比為
用戶使用的流量在與之前參數估計得到的用戶需求流量大致相同,但有一定誤差。這是因為,用戶往往會高估自己需要使用的流量。不過,假設用戶實際使用的流量等於用戶流量需求可能是可行的,因為留一點流量上的冗餘是問題不大的。
因為
而可以求解方程得到,
所以可以由數據分析得到。
最大期望利潤問題#
最大期望利潤問題,也就是使得
最大的问题。(其中 $f_n$ 為選擇率)
由於和都是基本不變的量,而且在參數估計出用戶的需求分布後,只取決於套餐的屬性,也是穩定的,所以最大利潤問題就是確定套餐屬性的問題。
如果假設套餐的質量屬性是常數,那麼變量就只有各個套餐的價格和流量了。
所以,計算最大期望利潤的方法為:
- 統計得到
- 確定各個套餐的質量
- 確定各個套餐的價格或者流量,把另一個設置為變量。
- 對變量進行梯度下降,使上面那個和式取最大值
-
- 可以在有用戶的數學模型之後,蒙特卡羅方法得到
-
- 為價格,是輸入變量
-
- 與用戶的建模相關