Корреляция Пирсона в Python

У меня есть код Python о сходстве пользователя с корреляцией Пирсона, и я хочу проанализировать шаг расчета, потому что я новичок в Python, хе-хе. Когда я пытаюсь посчитать вручную и сравнить с результатом этой программы, результат всегда разный. Мне интересно, ошибаюсь ли я, когда пытаюсь вычислить вручную. Код такой:

# A dictionary of movie critics and their ratings of a small set of movies


critics={'User 1': {'Spiderman': 1.0, 'Batman Begins': 2.0, 'Superman': 4.0},
  'User 2': {'Spiderman': 2.0, 'Batman Begins': 3.0, 'Superman': 3.0}
}


from math import sqrt

# Returns the Pearson correlation coefficient for p1 and p2
def sim_pearson(prefs,p1,p2):
  # Get the list of mutually rated items
  si={}
  for item in prefs[p1]:
    if item in prefs[p2]: si[item]=1

  # if they are no ratings in common, return 0
  if len(si)==0: return 0

  # Sum calculations
  n=len(si)

  # Sums of all the preferences
  sum1=sum([prefs[p1][it] for it in si])
  sum2=sum([prefs[p2][it] for it in si])

  # Sums of the squares
  sum1Sq=sum([pow(prefs[p1][it],2) for it in si])
  sum2Sq=sum([pow(prefs[p2][it],2) for it in si])

  # Sum of the products
  pSum=sum([prefs[p1][it]*prefs[p2][it] for it in si])

  # Calculate r (Pearson score)
  num=pSum-(sum1*sum2/n)
  den=sqrt((sum1Sq-pow(sum1,2)/n)*(sum2Sq-pow(sum2,2)/n))
  if den==0: return 0

  r=num/den

  return r


def main():
    z = sim_pearson(critics, 'User 1','User 2')
    print z

if __name__ == "__main__":
    main()

Я хочу рассчитать сходство между пользователем 1 и пользователем 2. Но я запутался в этой части:

([prefs[p1][it] for it in si])

что означает [это]?

Результат подобия, если я использую эту программу: 0,755928946018

верно ли значение этого кода ([prefs[p1][it] for it in si])умножает рейтинги пользователя 1? Нравится 1*2*4? или он должен умножаться на рейтинги пользователя 2? Нравится (1*2)+(1*3)+(4*3)?

Меня смущает [p1][it]. Я надеюсь, что вы можете мне помочь, спасибо за заранее.


person user3528526    schedule 19.09.2014    source источник


Ответы (1)


Давайте возьмем строку, которая вас смущает, и разберем ее:

sum1=sum([prefs[p1][it] for it in si])

Давайте работать снаружи внутрь. Большая часть внешней части — это оператор присваивания, поэтому мы вычисляем какое-то значение, которое нужно присвоить sum1:

sum1 = ...

Теперь давайте посмотрим, что присваивается:

sum1 = sum(...)

Встроенная функция sum ожидает передачи итерируемого объекта (например, списка). Давайте посмотрим, что такое аргумент:

sum1 = sum([... for it in si])

Внешние квадратные скобки говорят нам, что мы получаем список. Синтаксис for it in si означает, что это понимание списка. Python запускает цикл for для создания элементов списка. Я почти уверен, что имя переменной it означает «предмет». Цикл проходит по ключам словаря si (который на самом деле должен был быть создан как список, так как вы никогда не заботитесь о его значениях).

Стоит отметить, что вы могли бы на самом деле опустить квадратные скобки из кода здесь, и вместо того, чтобы быть списковым пониманием, которое создает полный список заранее, это было бы «ленивое» выражение генератора, которое создает итерируемый объект генератора, который вычисляет каждое значение одно за другим по мере их запроса.

В любом случае, давайте выясним, что представляют собой элементы понимания списка:

sum1 = sum([...[it] for it in si])

Квадратные скобки в [it] представляют собой синтаксис индексации, поскольку они находятся непосредственно справа от другого выражения. Вы можете индексировать списки и кортежи с целыми числами, а словари — с любыми хешируемыми объектами (например, строками). В данном случае это ключ it, который является нашей переменной цикла в понимании списка. Давайте посмотрим, что мы индексируем:

sum1 = sum([...[p1][it] for it in si])

Индексация [it] применяется к результату предыдущей индексации, на этот раз с [p1], который является аргументом функции. Давайте посмотрим, для чего выполняется это индексирование:

sum1 = sum([prefs[p1][it] for it in si])

Индексация выполняется по prefs, глобальной переменной, содержащей словарь. Ключами к этому словарю являются рецензенты (именно это должно быть p1), а значениями являются дополнительные вложенные словари, отображающие имена фильмов в рейтинги.

Таким образом, оператор суммирует оценки одного рецензента для определенного набора фильмов и присваивает их sum1. С данными вашего примера это будет 1.0 + 2.0 + 4.0, поэтому sum1 будет присвоено 7.0.

person Blckknght    schedule 19.09.2014
comment
Хороший ответ! Очень подробно - person llrs; 19.09.2014
comment
а n относится к количеству пользователей или количеству фильмов, которые оцениваются пользователем? - person user3528526; 19.09.2014
comment
Я получил sum1=7 sum2=8 sum1sq=21 sum2sq=22 psum=56, это правда? потому что результат всегда разный каждый раз, когда я вычисляю вручную, хм - person user3528526; 19.09.2014