Press "Enter" to skip to content

一个选择餐厅的贝叶斯方法

最近,我在寻找一家新的好餐厅。谷歌地图为我标出了两个选择:餐厅A有10条评价,全部都是5星,而餐厅B有200条评价,平均评分为4分。我有些动心地想选择餐厅A,但是评价数量少让我有些担忧。另一方面,餐厅B的众多评价给了我对其4星评级的信心,但并没有什么特别出众的。所以,我想比较一下餐厅,选择在评价或者缺乏评价方面更有优势的。幸运的是,贝叶斯提供了一种方法。

作者制作的图片

贝叶斯框架可以假设一些有关评级的初始概率分布,并根据观察数据来更新初始信念。

设置初始信念 / 先验

  • 在任何评价之前,我们对每个评级(从1到5星)的概率一无所知。因此,在任何评价之前,所有评级的可能性是相等的。这意味着我们从均匀分布开始,可以表示为狄利克雷分布(贝塔的泛化)。
  • 我们的平均评级将是(1+2+3+4+5)/5 = 3,这是概率集中的地方。
# 先验概率估计从均匀样本中采样sample_size = 10000p_a = np.random.dirichlet(np.ones(5), size=sample_size)p_b = np.random.dirichlet(np.ones(5), size=sample_size)# 基于采样概率的先验评级均值ratings_support = np.array([1, 2, 3, 4, 5])prior_reviews_mean_a = np.dot(p_a, ratings_support)prior_reviews_mean_b = np.dot(p_b, ratings_support)
作者制作的图片

更新信念

  • 为了更新初始信念,我们需要将先验信念与观察到的数据的似然相乘。
  • 观察到的数据自然地可以用多项式分布(二项式的泛化)来描述。
  • 事实证明,狄利克雷是多项式似然的共轭先验。换句话说,我们的后验分布也是狄利克雷分布,其参数结合了观察到的数据。
作者制作的图片
# 观察到的数据reviews_a = np.array([0, 0, 0, 0, 10])reviews_b= np.array([21, 5, 10, 79, 85])# 基于观察到的数据的后验评级概率估计sample_size = 10000p_a = np.random.dirichlet(reviews_a+1, size=sample_size)p_b = np.random.dirichlet(reviews_b+1, size=sample_size)# 计算后验评级均值posterior_reviews_mean_a = np.dot(p_a, ratings_support)posterior_reviews_mean_b = np.dot(p_b, ratings_support)
  • A的后验平均评级现在在先验3和观察到的5之间。但是,由于大量的评价超过了初始信念,B的平均评级并没有变化太多。
作者制作的图片

那么,哪一个更好呢?

  • 回到我们最初的问题,“更好”意味着A的平均评分大于B的平均评分的可能性,即P(E(A|data)>E(B|data))。
  • 在我的例子中,我得出了85%的可能性,即餐厅A比餐厅B更好。
# P(E(A)-E(B)>0)posterior_rating_diff = posterior_reviews_mean_a-posterior_reviews_mean_bp_posterior_better = sum(posterior_rating_diff>0)/len(posterior_rating_diff)
Image made by the author.

贝叶斯更新允许我们融入先前的信念,这在评论数量较少的情况下尤为有价值。然而,当评论数量较大时,初始信念对后续信念的影响并不显著。

代码可在我的 Github 上找到,我打算去餐厅A。

Leave a Reply

Your email address will not be published. Required fields are marked *