Байесовское усреднение в датафрейме - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь извлечь ряд байесовских средних, основанных на кадре данных (по строкам).

Например, скажем, у меня есть серия (от 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, который представляет байесовское среднее каждого моноблока из приведенных выше данных.

Для расчета БА я использую уравнение , представленное здесь :

Bayesian Average

  • 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? Или есть более простой способ справиться с этим вообще (например, существующий пакет / функция)?

Спасибо!

1 Ответ

0 голосов
/ 25 января 2019

Я начал с фрейма данных, который вы привели в качестве примера:

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

Первое, что я сделал, - это создал список всех столбцов, которыебыли пользовательские обзоры:

user_cols = []
for col in df.columns.values:
    if 'User' in col:
        user_cols.append(col)

Далее я нашел наиболее простым создание каждой переменной уравнения байесовского среднего в виде столбца в кадре данных или в виде отдельной переменной:

  1. Рассчитать значение v для каждого бара:

    df['v'] = df[user_cols].count(axis=1)

  2. Рассчитать значение m (равно 2,0 в этом примере):

    m = np.mean(df['v'])

  3. Рассчитать значение w для каждого бара:

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

  4. И вычислите значение R для каждого бара:

    df['R'] = np.mean(df[user_cols], axis=1)

  5. Наконец, получите значение C (равно 0,426в этом примере):

    C = np.nanmean(df[user_cols].values.flatten())

И теперь мы готовы вычислить среднюю оценку по Байесу S для каждого моноблока:

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

чтis дает нам фрейм данных, который выглядит следующим образом:

    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):

    Bar        User1    User2    User3        S
0   Snickers    0.01      NaN      0.7   0.3905
1   Mars Bars   0.25      0.4      0.1   0.3204
2   Milky Way   0.90      1.0      NaN   0.6880
3   Almond Joy  NaN       NaN      NaN      NaN
4   Babe Ruth   0.50      0.1      0.3   0.3504
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...