Python 数据帧中的贝叶斯平均
我试图根据数据帧(按行)提取一系列贝叶斯平均值 例如,假设我有一系列(0到1)用户对糖果条的评分,存储在数据框中,如下所示: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
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是所有糖果条的平均评论数
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或其他问题引起的(这个糖果条计算只是一个抽象版本)。在这种情况下,即使只知道我的基线方法是正确的,对解决实际问题也非常有帮助:)