Python 数据帧中的贝叶斯平均

Python 数据帧中的贝叶斯平均,python,pandas,dataframe,bayesian,Python,Pandas,Dataframe,Bayesian,我试图根据数据帧(按行)提取一系列贝叶斯平均值 例如,假设我有一系列(0到1)用户对糖果条的评分,存储在数据框中,如下所示: User1 User2 User3 Snickers 0.01 NaN 0.7 Mars Bars 0.25 0.4 0.1 Milky Way 0.9 1.0 NaN Almond Joy NaN NaN NaN Babe Ruth 0.5 0.1

我试图根据数据帧(按行)提取一系列贝叶斯平均值

例如,假设我有一系列(0到1)用户对糖果条的评分,存储在数据框中,如下所示:

            User1   User2   User3
Snickers    0.01    NaN     0.7
Mars Bars   0.25    0.4     0.1
Milky Way   0.9     1.0     NaN
Almond Joy  NaN     NaN     NaN
Babe Ruth   0.5     0.1     0.3
我想在不同的DF中创建一个列,它表示来自上述数据的每个糖果条的贝叶斯平均值

为了计算BA,我使用:

  • S=糖果条的分数
  • R=糖果条用户评分的平均值
  • C=所有糖果条的用户评分平均值
  • w=分配给R并计算为v/(v+m)的权重,其中v是该糖果条的用户评分数,m是所有糖果条的平均评论数
我已经将其翻译成python:

def bayesian_average(df):
    """given a dataframe, returns a series of bayesian averages"""
    R = df.mean(axis=1)
    C = df.sum(axis=1).sum()/df.count(axis=1).sum()
    w = df.count(axis=1)/(df.count(axis=1)+(df.count(axis=1).sum()/len(df.dropna(how='all', inplace=False))))
    return ((w*R) + ((1-w)*C))

other_df['bayesian_avg'] = bayesian_average(ratings_df)
然而,我的计算似乎是关闭的,这样一来,随着初始数据帧中用户列数的增加,最终计算出的贝叶斯平均值也会增加(变成大于1的数字)

这是我使用的基本方程的问题,还是我如何将其转换为python的问题?或者,是否有更简单的方法来处理这一问题(例如,预先存在的包/函数)


谢谢

我首先以您给出的数据帧为例:

d = {
    'Bar': ['Snickers', 'Mars Bars', 'Milky Way', 'Almond Joy', 'Babe Ruth'],
    'User1': [0.01, 0.25, 0.9, np.nan, 0.5],
    'User2': [np.nan, 0.4, 1.0, np.nan, 0.1],
    'User3': [0.7, 0.1, np.nan, np.nan, 0.3]
}

df = pd.DataFrame(data=d)
看起来是这样的:

    Bar         User1   User2    User3
0   Snickers     0.01     NaN      0.7
1   Mars Bars    0.25     0.4      0.1
2   Milky Way    0.90     1.0      NaN
3   Almond Joy    NaN     NaN      NaN
4   Babe Ruth    0.50     0.1      0.3
    Bar        User1    User2    User3   v    w      R       S
0   Snickers    0.01      NaN      0.7   2  0.5  0.355  0.3905
1   Mars Bars   0.25      0.4      0.1   3  0.6  0.250  0.3204
2   Milky Way   0.90      1.0      NaN   2  0.5  0.950  0.6880
3   Almond Joy  NaN       NaN      NaN   0  0.0    NaN     NaN
4   Babe Ruth   0.50      0.1      0.3   3  0.6  0.300  0.3504
我做的第一件事是创建一个包含所有有用户评论的列的列表:

user_cols = []
for col in df.columns.values:
    if 'User' in col:
        user_cols.append(col)
接下来,我发现最简单的方法是将贝叶斯平均方程的每个变量创建为数据帧中的一列,或作为独立变量:

  • 计算每个条的
    v
    值:

    df['v']=df[user\u cols]。计数(axis=1)

  • 计算
    m
    (本例中等于2.0)的值:

    m=np.平均值(df['v'])

  • 计算每个条的
    w
    值:

    df['w']=df['v']/(df['v']+m)

  • 并计算每个条的
    R
    值:

    df['R']=np.平均值(df[user\u cols],axis=1)

  • 最后,获取
    C
    的值(在本例中等于0.426):

    C=np.nanmean(df[user\u cols].values.flatte())

  • 现在我们准备计算每个糖果条的贝叶斯平均分数,
    S

    df['S']=df['w']*df['R']+(1-df['w'])*C

    这为我们提供了一个如下所示的数据帧:

        Bar         User1   User2    User3
    0   Snickers     0.01     NaN      0.7
    1   Mars Bars    0.25     0.4      0.1
    2   Milky Way    0.90     1.0      NaN
    3   Almond Joy    NaN     NaN      NaN
    4   Babe Ruth    0.50     0.1      0.3
    
        Bar        User1    User2    User3   v    w      R       S
    0   Snickers    0.01      NaN      0.7   2  0.5  0.355  0.3905
    1   Mars Bars   0.25      0.4      0.1   3  0.6  0.250  0.3204
    2   Milky Way   0.90      1.0      NaN   2  0.5  0.950  0.6880
    3   Almond Joy  NaN       NaN      NaN   0  0.0    NaN     NaN
    4   Babe Ruth   0.50      0.1      0.3   3  0.6  0.300  0.3504
    
    其中最后一列
    S
    包含糖果条的所有S分数。如果需要,可以删除
    v
    w
    R
    临时列:
    df=df.drop(['v','w','R'],axis=1)


    我相信,在计算C时,您不希望删除null值,这会产生删除包含null值的行和列的效果。我更新了C的公式,将其保留在空值中,以防止删除非空值:
    np.nanmean(df[user\u cols].values.flatte())
    。还为S更新了最终结果。谢谢!我的代码似乎走在正确的轨道上,但有一些计算(m&C)可以让我收紧逻辑。我不确定我的方法是否不同到足以引入我所看到的错误,但通过添加您的逻辑,我至少可以确信我的基线BA算法是正确的。我使用1000列的数据集测试了您的代码,但没有返回大于1的数字,尽管我可能也遗漏了一些东西@这个问题很可能是由我的代码中的bug或其他问题引起的(这个糖果条计算只是一个抽象版本)。在这种情况下,即使只知道我的基线方法是正确的,对解决实际问题也非常有帮助:)